Add comprehensive enum validation test coverage (#7867) #26146
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: CI | |
| on: | |
| push: | |
| branches: [main] | |
| pull_request: | |
| paths: | |
| - '**.go' | |
| - 'pkg/workflow/**' | |
| - 'actions/**' | |
| - '.github/workflows/ci.yml' | |
| - '.github/workflows/**/*.md' | |
| workflow_dispatch: | |
| jobs: | |
| test: | |
| needs: [lint-go, lint-js] | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| concurrency: | |
| group: ci-${{ github.ref }}-test | |
| cancel-in-progress: true | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 | |
| - name: Set up Go | |
| id: setup-go | |
| uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6 | |
| with: | |
| go-version-file: go.mod | |
| cache: true | |
| - name: Report Go cache status | |
| run: | | |
| if [ "${{ steps.setup-go.outputs.cache-hit }}" == "true" ]; then | |
| echo "✅ Go cache hit" >> $GITHUB_STEP_SUMMARY | |
| else | |
| echo "⚠️ Go cache miss" >> $GITHUB_STEP_SUMMARY | |
| fi | |
| - name: Verify dependencies | |
| run: go mod verify | |
| - name: Run unit tests with coverage | |
| run: | | |
| go test -v -parallel=8 -timeout=3m -tags '!integration' -run='^Test' -coverprofile=coverage.out -json ./... | tee test-result-unit.json | |
| go tool cover -html=coverage.out -o coverage.html | |
| # Coverage reports for recent builds only - 7 days is sufficient for debugging recent changes | |
| - name: Upload coverage report | |
| uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 | |
| with: | |
| name: coverage-report | |
| path: coverage.html | |
| retention-days: 7 | |
| - name: Upload unit test results | |
| uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 | |
| with: | |
| name: test-result-unit | |
| path: test-result-unit.json | |
| retention-days: 14 | |
| integration: | |
| needs: [lint-go, lint-js] # Integration tests run independently (have their own checkout/setup) | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| test-group: | |
| - name: "CLI Compile & Poutine" | |
| packages: "./pkg/cli" | |
| pattern: "^TestCompile[^W]|TestPoutine" # Exclude TestCompileWorkflows to avoid duplicates | |
| - name: "CLI MCP Playwright" | |
| packages: "./pkg/cli" | |
| pattern: "TestMCPInspectPlaywright" | |
| - name: "CLI MCP Gateway" | |
| packages: "./pkg/cli" | |
| pattern: "TestMCPGateway" | |
| - name: "CLI MCP Other" | |
| packages: "./pkg/cli" | |
| pattern: "TestMCPAdd|TestMCPInspectGitHub|TestMCPServer|TestMCPConfig" | |
| - name: "CLI Logs & Firewall" | |
| packages: "./pkg/cli" | |
| pattern: "TestLogs|TestFirewall|TestNoStopTime|TestLocalWorkflow" | |
| - name: "CLI Progress Flag" # Isolate slow 30s test | |
| packages: "./pkg/cli" | |
| pattern: "TestProgressFlagSignature" | |
| - name: "CLI HTTP MCP Connect" # Isolate slow HTTP MCP connection tests | |
| packages: "./pkg/cli" | |
| pattern: "TestConnectHTTPMCPServer" | |
| - name: "CLI Compile Workflows" # Isolate slow workflow compilation test | |
| packages: "./pkg/cli" | |
| pattern: "TestCompileWorkflows_EmptyMarkdown" | |
| - name: "CLI Security Tools" # Group security tool compilation tests | |
| packages: "./pkg/cli" | |
| pattern: "TestCompileWithZizmor|TestCompileWithPoutine|TestCompileWithPoutineAndZizmor" | |
| - name: "CLI Add & List Commands" | |
| packages: "./pkg/cli" | |
| pattern: "^TestAdd|^TestList" | |
| - name: "CLI Update Command" | |
| packages: "./pkg/cli" | |
| pattern: "^TestUpdate" | |
| - name: "CLI Audit & Inspect" | |
| packages: "./pkg/cli" | |
| pattern: "^TestAudit|^TestInspect" | |
| - name: "CLI Completion & Other" # Remaining catch-all (reduced from original) | |
| packages: "./pkg/cli" | |
| pattern: "" # Catch-all for tests not matched by other CLI patterns | |
| skip_pattern: "^TestCompile[^W]|TestPoutine|TestMCPInspectPlaywright|TestMCPGateway|TestMCPAdd|TestMCPInspectGitHub|TestMCPServer|TestMCPConfig|TestLogs|TestFirewall|TestNoStopTime|TestLocalWorkflow|TestProgressFlagSignature|TestConnectHTTPMCPServer|TestCompileWorkflows_EmptyMarkdown|TestCompileWithZizmor|TestCompileWithPoutine|TestCompileWithPoutineAndZizmor|^TestAdd|^TestList|^TestUpdate|^TestAudit|^TestInspect" | |
| - name: "Workflow Compiler" | |
| packages: "./pkg/workflow" | |
| pattern: "TestCompile|TestWorkflow|TestGenerate|TestParse" | |
| - name: "Workflow Tools & MCP" | |
| packages: "./pkg/workflow" | |
| pattern: "TestMCP|TestTool|TestSkill|TestPlaywright|TestFirewall" | |
| - name: "Workflow Validation" | |
| packages: "./pkg/workflow" | |
| pattern: "TestValidat|TestLock|TestError|TestWarning" | |
| - name: "Workflow Safe Outputs" | |
| packages: "./pkg/workflow" | |
| pattern: "SafeOutputs|CreatePullRequest|OutputLabel|HasSafeOutputs" | |
| - name: "Workflow GitHub & Git" | |
| packages: "./pkg/workflow" | |
| pattern: "GitHub|Git|PushToPullRequest|BuildFromAllowed" | |
| - name: "Workflow Rendering & Bundling" | |
| packages: "./pkg/workflow" | |
| pattern: "Render|Bundle|Script|WritePromptText" | |
| - name: "Workflow Cache" | |
| packages: "./pkg/workflow" | |
| pattern: "^TestCache|TestCacheDependencies|TestCacheKey|TestValidateCache" | |
| - name: "Workflow Actions Pin Validation" | |
| packages: "./pkg/workflow" | |
| pattern: "^TestActionPinSHAsMatchVersionTags" | |
| - name: "Workflow Actions & Containers" | |
| packages: "./pkg/workflow" | |
| pattern: "^TestAction[^P]|Container" | |
| - name: "Workflow Dependabot & Security" | |
| packages: "./pkg/workflow" | |
| pattern: "Dependabot|Security|PII" | |
| - name: "CMD Tests" # All cmd/gh-aw integration tests | |
| packages: "./cmd/gh-aw" | |
| pattern: "" | |
| skip_pattern: "" # No other groups cover cmd tests | |
| - name: "Parser Remote Fetch & Cache" | |
| packages: "./pkg/parser" | |
| pattern: "TestDownloadFileFromGitHub|TestResolveIncludePath|TestDownloadIncludeFromWorkflowSpec|TestImportCache" | |
| - name: "Parser Location & Validation" | |
| packages: "./pkg/parser" | |
| pattern: "" # Catch-all for tests not matched by other Parser patterns | |
| skip_pattern: "TestDownloadFileFromGitHub|TestResolveIncludePath|TestDownloadIncludeFromWorkflowSpec|TestImportCache" | |
| - name: "Workflow Permissions" | |
| packages: "./pkg/workflow" | |
| pattern: "TestPermissions|TestPackageExtractor|TestCollectPackagesFromWorkflow" | |
| - name: "Workflow Expression & Safety" | |
| packages: "./pkg/workflow" | |
| pattern: "TestExpression|TestValidateExpressionSafety|TestCheckNetworkSupport|TestValidateStrictMCPNetwork" | |
| - name: "Workflow Job Management" | |
| packages: "./pkg/workflow" | |
| pattern: "TestJobManager|TestWorkflowStep|TestScriptRegistry" | |
| - name: "Workflow Misc Part 1" # Split large catch-all into two balanced groups | |
| packages: "./pkg/workflow" | |
| pattern: "TestAgent|TestCopilot|TestCustom|TestEngine|TestModel|TestNetwork|TestOpenAI|TestProvider" | |
| - name: "Workflow String & Sanitization" | |
| packages: "./pkg/workflow" | |
| pattern: "String|Sanitize|Normalize|Trim|Clean|Format" | |
| - name: "Workflow Runtime & Setup" | |
| packages: "./pkg/workflow" | |
| pattern: "Runtime|Setup|Install|Download|Version|Binary" | |
| - name: "Workflow Misc Part 2" # Remaining workflow tests | |
| packages: "./pkg/workflow" | |
| pattern: "" | |
| skip_pattern: "TestCompile|TestWorkflow|TestGenerate|TestParse|TestMCP|TestTool|TestSkill|TestPlaywright|TestFirewall|TestValidat|TestLock|TestError|TestWarning|SafeOutputs|CreatePullRequest|OutputLabel|HasSafeOutputs|GitHub|Git|PushToPullRequest|BuildFromAllowed|Render|Bundle|Script|WritePromptText|^TestCache|TestCacheDependencies|TestCacheKey|TestValidateCache|^TestActionPinSHAsMatchVersionTags|^TestAction[^P]|Container|Dependabot|Security|PII|TestPermissions|TestPackageExtractor|TestCollectPackagesFromWorkflow|TestExpression|TestValidateExpressionSafety|TestCheckNetworkSupport|TestValidateStrictMCPNetwork|TestJobManager|TestWorkflowStep|TestScriptRegistry|TestAgent|TestCopilot|TestCustom|TestEngine|TestModel|TestNetwork|TestOpenAI|TestProvider|String|Sanitize|Normalize|Trim|Clean|Format|Runtime|Setup|Install|Download|Version|Binary" | |
| concurrency: | |
| group: ci-${{ github.ref }}-integration-${{ matrix.test-group.name }} | |
| cancel-in-progress: true | |
| name: "Integration: ${{ matrix.test-group.name }}" | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 | |
| - name: Set up Go | |
| id: setup-go | |
| uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6 | |
| with: | |
| go-version-file: go.mod | |
| cache: true | |
| - name: Report Go cache status | |
| run: | | |
| if [ "${{ steps.setup-go.outputs.cache-hit }}" == "true" ]; then | |
| echo "✅ Go cache hit" >> $GITHUB_STEP_SUMMARY | |
| else | |
| echo "⚠️ Go cache miss" >> $GITHUB_STEP_SUMMARY | |
| fi | |
| - name: Verify dependencies | |
| run: go mod verify | |
| - name: Run integration tests - ${{ matrix.test-group.name }} | |
| run: | | |
| # Sanitize the test group name for use in filename | |
| SAFE_NAME=$(echo "${{ matrix.test-group.name }}" | sed 's/[^a-zA-Z0-9]/-/g' | sed 's/--*/-/g') | |
| if [ -z "${{ matrix.test-group.pattern }}" ]; then | |
| # Catch-all group: run with -skip to exclude tests matched by other groups | |
| if [ -n "${{ matrix.test-group.skip_pattern || '' }}" ]; then | |
| go test -v -parallel=8 -timeout=5m -tags 'integration' -skip '${{ matrix.test-group.skip_pattern }}' -json ${{ matrix.test-group.packages }} | tee "test-result-integration-${SAFE_NAME}.json" | |
| else | |
| go test -v -parallel=8 -timeout=5m -tags 'integration' -json ${{ matrix.test-group.packages }} | tee "test-result-integration-${SAFE_NAME}.json" | |
| fi | |
| else | |
| go test -v -parallel=8 -timeout=5m -tags 'integration' -run '${{ matrix.test-group.pattern }}' -json ${{ matrix.test-group.packages }} | tee "test-result-integration-${SAFE_NAME}.json" | |
| fi | |
| - name: Upload integration test results | |
| uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 | |
| with: | |
| name: test-result-integration-${{ matrix.test-group.name }} | |
| path: test-result-integration-*.json | |
| retention-days: 14 | |
| update: | |
| needs: [lint-go, lint-js] # Run in parallel with integration tests | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| concurrency: | |
| group: ci-${{ github.ref }}-update | |
| cancel-in-progress: true | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 | |
| - name: Set up Go | |
| id: setup-go | |
| uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6 | |
| with: | |
| go-version-file: go.mod | |
| cache: true | |
| - name: Report Go cache status | |
| run: | | |
| if [ "${{ steps.setup-go.outputs.cache-hit }}" == "true" ]; then | |
| echo "✅ Go cache hit" >> $GITHUB_STEP_SUMMARY | |
| else | |
| echo "⚠️ Go cache miss" >> $GITHUB_STEP_SUMMARY | |
| fi | |
| - name: Verify dependencies | |
| run: go mod verify | |
| - name: Build gh-aw binary | |
| run: make build | |
| - name: Test update command (dry-run) | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| echo "Testing update command to ensure it runs without issues..." | |
| # Run update with verbose flag to check for updates without making changes | |
| # The command checks for gh-aw updates, action updates, and workflow updates | |
| ./gh-aw update --verbose --no-actions || true | |
| echo "✅ Update command executed successfully" >> $GITHUB_STEP_SUMMARY | |
| build: | |
| needs: [lint-go, lint-js] | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| concurrency: | |
| group: ci-${{ github.ref }}-build | |
| cancel-in-progress: true | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 | |
| - name: Set up Node.js | |
| id: setup-node | |
| uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6 | |
| with: | |
| node-version: "24" | |
| cache: npm | |
| cache-dependency-path: actions/setup/js/package-lock.json | |
| - name: Report Node cache status | |
| run: | | |
| if [ "${{ steps.setup-node.outputs.cache-hit }}" == "true" ]; then | |
| echo "✅ Node cache hit" >> $GITHUB_STEP_SUMMARY | |
| else | |
| echo "⚠️ Node cache miss" >> $GITHUB_STEP_SUMMARY | |
| fi | |
| - name: Set up Go | |
| id: setup-go | |
| uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6 | |
| with: | |
| go-version-file: go.mod | |
| cache: true | |
| - name: Report Go cache status | |
| run: | | |
| if [ "${{ steps.setup-go.outputs.cache-hit }}" == "true" ]; then | |
| echo "✅ Go cache hit" >> $GITHUB_STEP_SUMMARY | |
| else | |
| echo "⚠️ Go cache miss" >> $GITHUB_STEP_SUMMARY | |
| fi | |
| - name: npm ci | |
| run: npm ci | |
| working-directory: ./actions/setup/js | |
| - name: Build code | |
| run: make build | |
| - name: Rebuild lock files | |
| run: make recompile | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| js: | |
| needs: [lint-go, lint-js] | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| concurrency: | |
| group: ci-${{ github.ref }}-js | |
| cancel-in-progress: true | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 | |
| - name: Set up Node.js | |
| id: setup-node | |
| uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6 | |
| with: | |
| node-version: "24" | |
| cache: npm | |
| cache-dependency-path: actions/setup/js/package-lock.json | |
| - name: Report Node cache status | |
| run: | | |
| if [ "${{ steps.setup-node.outputs.cache-hit }}" == "true" ]; then | |
| echo "✅ Node cache hit" >> $GITHUB_STEP_SUMMARY | |
| else | |
| echo "⚠️ Node cache miss" >> $GITHUB_STEP_SUMMARY | |
| fi | |
| - name: Install npm dependencies | |
| run: cd actions/setup/js && npm ci | |
| - name: Run tests | |
| run: cd actions/setup/js && npm test | |
| bench: | |
| needs: [lint-go, lint-js] | |
| # Only run benchmarks on main branch for performance tracking | |
| if: github.ref == 'refs/heads/main' | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| concurrency: | |
| group: ci-${{ github.ref }}-bench | |
| cancel-in-progress: true | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 | |
| - name: Set up Go | |
| id: setup-go | |
| uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6 | |
| with: | |
| go-version-file: go.mod | |
| cache: true | |
| - name: Report Go cache status | |
| run: | | |
| if [ "${{ steps.setup-go.outputs.cache-hit }}" == "true" ]; then | |
| echo "✅ Go cache hit" >> $GITHUB_STEP_SUMMARY | |
| else | |
| echo "⚠️ Go cache miss" >> $GITHUB_STEP_SUMMARY | |
| fi | |
| - name: Verify dependencies | |
| run: go mod verify | |
| - name: Run benchmarks | |
| run: make bench | |
| # Benchmark results for performance trend analysis - 14 days allows comparison across multiple runs | |
| - name: Save benchmark results | |
| uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 | |
| with: | |
| name: benchmark-results | |
| path: bench_results.txt | |
| if-no-files-found: ignore | |
| retention-days: 14 | |
| lint-go: | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| concurrency: | |
| group: ci-${{ github.ref }}-lint-go | |
| cancel-in-progress: true | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 | |
| - name: Set up Go | |
| id: setup-go | |
| uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6 | |
| with: | |
| go-version-file: go.mod | |
| cache: true | |
| - name: Report Go cache status | |
| run: | | |
| if [ "${{ steps.setup-go.outputs.cache-hit }}" == "true" ]; then | |
| echo "✅ Go cache hit" >> $GITHUB_STEP_SUMMARY | |
| else | |
| echo "⚠️ Go cache miss" >> $GITHUB_STEP_SUMMARY | |
| fi | |
| # Go formatting check (fast, no deps needed) | |
| - name: Check Go formatting | |
| run: | | |
| unformatted=$(go fmt ./...) | |
| if [ -n "$unformatted" ]; then | |
| echo "❌ Code is not formatted. Run 'make fmt' to fix." >> $GITHUB_STEP_SUMMARY | |
| echo "Unformatted files:" >> $GITHUB_STEP_SUMMARY | |
| echo "$unformatted" >> $GITHUB_STEP_SUMMARY | |
| echo "" | |
| echo "To fix this locally, run:" | |
| echo " make fmt" | |
| echo "" | |
| echo "Or format individual files with:" | |
| echo " go fmt ./path/to/file.go" | |
| exit 1 | |
| fi | |
| echo "✅ Go formatting check passed" >> $GITHUB_STEP_SUMMARY | |
| # Install build tools from tools.go | |
| - name: Install build tools | |
| run: make tools | |
| # Run golangci-lint via Makefile for consistency | |
| # Uses incremental linting on PRs for faster CI (50-75% speedup) | |
| - name: Run golangci-lint | |
| run: | | |
| export PATH="$PATH:$(go env GOPATH)/bin" | |
| if [ "${{ github.event_name }}" = "pull_request" ]; then | |
| # Incremental linting on PRs - only check changed files | |
| # This provides 50-75% faster linting on typical PRs | |
| make golint-incremental BASE_REF=origin/${{ github.base_ref }} | |
| else | |
| # Full scan on main branch to ensure comprehensive coverage | |
| make golint | |
| fi | |
| # Error message linting (requires Go only) | |
| - name: Lint error messages | |
| run: make lint-errors | |
| lint-js: | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| concurrency: | |
| group: ci-${{ github.ref }}-lint-js | |
| cancel-in-progress: true | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 | |
| - name: Set up Node.js | |
| id: setup-node | |
| uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6 | |
| with: | |
| node-version: "24" | |
| cache: npm | |
| cache-dependency-path: actions/setup/js/package-lock.json | |
| - name: Report Node cache status | |
| run: | | |
| if [ "${{ steps.setup-node.outputs.cache-hit }}" == "true" ]; then | |
| echo "✅ Node cache hit" >> $GITHUB_STEP_SUMMARY | |
| else | |
| echo "⚠️ Node cache miss" >> $GITHUB_STEP_SUMMARY | |
| fi | |
| - name: Install npm dependencies | |
| run: cd actions/setup/js && npm ci | |
| # JavaScript and JSON formatting checks | |
| - name: Lint JavaScript files | |
| run: make lint-cjs | |
| - name: Check JSON formatting | |
| run: make fmt-check-json | |
| audit: | |
| needs: [lint-go, lint-js] | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| concurrency: | |
| group: ci-${{ github.ref }}-audit | |
| cancel-in-progress: true | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 | |
| - name: Set up Go | |
| id: setup-go | |
| uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6 | |
| with: | |
| go-version-file: go.mod | |
| cache: true | |
| - name: Report Go cache status | |
| run: | | |
| if [ "${{ steps.setup-go.outputs.cache-hit }}" == "true" ]; then | |
| echo "✅ Go cache hit" >> $GITHUB_STEP_SUMMARY | |
| else | |
| echo "⚠️ Go cache miss" >> $GITHUB_STEP_SUMMARY | |
| fi | |
| - name: Verify dependencies | |
| run: go mod verify | |
| - name: Build gh-aw binary | |
| run: make build | |
| - name: Run dependency audit (human-readable) | |
| run: | | |
| echo "## Dependency Health Audit" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| ./gh-aw update --audit 2>&1 | tee audit_output.txt || true | |
| echo "\`\`\`" >> $GITHUB_STEP_SUMMARY | |
| head -100 audit_output.txt >> $GITHUB_STEP_SUMMARY | |
| echo "\`\`\`" >> $GITHUB_STEP_SUMMARY | |
| - name: Run dependency audit (JSON) | |
| id: audit_json | |
| run: | | |
| # Run audit with JSON output for agent-friendly parsing | |
| ./gh-aw update --audit --json > audit.json 2>&1 | |
| # Display summary in GitHub Actions | |
| echo "✅ Dependency audit completed" >> $GITHUB_STEP_SUMMARY | |
| # Extract key metrics | |
| TOTAL_DEPS=$(jq '.summary.total_dependencies' audit.json) | |
| OUTDATED=$(jq '.summary.outdated_count' audit.json) | |
| SECURITY=$(jq '.summary.security_advisories' audit.json) | |
| V0_PERCENT=$(jq '.summary.v0_percentage' audit.json) | |
| echo "📊 **Audit Results:**" >> $GITHUB_STEP_SUMMARY | |
| echo "- Total dependencies: $TOTAL_DEPS" >> $GITHUB_STEP_SUMMARY | |
| echo "- Outdated: $OUTDATED" >> $GITHUB_STEP_SUMMARY | |
| echo "- Security advisories: $SECURITY" >> $GITHUB_STEP_SUMMARY | |
| echo "- v0.x exposure: ${V0_PERCENT}%" >> $GITHUB_STEP_SUMMARY | |
| - name: Upload audit results | |
| uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 | |
| with: | |
| name: dependency-audit | |
| path: | | |
| audit.json | |
| audit_output.txt | |
| retention-days: 30 | |
| actions-build: | |
| needs: [lint-go, lint-js] | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| concurrency: | |
| group: ci-${{ github.ref }}-actions-build | |
| cancel-in-progress: true | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 | |
| - name: Set up Go | |
| id: setup-go | |
| uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6 | |
| with: | |
| go-version-file: go.mod | |
| cache: true | |
| - name: Report Go cache status | |
| run: | | |
| if [ "${{ steps.setup-go.outputs.cache-hit }}" == "true" ]; then | |
| echo "✅ Go cache hit" >> $GITHUB_STEP_SUMMARY | |
| else | |
| echo "⚠️ Go cache miss" >> $GITHUB_STEP_SUMMARY | |
| fi | |
| - name: Verify dependencies | |
| run: go mod verify | |
| - name: Build actions | |
| run: make actions-build | |
| - name: Validate actions | |
| run: make actions-validate | |
| fuzz: | |
| needs: [lint-go, lint-js] | |
| # Only run fuzz tests on main branch (10s is insufficient for PRs) | |
| if: github.ref == 'refs/heads/main' | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| concurrency: | |
| group: ci-${{ github.ref }}-fuzz | |
| cancel-in-progress: true | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 | |
| - name: Set up Go | |
| id: setup-go | |
| uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6 | |
| with: | |
| go-version-file: go.mod | |
| cache: true | |
| - name: Report Go cache status | |
| run: | | |
| if [ "${{ steps.setup-go.outputs.cache-hit }}" == "true" ]; then | |
| echo "✅ Go cache hit" >> $GITHUB_STEP_SUMMARY | |
| else | |
| echo "⚠️ Go cache miss" >> $GITHUB_STEP_SUMMARY | |
| fi | |
| - name: Verify dependencies | |
| run: go mod verify | |
| - name: Run fuzz tests | |
| run: | | |
| go test -run='^$' -fuzz=FuzzParseFrontmatter -fuzztime=10s ./pkg/parser/ | |
| go test -run='^$' -fuzz=FuzzScheduleParser -fuzztime=10s ./pkg/parser/ | |
| go test -run='^$' -fuzz=FuzzExpressionParser -fuzztime=10s ./pkg/workflow/ | |
| go test -run='^$' -fuzz=FuzzMentionsFiltering -fuzztime=10s ./pkg/workflow/ | |
| go test -run='^$' -fuzz=FuzzSanitizeOutput -fuzztime=10s ./pkg/workflow/ | |
| go test -run='^$' -fuzz=FuzzSanitizeIncomingText -fuzztime=10s ./pkg/workflow/ | |
| go test -run='^$' -fuzz=FuzzSanitizeLabelContent -fuzztime=10s ./pkg/workflow/ | |
| go test -run='^$' -fuzz=FuzzWrapExpressionsInTemplateConditionals -fuzztime=10s ./pkg/workflow/ | |
| go test -run='^$' -fuzz=FuzzYAMLParsing -fuzztime=10s ./pkg/workflow/ | |
| go test -run='^$' -fuzz=FuzzTemplateRendering -fuzztime=10s ./pkg/workflow/ | |
| go test -run='^$' -fuzz=FuzzInputValidation -fuzztime=10s ./pkg/workflow/ | |
| go test -run='^$' -fuzz=FuzzNetworkPermissions -fuzztime=10s ./pkg/workflow/ | |
| go test -run='^$' -fuzz=FuzzSafeJobConfig -fuzztime=10s ./pkg/workflow/ | |
| security: | |
| needs: [lint-go, lint-js] # Run in parallel with test to reduce critical path | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| concurrency: | |
| group: ci-${{ github.ref }}-security | |
| cancel-in-progress: true | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 | |
| - name: Set up Go | |
| id: setup-go | |
| uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6 | |
| with: | |
| go-version-file: go.mod | |
| cache: true | |
| - name: Report Go cache status | |
| run: | | |
| if [ "${{ steps.setup-go.outputs.cache-hit }}" == "true" ]; then | |
| echo "✅ Go cache hit" >> $GITHUB_STEP_SUMMARY | |
| else | |
| echo "⚠️ Go cache miss" >> $GITHUB_STEP_SUMMARY | |
| fi | |
| - name: Verify dependencies | |
| run: go mod verify | |
| - name: Run security regression tests | |
| run: make test-security | |
| security-scan: | |
| needs: [lint-go, lint-js] # Run in parallel with test to reduce critical path | |
| # Only run security scans on main branch to reduce PR overhead | |
| if: github.ref == 'refs/heads/main' | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 # Prevent jobs from hanging indefinitely | |
| permissions: | |
| contents: read | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| tool: | |
| - name: zizmor | |
| flag: --zizmor | |
| - name: actionlint | |
| flag: --actionlint | |
| - name: poutine | |
| flag: --poutine | |
| concurrency: | |
| group: ci-${{ github.ref }}-security-scan-${{ matrix.tool.name }} | |
| cancel-in-progress: true | |
| name: "Security Scan: ${{ matrix.tool.name }}" | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 | |
| - name: Set up Go | |
| id: setup-go | |
| uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6 | |
| with: | |
| go-version-file: go.mod | |
| cache: true | |
| - name: Report Go cache status | |
| run: | | |
| if [ "${{ steps.setup-go.outputs.cache-hit }}" == "true" ]; then | |
| echo "✅ Go cache hit" >> $GITHUB_STEP_SUMMARY | |
| else | |
| echo "⚠️ Go cache miss" >> $GITHUB_STEP_SUMMARY | |
| fi | |
| - name: Build gh-aw | |
| run: make build | |
| - name: Run ${{ matrix.tool.name }} security scan on poem workflow | |
| run: ./gh-aw compile poem-bot ${{ matrix.tool.flag }} | |
| logs-token-check: | |
| needs: [lint-go, lint-js] # Run in parallel with test to reduce critical path | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| concurrency: | |
| group: ci-${{ github.ref }}-logs-token-check | |
| cancel-in-progress: true | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 | |
| - name: Set up Go | |
| id: setup-go | |
| uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6 | |
| with: | |
| go-version-file: go.mod | |
| cache: true | |
| - name: Report Go cache status | |
| run: | | |
| if [ "${{ steps.setup-go.outputs.cache-hit }}" == "true" ]; then | |
| echo "✅ Go cache hit" >> $GITHUB_STEP_SUMMARY | |
| else | |
| echo "⚠️ Go cache miss" >> $GITHUB_STEP_SUMMARY | |
| fi | |
| - name: Build gh-aw | |
| run: make build | |
| - name: Run logs command with JSON output | |
| id: logs_check | |
| run: | | |
| # Run the logs command and capture output | |
| ./gh-aw logs -c 2 --engine copilot --json > logs_output.json 2>&1 || true | |
| # Display the output for debugging | |
| echo "Logs command output:" | |
| cat logs_output.json | |
| # Check if token count is found in the JSON output | |
| if jq -e '.summary.total_tokens' logs_output.json > /dev/null 2>&1; then | |
| TOKEN_COUNT=$(jq '.summary.total_tokens' logs_output.json) | |
| echo "✅ Token count found: $TOKEN_COUNT" >> $GITHUB_STEP_SUMMARY | |
| echo "token_count=$TOKEN_COUNT" >> $GITHUB_OUTPUT | |
| exit 0 | |
| else | |
| echo "❌ Token count not found in JSON output" >> $GITHUB_STEP_SUMMARY | |
| exit 1 | |
| fi | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} |