Skip to content

fix(ci): use env scope for secrets in gating if: expressions#431

Merged
ruvnet merged 1 commit intomainfrom
fix/ci-workflows-secrets-in-if
Apr 26, 2026
Merged

fix(ci): use env scope for secrets in gating if: expressions#431
ruvnet merged 1 commit intomainfrom
fix/ci-workflows-secrets-in-if

Conversation

@ruvnet
Copy link
Copy Markdown
Owner

@ruvnet ruvnet commented Apr 26, 2026

Root cause

Every push to main has produced a 0-second CI failure with 0 jobs executed — visible on PR #389, #377, #405, #425, #426, #427, #430, and every commit since. The workflow appeared to fail without ever running anything.

Confirmed via direct API dispatch:

```
$ gh api -X POST repos/ruvnet/RuView/actions/workflows/167079093/dispatches -f ref=main
422 Invalid Argument - failed to parse workflow:
(Line: 315, Col: 11): Unrecognized named-value: 'secrets'.
Located at position 1 within expression: secrets.SLACK_WEBHOOK_URL != ''
```

The Slack-notify steps in `ci.yml` (lines 315/325) and `security-scan.yml` (line 406) used `${{ secrets.X != '' }}` directly in step-level `if:` conditions. GitHub Actions does not allow direct `secrets.X` access in `if:` expressions — only `env.X` is valid in that context. The whole workflow file was rejected during parse, every job was skipped, and a "failure" status was reported with no logs.

Fix

Promote the secret to job-level `env:` so step-level `if:` references `env.X`. The actual secret value still flows through unchanged at runtime.

Before:
```yaml
notify:
steps:

  • name: Notify Slack on success
    if: ${{ secrets.SLACK_WEBHOOK_URL != '' && needs.foo.result == 'success' }}
    env:
    SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
    ```

After:
```yaml
notify:
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
steps:

  • name: Notify Slack on success
    if: ${{ env.SLACK_WEBHOOK_URL != '' && needs.foo.result == 'success' }}
    ```

Same pattern applied to `security-scan.yml` for `SECURITY_SLACK_WEBHOOK_URL`.

Validation

```
$ gh api -X POST repos/ruvnet/RuView/actions/workflows/167079093/dispatches -f ref=fix/ci-workflows-secrets-in-if
(no error — workflow now parses)

$ gh run list --workflow ci.yml --branch fix/ci-workflows-secrets-in-if
[{"name":"Continuous Integration","status":"in_progress","event":"workflow_dispatch"}]
```

Pre-fix: `name: ".github/workflows/ci.yml"` (path — GitHub's fallback when the YAML name field can't be read), `status: completed` with 0 jobs in 0s.

Post-fix: `name: "Continuous Integration"` (matches the YAML `name:` field at line 1), `status: in_progress`, jobs actually executing.

What this PR does NOT fix

The CI runs may still fail for real reasons once they actually execute (missing CI dependencies, broken tests, missing secrets, etc.). This PR only restores honesty: failures will now produce real logs you can read, instead of vanishing into a 0-second startup error.

If `SLACK_WEBHOOK_URL` / `SECURITY_SLACK_WEBHOOK_URL` aren't configured as repo secrets, the corresponding notify steps will skip gracefully (`env.X == ''`), which is the intended behavior.

Test plan

  • `gh api workflow dispatch` no longer returns 422
  • Manually-dispatched run reaches `in_progress` status with name "Continuous Integration"
  • Real PR-driven runs against this branch reach completion (passing or failing) with actual logs
  • Confirm `security-scan.yml` parses on next `schedule` trigger or manual dispatch

🤖 Generated with claude-flow

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 <ruv@ruv.net>
@ruvnet ruvnet merged commit 74233cf into main Apr 26, 2026
3 of 17 checks passed
@ruvnet ruvnet deleted the fix/ci-workflows-secrets-in-if branch April 26, 2026 03:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant