feat(examples/conceptual-design): add design concept generation playbook #152
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Secret Scan | |
| on: | |
| push: | |
| branches: [main] | |
| pull_request: | |
| branches: [main] | |
| workflow_dispatch: | |
| jobs: | |
| secret-scan: | |
| name: Scan for secrets and large files | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Scan for API keys and secrets | |
| run: | | |
| echo "::group::Secret pattern scan" | |
| # Patterns to detect. The `sk-` family is gated on (^|[^A-Za-z0-9_-]) | |
| # to skip false positives in markdown anchor slugs like | |
| # `#task-expects-...` where `sk-` appears inside a kebab-case word. | |
| # Real keys are also required to contain at least one digit, which | |
| # excludes lowercase prose entirely. | |
| PATTERNS=( | |
| '(^|[^A-Za-z0-9_-])sk-[A-Za-z0-9_-]*[0-9][A-Za-z0-9_-]{19,}' | |
| 'AIza[A-Za-z0-9_-]{30,}' | |
| 'xai-[A-Za-z0-9_-]*[0-9][A-Za-z0-9_-]{25,}' | |
| 'msy_[A-Za-z0-9_-]{20,}' | |
| '(^|[^A-Za-z0-9_-])sk-proj-[A-Za-z0-9_-]{50,}' | |
| '(^|[^A-Za-z0-9_-])sk-api-[A-Za-z0-9_-]{50,}' | |
| '(^|[^A-Za-z0-9_-])sk-cp-[A-Za-z0-9_-]{50,}' | |
| 'BEGIN\s+(RSA|OPENSSH|EC)\s+PRIVATE\s+KEY' | |
| 'AFDhg[A-Za-z0-9]{15,}' | |
| 'YmF8e[A-Za-z0-9]{15,}' | |
| ) | |
| FOUND=0 | |
| for pattern in "${PATTERNS[@]}"; do | |
| # Scan only tracked files, excluding binary and lock files | |
| RESULTS=$(git ls-files | \ | |
| grep -vE '\.(png|jpg|jpeg|gif|svg|ico|webp|woff2?|ttf|eot|mp4|webm|mp3|wav|ogg|apk|zip|sqlite|bin)$' | \ | |
| grep -vE 'node_modules|pnpm-lock\.yaml|package-lock\.json|\.tsbuildinfo$' | \ | |
| xargs grep -lE "$pattern" 2>/dev/null || true) | |
| if [ -n "$RESULTS" ]; then | |
| echo "" | |
| echo "⚠️ Pattern '$pattern' found in:" | |
| for file in $RESULTS; do | |
| echo " $file" | |
| # Show the matching line | |
| grep -nE "$pattern" "$file" 2>/dev/null | head -3 | while read -r line; do | |
| echo " → $line" | |
| done | |
| done | |
| FOUND=1 | |
| fi | |
| done | |
| if [ "$FOUND" -eq 1 ]; then | |
| echo "" | |
| echo "::error:: Secrets detected in repository. Remove them before merging." | |
| exit 1 | |
| fi | |
| echo "::notice:: No secrets detected." | |
| echo "::endgroup::" | |
| - name: Check for tracked .env files | |
| run: | | |
| echo "::group::Tracked .env file check" | |
| TRACKED_ENV=$(git ls-files | grep -E '\.env$|\.env\.local$|\.env\.local-backup$' || true) | |
| if [ -n "$TRACKED_ENV" ]; then | |
| echo "::error:: The following .env files are tracked by git:" | |
| echo "$TRACKED_ENV" | |
| echo "Run 'git rm --cached' on these files and add them to .gitignore." | |
| exit 1 | |
| fi | |
| echo "::notice:: No tracked .env files." | |
| echo "::endgroup::" | |
| - name: Check for large files | |
| run: | | |
| echo "::group::Large file check" | |
| # Check for files > 1MB in the latest commit | |
| LARGE_FILES=$(git ls-files -s | awk '$4 > 1000000 {print $4}' || true) | |
| if [ -n "$LARGE_FILES" ]; then | |
| echo "::warning:: Large files (>1MB) in repository:" | |
| for f in $LARGE_FILES; do | |
| SIZE=$(ls -lh "$f" 2>/dev/null | awk '{print $5}' || echo "unknown") | |
| echo " $f ($SIZE)" | |
| done | |
| echo "Consider using Git LFS or removing these files." | |
| # Warning only — doesn't fail the build | |
| else | |
| echo "::notice:: No large files detected." | |
| fi | |
| echo "::endgroup::" | |