diff --git a/.github/workflows/ruby.yml b/.github/workflows/ruby.yml index aed0cb0d..c4d411ae 100644 --- a/.github/workflows/ruby.yml +++ b/.github/workflows/ruby.yml @@ -4,6 +4,15 @@ on: [push, pull_request] jobs: build: + name: Ruby ${{matrix.ruby}} / ${{matrix.gemfile}} + + strategy: + matrix: + gemfile: [Gemfile, gemfiles/minimum_rubocop.gemfile] + ruby: ["2.7", "3.0", "3.1"] + + env: + BUNDLE_GEMFILE: ${{ matrix.gemfile }} runs-on: ubuntu-latest @@ -12,6 +21,10 @@ jobs: - name: Set up Ruby uses: ruby/setup-ruby@v1 with: + ruby-version: ${{ matrix.ruby }} bundler-cache: true + - name: Rubocop Version + if: ${{ matrix.gemfile == 'gemfiles/minimum_rubocop.gemfile' }} + run: bundle info rubocop | head -1 - name: RuboCop and Tests run: bundle exec rake diff --git a/.gitignore b/.gitignore index 17192ef7..ff924889 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,5 @@ _site node_modules css/ pkg/ + +gemfiles/*.gemfile.lock diff --git a/Gemfile.lock b/Gemfile.lock index 2fc0fd52..537c195b 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -2,7 +2,7 @@ PATH remote: . specs: rubocop-shopify (2.5.0) - rubocop (~> 1.28) + rubocop (~> 1.29) GEM remote: https://rubygems.org/ diff --git a/gemfiles/minimum_rubocop.gemfile b/gemfiles/minimum_rubocop.gemfile new file mode 100644 index 00000000..fef7f2ba --- /dev/null +++ b/gemfiles/minimum_rubocop.gemfile @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +eval_gemfile "../Gemfile" + +# This naively extracts the minimum rubocop version from our gemspec, +# allowing us to ensure that it remains compatible. +minimum_rubocop_version = File.read("rubocop-shopify.gemspec")[/(?<=add_dependency\("rubocop", "~> ).*(?="\)$)/] +raise "Failed to extract minimum rubocop version from gemspec" if minimum_rubocop_version.nil? + +gem "rubocop", minimum_rubocop_version diff --git a/rubocop-shopify.gemspec b/rubocop-shopify.gemspec index 6a58373f..f0edcdcb 100644 --- a/rubocop-shopify.gemspec +++ b/rubocop-shopify.gemspec @@ -21,5 +21,7 @@ Gem::Specification.new do |s| "allowed_push_host" => "https://rubygems.org", } - s.add_dependency("rubocop", "~> 1.28") + s.required_ruby_version = ">= 2.7.0" + + s.add_dependency("rubocop", "~> 1.29") end diff --git a/test/ruby_versions_test.rb b/test/ruby_versions_test.rb new file mode 100644 index 00000000..c2a4873e --- /dev/null +++ b/test/ruby_versions_test.rb @@ -0,0 +1,50 @@ +# frozen_string_literal: true + +require "test_helper" +require "pry" +require "yaml" + +class RubyVersionsTest < Minitest::Test + def test_ci_matrix_includes_minimum_ruby_version + minimum_ruby_version = normalize(extract_minimum_ruby_version_from_gemspec) + ruby_versions = extract_ruby_versions_from_ci_matrix.map { |version| normalize(version) } + + assert_includes( + ruby_versions, + minimum_ruby_version, + "CI must be configured to test as far back as gem's required_ruby_version", + ) + end + + private + + def extract_minimum_ruby_version_from_gemspec + # This naively extracts the minimum Ruby version compatible with out gemspec + # allowing us to ensure that it is included in the CI matrix. + minimum_ruby_version = File.read("rubocop-shopify.gemspec")[/(?<=required_ruby_version = ">= ).*(?="$)/] + + return minimum_ruby_version unless minimum_ruby_version.nil? + + flunk("Failed to extract required_ruby_version from gemspec") + end + + def extract_ruby_versions_from_ci_matrix + YAML + .load_file(".github/workflows/ruby.yml") + .fetch("jobs") + .fetch("build") + .fetch("strategy") + .fetch("matrix") + .fetch("ruby") + end + + # Remove the trailing .0 for versions of the form X.Y.0 + # Otherwise, return the version unchanged + def normalize(version) + if version.match?(/^\d+\.\d+\.0$/) + version.chomp(".0") + else + version + end + end +end