Skip to content

chore: validate workflow YAML in the pre-commit hook - #265

Merged
rabestro merged 2 commits into
mainfrom
chore/workflow-yaml-hook
Aug 2, 2026
Merged

chore: validate workflow YAML in the pre-commit hook#265
rabestro merged 2 commits into
mainfrom
chore/workflow-yaml-hook

Conversation

@rabestro

@rabestro rabestro commented Aug 2, 2026

Copy link
Copy Markdown
Owner

Summary

Adds a workflow-yaml pre-commit job that parses staged .github/workflows/*.y*ml.

A broken workflow does not fail CI — it silently stops running, so its checks disappear rather than turn red, and release-only workflows are not exercised by a pull request at all, so nothing surfaces until a release. This happened for real in dicechess-engine-scala: an editing mistake left publish.yaml and release.yaml invalid on main for hours with every check green (rabestro/dicechess-engine-scala#542).

Same job, same wording as the one added there, so the hook config stays consistent across repos.

Verification

  • lefthook validateAll good, and the job shows up in pre-commit
  • Negative tested: the exact command exits non-zero on a workflow with the original defect (a step missing its - name: with an out-dented run:) — a guard never seen failing is not a guard
  • Passes on this repo's existing workflow files
  • Only lefthook.yml changed, one insertion

Ruby ships with macOS and the GitHub runners, so this needs no new tooling and costs milliseconds.

🤖 Generated with Claude Code

A broken workflow does not fail CI — it silently stops running, so its checks
disappear rather than turn red, and release-only workflows are not exercised by
a pull request at all. dicechess-engine-scala had publish.yaml and release.yaml
invalid on main for hours with every check green (see that repo's #542).

Negative tested: the command exits non-zero on a workflow with that exact
defect, and passes on this repo's existing workflows. Ruby ships with macOS and
the runners, so this adds no tooling and costs milliseconds.
@coderabbitai

coderabbitai Bot commented Aug 2, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 2a67ef84-5582-4184-99cf-af185fab27e6

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@rabestro rabestro self-assigned this Aug 2, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@lefthook.yml`:
- Around line 25-27: Update the pre-commit jobs documentation in development.md
to include workflow-yaml alongside betterleaks and scalafmt, matching the job
configured in lefthook.yml. Preserve the existing documentation structure and
descriptions for the other jobs.
- Around line 25-27: Update the workflow-yaml hook in lefthook.yml to remove its
dependency on the unprovisioned Ruby YAML parser, or add a pinned Ruby
installation to mise.toml and supported workflow environments. Ensure
contributors can run this pre-commit validation with the documented toolchain.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 96ff648f-e93d-447d-90da-b57755c9472f

📥 Commits

Reviewing files that changed from the base of the PR and between 9b0aafa and 5791c3d.

📒 Files selected for processing (1)
  • lefthook.yml

Comment thread lefthook.yml Outdated
Addresses both CodeRabbit findings on #265.

Ruby was an undeclared dependency: mise.toml provisions only JVM tooling and CLI
utilities, and no workflow installs Ruby, so a contributor without it could not
commit workflow changes. This repo is public, so that is a real barrier.

actionlint is pinned in mise.toml, so `mise install` provides it like every other
tool, and it is strictly stronger than the previous check: it rejects the same
invalid indentation AND catches duplicate keys, which a plain YAML load accepts
silently. Verified both — the malformed-step fixture and a duplicate-key fixture
are each rejected, and this repo's own workflows pass.

`-shellcheck=` disables the optional shell lint of `run:` bodies. actionlint picks
shellcheck up from PATH when present, and a mise shim with no version installed
makes it abort with a fatal error, so leaving it off keeps this job dependent on
actionlint and nothing else.

Also documents the job in development.md, which listed only betterleaks and
scalafmt.
@github-actions github-actions Bot added documentation Improvements or additions to documentation ci-cd Continuous integration pipelines and deployment setups labels Aug 2, 2026
@rabestro
rabestro merged commit 9b965de into main Aug 2, 2026
3 checks passed
@rabestro
rabestro deleted the chore/workflow-yaml-hook branch August 2, 2026 13:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci-cd Continuous integration pipelines and deployment setups documentation Improvements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant