Skip to content

Commit

Permalink
Extract linting into separate CI job
Browse files Browse the repository at this point in the history
Because we can simply set `TargetRubyVersion` to the version whose
syntax we want to support, we can run the Rubocop in a single job,
rather than repeating it across all jobs (and matrix combinations).

A side benefit is that this separates test failures from linting
failures, whereas previously tests would be skipped if the linter
failed.
  • Loading branch information
sambostock committed Aug 18, 2023
1 parent 135caff commit b5bdb4c
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 2 deletions.
16 changes: 14 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,24 @@ jobs:
run: |
sudo systemctl start mysql.service
mysql -uroot -h localhost -proot -e "CREATE DATABASE job_iteration_test;"
- name: Rubocop
run: bundle exec rubocop
- name: Ruby tests
run: bundle exec rake test
env:
REDIS_HOST: localhost
REDIS_PORT: ${{ job.services.redis.ports[6379] }}

lint:
runs-on: ubuntu-latest
name: Lint
steps:
- name: Check out code
uses: actions/checkout@v3
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: "3.2"
bundler-cache: true
- name: Rubocop
run: bundle exec rubocop
- name: Documentation correctly written
run: bundle exec yardoc --no-output --no-save --no-stats --fail-on-warning
79 changes: 79 additions & 0 deletions test/rubocop_config_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# frozen_string_literal: true

require "test_helper"
require "yaml"

module JobIteration
class RubocopConfigTest < ActiveSupport::TestCase
test "TargetRubyVersion in .rubocop.yml matches oldest Ruby in CI matrix" do
assert_equal(
oldest_ruby_in_matrix,
target_ruby_version,
"TargetRubyVersion in .rubocop.yml does not match oldest Ruby in CI matrix",
)
end

test "Linting runs on the newest Ruby in CI matrix" do
assert_equal(
newest_ruby_in_matrix,
ruby_version_for_linting,
"Linting does not run on the newest Ruby in CI matrix",
)
end

test "TargetRubyVersion in .rubocop.yml matches required Ruby version in gemspec" do
assert_equal(
required_ruby_version,
target_ruby_version,
"TargetRubyVersion in .rubocop.yml does not match required Ruby version in gemspec",
)
end

private

def oldest_ruby_in_matrix
ruby_versions_in_matrix.min
end

def newest_ruby_in_matrix
ruby_versions_in_matrix.max
end

def ruby_versions_in_matrix
YAML
.load_file(".github/workflows/ci.yml")
.dig("jobs", "build", "strategy", "matrix", "ruby")
.tap { |ruby_versions| refute_nil(ruby_versions, "Ruby versions not found in CI matrix") }
.map { |ruby_version| Gem::Version.new(ruby_version) }
end

def ruby_version_for_linting
YAML
.load_file(".github/workflows/ci.yml")
.dig("jobs", "lint", "steps")
.tap { |steps| refute_nil(steps, "Steps not found in linting CI config") }
.find { |step| step.fetch("uses", "") =~ %r{^ruby/setup-ruby} }
.tap { |step| refute_nil(step, "Ruby setup step not found in linting CI config") }
.then { |step| step.dig("with", "ruby-version") }
.tap { |ruby_version| refute_nil(ruby_version, "Ruby version not found in linting CI config") }
.then { |ruby_version| Gem::Version.new(ruby_version) }
end

def target_ruby_version
YAML
.load_file(".rubocop.yml")
.dig("AllCops", "TargetRubyVersion")
.tap { |ruby_version| refute_nil(ruby_version, "TargetRubyVersion not found in .rubocop.yml") }
.then { |ruby_version| Gem::Version.new(ruby_version) }
end

def required_ruby_version
Gem
.loaded_specs
.fetch("job-iteration")
.required_ruby_version
.to_s[/(?<=>= )\d+\.\d+/]
.then { |ruby_version| Gem::Version.new(ruby_version) }
end
end
end

0 comments on commit b5bdb4c

Please sign in to comment.