Matt Palmer

Matt Palmer

November 25, 2021

Linting your GitHub Actions

Your infrastructure-as-code is still code, and all that YAML needs to be checked for correctness. So does ours, and we did something about it.

CipherStash - Linting your GitHub Actions

GitHub's CI/CD offering, GitHub Actions, is a solid product that CipherStash uses extensively. At the end of the day, though, Actions are still code, and as such they need to be linted and checked like the rest of your codebase. In the spirit of "trust, but verify", I've developed a Rust tool to validate these YAML files that we're using to good effect here at Stashie HQ.

But... They're Just YAML!

the devops nightmare... yaml everywhere

Just because it's "only" a configuration file, doesn't mean you can't make mistakes with YAML. In many ways, linting your GitHub Actions files is more important than many of your other development artifacts, because you can't test them before pushing. If you've worked with GitHub Actions for any length of time, you've probably got something like this in your shell history:

git commit -am "Improve test action" git commit -am "Fix test action syntax" git commit -am "Fix test action take 2" git commit -am "Try this fix instead" git commit -am "ffs" ...

git commit yaml table flip

Invalid YAML syntax, failing to abide by the required "structure" of a GitHub Action file, and a whole host of other problems: you only find out about them after you push. As my shell history can attest, this is a painful and annoying way to work.

The worst problem, though, is yet to come.

The Typo Strikes Back

You can (and should!) restrict workflows to only run when commits change files in certain parts of your repo. This speeds up PR checking (as irrelevant checks aren't run) and saves your precious minutes. However, one typo -- or renamed directory -- can ruin your day, as all of a sudden your check never runs:

name: Test PR on: pull_request: branches: [main] paths: - srcc/** - test/**

One little extra c in there, and your test suite never gets run. Ruination!


After being bitten by one-too-many typos and profanity-laden commit messages, I decided to break out the thinking geek's favourite tool: Rust.

i can fix this with rust

The end result was action-validator, a very simple tool that:

  • Ensures that any Action or Workflow definition file is valid YAML;
  • That it has all the required fields, and no unknown fields, by validating the structure against published schemas; and
  • That all globs mentioned in paths and paths-ignore lists match at least one file in the repo.

By inserting this into our standard pre-commit hook, like so:

for file in $(git diff --cached --name-only); do if [[ "$file" =~ ^\.github/(workflows|actions)/.*\.yml$ ]]; then echo "==> action-validator $file..." action-validator "$file" fi done

We now get early warning of any common problems being introduced into our codebase. WINNAH!

asdf arglebargle

As an aside, we're heavy users of the asdf version manager, so it was natural that action-validator would support that from day 0. Hence, if you also are a member of the Church of asdf (meetings weekly, tea and biscuits provided), you can just do the following:

$ asdf plugin add action-validator $ echo "action-validator $(asdf latest action-validator)" >> .tool-versions

... and everyone will have action-validator ready and waiting for their next commit.

That's... it?

Yes, for now. Simple tools are quality tools. Of course, if you've got ideas for more things that action-validator could check, PRs are always welcome. Be the change you wish to see in the world!

About the Author

Ready to protect your data?

Try QX for Free

No credit card required.

Latest Posts

View All Articles