Adding the GitHub Super Linter Action
GitHub recently announced the Super Linter, a Docker container that can be run via GitHub Actions and comes complete with a lot of built in linting tools to help you detect less than ideal code. As someone who uses linters in different contexts, for example shellcheck for bash, rubocop for Ruby and flake8 for Python, I like the idea of having someone else package these up for easier use in my own GitHub repositories. I don’t have many repos running tests under Actions so I decided to move a small one over and see if the Super Linter lived up to its name.
For my experiments I picked the puppet-ip_in_range repo, which provides a small puppet function to determine if an IPv4 address is within a given IPv4 CIDR. I mostly chose it because it has YAML, JSON, Ruby and Markdown in the same code base but also because it’s mostly clean under rubocop. I had three goals for moving the repo:
RSpec tests must run under GitHub Actions
Super Linter must run but not fail the tests on outputs
The addition of Rubocop Linter Action as I like the way it displays the output.
The first of these requirements, running the tests under rspec, was the easiest as I already have it running in another repo and I don’t yet need any test matrices. I’m happy testing under a single version of Puppet and the ruby version it would normally be bundled with. You can see the code that configures the
rake spec run in the
#... snip ... build: name: "Run Rspec Tests" env: PUPPET_GEM_VERSION: "~> 6.16.0" # ... snip ... - name: Build and test with Rake run: | gem install bundler bundle install --jobs 4 --retry 3 bundle exec rake spec
The highlights of this YAML are that we pass a gem version through to
the Gemfile so you can easily run the tests against different versions
of Puppet and the multiline run command that installs the gems and
runs the specs. If any tests fail the build will also fail. With
specs running, and more importantly still passing under Actions, I
added the super linter in its own configuration file. You can have
steps in the same YAML config but as I’m unsure which parts
of the tooling I will keep I’ve kept them separate for now.
The default configuration and example YAML provided are more than enough
to get you started with the action. My own
Super Lint Configuration
is nearly all boilerplate apart from adding the
environment variable to ensure failing lints don’t break the build. And
on the very first run I discovered lint warnings where I didn’t expect them.
Initially even my
README.md flagged a warning as I had an older
## header ## buried in the text. After a few small cleanup pull
requests to save me some embarrassment, the code base is over 5 years
old after all, I had all the unknowns fixed so I could compare the
output with the expected linter violations. Most of this repo is ruby
code so rubocop, the most common linter on ruby projects, found a number
of things it’s not happy with. I’m not a big fan of some of rubocops
choices but I’ve never had the time to customise all my local configuration so
I was expecting some output, I wasn’t quite expecting some of the things
it flagged. For example the GitHub Super Linter raises
Style/StringLiterals: Prefer double-quoted strings unless you need single quotes to avoid extra backslashes for escaping while I, and the
default rubocop config,
prefer single quoted strings to indicate no variables are used in
the string. This to me is the important concept to take away from my
experiment, the Super Linter action may provide the tooling in a
convenient way but it’s customised to a different companies workflow and
so you’ll still need to add your own configs to ensure it compares
against your style choices.
With the new big gun of the linter world deployed I also added the Rubocop Linter Action. I was expecting this to take a few minutes as i have an example of it running elsewhere but the way the plugin is configured has completely changed (for the better) and I had to do a little rework. I added the Rubocop Linter Action workflow to the repo alongside its new configuration file approach to ensure rubocop issues couldn’t break the build and on the next push i was getting the much prettier than super lint, but much more demanding of screen space, output with syntax highlighting.