fix(ci): move hashFiles() out of job-level if: — the last red workflow - #88
Merged
Merged
Conversation
The duplicate `permissions:` key was necessary to fix but NOT sufficient: comprehensive-quality.yml still produced a run with ZERO jobs and no check run on the previous commit, i.e. it was still rejected at parse time. Second, independent defect, confirmed with actionlint: .github/workflows/comprehensive-quality.yml:156:9: calling function "hashFiles" is not allowed here. "hashFiles" is only available in "jobs.<job_id>.steps.*" contexts `hashFiles()` in a job-level `if:` makes Actions reject the WHOLE FILE, so none of the 11 jobs ever materialised. It was also semantically pointless there: at job level nothing is checked out yet, so the glob could never match. Moved the guard onto the two steps that actually need it, where it runs after checkout and is a valid context. Verified: `actionlint .github/workflows/*.yml` now reports zero expression or syntax errors across all 19 files; the only remaining output is shellcheck style/info (SC2086, SC2129, SC2035, ...) in unrelated workflows. Lesson for the estate: a strict YAML duplicate-key scan is NOT sufficient to prove an Actions workflow parses. YAML validity and Actions validity are different things — use actionlint. Co-Authored-By: Claude Opus 5 <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.
The final red workflow on
main. Everything else is green as of29abb4c.Why #87 did not finish the job
#87 fixed a genuine defect — a duplicate top-level
permissions:key incomprehensive-quality.yml— but that was necessary, not sufficient. The filewas rejected at parse time for a second, independent reason, so it still
produced runs with zero jobs and no check run afterwards.
(#87 was squash-merged just before the follow-up commit landed on its branch,
so that second fix never reached
main. This PR carries it.)The remaining defect
hashFiles()sat in a job-levelif:. That is not a permitted context andit makes Actions reject the entire file — which is why none of the 11 jobs
ever materialised, and why the workflow still shows in the UI as the raw path
.github/workflows/comprehensive-quality.ymlrather than its name(
Comprehensive Quality Gates): GitHub has never parsed far enough to read it.It was also meaningless where it was — at job level nothing is checked out yet,
so the glob could never match. The guard now sits on the two steps that need it,
evaluating after checkout, which is both valid and actually correct.
Verification
actionlint .github/workflows/comprehensive-quality.yml→ 0 findings(was 1 fatal expression error). Across all workflows, the only remaining
actionlint output is shellcheck style/info in unrelated files.
Expect this run to produce 11 jobs. Job count is the discriminator: zero
jobs means still parse-dead, non-zero means it parses and any failure is a real
quality-gate result to triage on its merits.
Method note worth keeping
A strict YAML duplicate-key scan is not sufficient to prove an Actions
workflow parses — YAML validity and Actions validity are different things, and
my earlier YAML-only check passed this file while GitHub still rejected it.
actionlintmodels the real rules and catches this class immediately. Given theestate tracks ~187 unparseable workflow files, it is the right instrument for
that sweep.
Context:
dev-notes/betlang-sitrep-2026-07-27.md.🤖 Generated with Claude Code