fix(rust-ci-reusable): wrap bare job-level if: in ${{ }} so GH parses (closes #322)#334
Merged
Merged
Conversation
…ns parses (fixes #322) GH Actions silently fails to parse the entire caller workflow when the reusable's job-level \`if:\` is a bare expression containing \`hashFiles(format('{0}/...', inputs.X))\`. The parse failure shows up estate-wide as 0s-duration "completed failure" runs since 2026-05-26 across 43+ callers, with the caller's workflow name reported as the path (\`.github/workflows/rust-ci.yml\`) instead of the YAML \`name:\` field — GitHub's tell-tale "workflow file issue". The audit and coverage jobs (lines 187, 215) already used \`\${{ ... }}\` wrapping and parsed cleanly. The check (109) and test (149) jobs used the bare form because, viewed in isolation, the YAML spec permits both. Empirically confirmed via 5-commit experiment on panic-attack#95: caller @cc5a372a → fail (name=path) rust-ci-reusable.yml caller @main → fail (name=path) rust-ci-reusable.yml caller w/governance.yml shape → fail (name=path) rust-ci-reusable.yml caller pointing at governance-reusable → PASS (name="Rust CI") caller verbatim clone of governance.yml → PASS Only the swap to governance-reusable.yml made the parse succeed → the bug is in rust-ci-reusable.yml specifically. The only structural diff between governance-reusable.yml and rust-ci-reusable.yml in the \`if:\` shape is exactly this bare-vs-wrapped split, and the bare lines in rust-ci-reusable.yml had a \`format()\` + \`inputs.X\` substitution that GH's expression parser rejects at job-level without the \`\${{ }}\` hint. Closes #322. Falsifies hypotheses 1+2+3 from the issue (caller structure, SHA resolution, workflow_id cache); root cause is hypothesis 4 (bare \`if:\` with \`hashFiles(format(inputs.X))\` at job level). Verified locally: - yamllint clean - yaml.safe_load parses both pre- and post-fix - the experiment branch panic-attack#95 last commit (governance-shape pointing at governance-reusable.yml) had name='Rust CI' parsed correctly Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This was referenced Jun 1, 2026
🔍 Hypatia Security ScanFindings: 201 issues detected
View findings[
{
"reason": "Action (for the check script)\n uses: actions/checkout@de needs attention",
"type": "unpinned_action",
"file": "governance-reusable.yml",
"action": "pin_sha",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Action (for the check script)\n uses: actions/checkout@de needs attention",
"type": "unpinned_action",
"file": "governance-reusable.yml",
"action": "pin_sha",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Issue in affinescript-verify.yml",
"type": "missing_timeout_minutes",
"file": "affinescript-verify.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Issue in boj-build.yml",
"type": "missing_timeout_minutes",
"file": "boj-build.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Issue in casket-pages.yml",
"type": "missing_timeout_minutes",
"file": "casket-pages.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Issue in casket-pages.yml",
"type": "missing_timeout_minutes",
"file": "casket-pages.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Issue in changelog-reusable.yml",
"type": "missing_timeout_minutes",
"file": "changelog-reusable.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Issue in codeql-reusable.yml",
"type": "missing_timeout_minutes",
"file": "codeql-reusable.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Issue in codeql.yml",
"type": "missing_timeout_minutes",
"file": "codeql.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Issue in deno-ci-reusable.yml",
"type": "missing_timeout_minutes",
"file": "deno-ci-reusable.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium"
}
]Powered by Hypatia Neurosymbolic CI/CD Intelligence |
hyperpolymath
added a commit
that referenced
this pull request
Jun 1, 2026
…-pattern as #322/#334) elixir-ci-reusable.yml:105 had the same bare-`if:`-at-job-level pattern that #334 fixed in rust-ci-reusable.yml. Surfaced via the sweep recipe documented in standards#334: grep -nE '^\s+if: [^$]+(hashFiles|format|inputs\.)' .github/workflows/*-reusable.yml The mix.exs guard is structurally identical to the Cargo.toml guard that broke 43+ Rust callers — same fix. Follow-up audit: same grep found ZERO additional hits in other reusables (governance/secret-scanner/scorecard/mirror/casket/dogfood). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
hyperpolymath
added a commit
that referenced
this pull request
Jun 1, 2026
…-pattern as #322/#334) (#336) ## Summary Same root cause as #322 / #334 — \`elixir-ci-reusable.yml:105\` had a bare \`if:\` at job level containing \`hashFiles(format('{0}/mix.exs', inputs.working_directory))\`. Surfaced via the sweep recipe from #334: \`\`\`bash grep -nE '^\\s+if: [^\$]+(hashFiles|format|inputs\\.)' .github/workflows/*-reusable.yml \`\`\` Only hit — every other reusable is clean. Same 2-line `\${{ }}` wrap. ## Test plan - [x] Sweep recipe returns no remaining hits across reusables - [x] yamllint clean - [x] Pattern matches #334's exact diff shape 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
hyperpolymath
added a commit
to hyperpolymath/panic-attack
that referenced
this pull request
Jun 1, 2026
…st-ci.yml from baseline-red) (#97) ## Summary \`standards#334\` (merged 2026-06-01T18:37Z) wrapped the bare job-level \`if:\` in \`rust-ci-reusable.yml\` that GH Actions had been silently rejecting since 2026-05-26 — the parse failure tracked in standards#322 that produced 0s-duration "completed failure" runs across the estate. Bumps panic-attack's pin from \`cc5a372a\` (pre-fix) to \`d7c3b8f7\` (current standards/main HEAD; includes #334 and follow-up canonical-wrapper SHA sweep #335). ## Test plan - [x] SHA exists on standards/main: \`gh api /repos/hyperpolymath/standards/commits/d7c3b8f75d70ab640e6f37a4c8f9e6e8f2b6df56\` returns 200 - [x] Includes standards#334 fix in its history - [ ] On merge: rust-ci.yml run should report \`name='Rust CI'\` (parsed) instead of \`name='.github/workflows/rust-ci.yml'\` (path fallback) - [ ] Jobs (\`check\` + \`test\`) should actually execute rather than 0s-fail ## Refs - Closes panic-attack#84 retroactively (orphan-SHA hypothesis was incorrect; real bug fixed at source). - Refs hyperpolymath/standards#322, hyperpolymath/standards#334. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
`rust-ci-reusable.yml` lines 109 and 149 used a bare `if:` expression at job level:
```yaml
if: hashFiles(format('{0}/Cargo.toml', inputs.working_directory)) != ''
```
GH Actions silently fails to parse the entire CALLER workflow when this exact shape (
hashFiles(format(inputs.X))bare at job-level) is reached in a reusable. Caller manifests as 0s-duration "completed failure" with the workflow name reported as the path (.github/workflows/rust-ci.yml) instead of the YAMLname:field — GitHub's "This run likely failed because of a workflow file issue" diagnostic.Root-cause investigation
Run on panic-attack#95 (experiment branch, 5 commits), tracking the parsed workflow
namefield via API:1d0a8b9@cc5a372arust-ci-reusable.ymld022c8f@mainrust-ci-reusable.yml02c6753@mainrust-ci-reusable.yml6250e19@maingovernance-reusable.yml'Rust CI'✓cb23224@maingovernance-reusable.yml'Rust CI'✓Falsifies #322 hypotheses 1+2+3:
@mainfloating ref ALSO failed.Root cause: hypothesis 4 (new) — when the caller's `uses:` resolves to a reusable whose first job has a bare `if: hashFiles(format(...))` at job level, GH's expression evaluator rejects the resolution at workflow-parse time. The audit + coverage jobs (lines 187, 215) were always wrapped in `${{ }}` and worked; the check + test jobs were not.
The fix
Two-line
if:wrapping. Diff:```diff
```
Estate impact
Once this merges, every caller of `rust-ci-reusable.yml` should immediately start parsing on its next push — no caller-side action needed for callers using `@main` floating refs. SHA-pinned callers will need to bump the pin to a commit at-or-after this merge.
Follow-up
Refs
🤖 Generated with Claude Code