From 3024a4e39c54aeab7034271b1b4973d8ceb23772 Mon Sep 17 00:00:00 2001 From: ruv Date: Sat, 25 Apr 2026 23:05:28 -0400 Subject: [PATCH] fix(ci): use env scope for secrets in gating if: expressions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GitHub Actions does not allow `secrets.X` to appear directly in step-level `if:` expressions — only `env.X` is valid in that context. Both ci.yml and security-scan.yml had Slack-notify steps gated on `secrets.SLACK_WEBHOOK_URL != ''`, which made the entire workflow fail to parse. Result: every push to main produced a 0-second failure with 0 jobs run, masquerading as a CI signal that wasn't actually running CI. Confirmed root cause via: gh api -X POST repos/.../actions/workflows/167079093/dispatches \ -f ref=main → 422 Invalid Argument - failed to parse workflow: (Line: 315, Col: 11): Unrecognized named-value: 'secrets' Fix: promote the secret to job-level `env:` so step-level `if:` references `env.SLACK_WEBHOOK_URL`. The actual secret value still flows through unchanged for the action's runtime use. Same pattern applied to security-scan.yml line 406 (the existing SECURITY_SLACK_WEBHOOK_URL gate). After this lands, every push to main should produce real CI runs that actually execute jobs and reflect repo health honestly. The runs may still fail for *real* reasons (e.g., CI image dependencies, test gaps), but they will fail visibly with logs instead of in 0s with no jobs. Co-Authored-By: claude-flow --- .github/workflows/ci.yml | 13 +++++++------ .github/workflows/security-scan.yml | 12 ++++++++++-- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7a9daaaf8..6de962ddb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -310,26 +310,27 @@ jobs: runs-on: ubuntu-latest needs: [code-quality, test, rust-tests, performance-test, docker-build, docs] if: always() + # GitHub Actions does not allow `secrets.X` directly in step-level `if:` + # expressions — only `env.X`. Promote the secret to env at job scope so + # the gating expression below is parseable. + env: + SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} steps: - name: Notify Slack on success - if: ${{ secrets.SLACK_WEBHOOK_URL != '' && needs.code-quality.result == 'success' && needs.test.result == 'success' && needs.docker-build.result == 'success' }} + if: ${{ env.SLACK_WEBHOOK_URL != '' && needs.code-quality.result == 'success' && needs.test.result == 'success' && needs.docker-build.result == 'success' }} uses: 8398a7/action-slack@v3 with: status: success channel: '#ci-cd' text: '✅ CI pipeline completed successfully for ${{ github.ref }}' - env: - SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} - name: Notify Slack on failure - if: ${{ secrets.SLACK_WEBHOOK_URL != '' && (needs.code-quality.result == 'failure' || needs.test.result == 'failure' || needs.docker-build.result == 'failure') }} + if: ${{ env.SLACK_WEBHOOK_URL != '' && (needs.code-quality.result == 'failure' || needs.test.result == 'failure' || needs.docker-build.result == 'failure') }} uses: 8398a7/action-slack@v3 with: status: failure channel: '#ci-cd' text: '❌ CI pipeline failed for ${{ github.ref }}' - env: - SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} - name: Create GitHub Release if: github.ref == 'refs/heads/main' && needs.docker-build.result == 'success' diff --git a/.github/workflows/security-scan.yml b/.github/workflows/security-scan.yml index 920e42cbf..b60d275bc 100644 --- a/.github/workflows/security-scan.yml +++ b/.github/workflows/security-scan.yml @@ -377,6 +377,11 @@ jobs: runs-on: ubuntu-latest needs: [sast, dependency-scan, container-scan, iac-scan, secret-scan, license-scan, compliance-check] if: always() + # Promote secret to env-scope so the gating `if:` on the Slack-notify + # step below is parseable (GitHub Actions rejects `secrets.X` in + # step-level `if:` expressions). + env: + SECURITY_SLACK_WEBHOOK_URL: ${{ secrets.SECURITY_SLACK_WEBHOOK_URL }} steps: - name: Download all artifacts uses: actions/download-artifact@v4 @@ -402,8 +407,11 @@ jobs: name: security-summary path: security-summary.md + # GitHub Actions does not allow `secrets.X` in step-level `if:` — + # use env.X instead. Inherits SECURITY_SLACK_WEBHOOK_URL from the + # job-level env block (added below). - name: Notify security team on critical findings - if: ${{ secrets.SECURITY_SLACK_WEBHOOK_URL != '' && (needs.sast.result == 'failure' || needs.dependency-scan.result == 'failure' || needs.container-scan.result == 'failure') }} + if: ${{ env.SECURITY_SLACK_WEBHOOK_URL != '' && (needs.sast.result == 'failure' || needs.dependency-scan.result == 'failure' || needs.container-scan.result == 'failure') }} uses: 8398a7/action-slack@v3 with: status: failure @@ -415,7 +423,7 @@ jobs: Workflow: ${{ github.workflow }} Please review the security scan results immediately. env: - SLACK_WEBHOOK_URL: ${{ secrets.SECURITY_SLACK_WEBHOOK_URL }} + SLACK_WEBHOOK_URL: ${{ env.SECURITY_SLACK_WEBHOOK_URL }} - name: Create security issue on critical findings if: needs.sast.result == 'failure' || needs.dependency-scan.result == 'failure'