From 5d04ea32e1f05286184f59dd927ae4b6ca55535a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=AA=E3=81=A4=E3=81=8D?= Date: Wed, 7 Jan 2026 09:52:52 -0800 Subject: [PATCH] Generate test matrix dynamically --- .github/workflows/test.yml | 112 ++++++++++--------------------------- generate-test-matrix.rb | 77 +++++++++++++++++++++++++ 2 files changed, 107 insertions(+), 82 deletions(-) create mode 100644 generate-test-matrix.rb diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 4aa2849dd..097b9648a 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -13,85 +13,33 @@ permissions: contents: read jobs: + test-matrix: + runs-on: ubuntu-latest + + outputs: + matrix: ${{ steps.matrix.outputs.matrix }} + + steps: + - uses: actions/checkout@v6 + + - uses: ./ + with: + ruby-version: ruby + + - id: matrix + run: echo "matrix=$(ruby generate-test-matrix.rb)" | tee -a "$GITHUB_OUTPUT" + + - run: echo "$MATRIX" | yq -P + env: + MATRIX: ${{ steps.matrix.outputs.matrix }} + test: + needs: [test-matrix] + strategy: fail-fast: false matrix: - os: [ ubuntu-22.04, ubuntu-24.04, ubuntu-22.04-arm, ubuntu-24.04-arm, macos-14, macos-15, macos-15-intel, windows-2022, windows-2025, windows-11-arm ] - ruby: [ - '1.9', '2.0', '2.1', '2.2', '2.3', '2.4', '2.5', '2.6', '2.7', '3.0', '3.1', '3.2', '3.3', '3.4', '4.0', ruby-head, - jruby-9.4, jruby, jruby-head, - truffleruby, truffleruby-head, - truffleruby+graalvm, truffleruby+graalvm-head - ] - include: - - { os: windows-2022, ruby: mingw } - - { os: windows-2022, ruby: mswin } - - { os: windows-2022, ruby: ucrt } - - { os: windows-2025, ruby: mingw } - - { os: windows-2025, ruby: mswin } - - { os: windows-2025, ruby: ucrt } - - { os: ubuntu-24.04, ruby: asan } - - { os: ubuntu-24.04, ruby: asan-release } - exclude: - # https://github.com/ruby/setup-ruby/issues/496 - - { os: ubuntu-22.04, ruby: '2.2' } - - { os: ubuntu-24.04, ruby: '1.9' } - - { os: ubuntu-24.04, ruby: '2.2' } - # These old Rubies fail to compile on macOS arm64 - - { os: macos-14, ruby: '1.9' } - - { os: macos-14, ruby: '2.0' } - - { os: macos-14, ruby: '2.1' } - - { os: macos-14, ruby: '2.2' } - - { os: macos-14, ruby: '2.3' } - - { os: macos-14, ruby: '2.4' } - - { os: macos-14, ruby: '2.5' } - - { os: macos-15, ruby: '1.9' } - - { os: macos-15, ruby: '2.0' } - - { os: macos-15, ruby: '2.1' } - - { os: macos-15, ruby: '2.2' } - - { os: macos-15, ruby: '2.3' } - - { os: macos-15, ruby: '2.4' } - - { os: macos-15, ruby: '2.5' } - # These old Rubies fail to compile or segfault on Linux arm64 - - { os: ubuntu-22.04-arm, ruby: '1.9' } - - { os: ubuntu-22.04-arm, ruby: '2.0' } - - { os: ubuntu-22.04-arm, ruby: '2.1' } - - { os: ubuntu-22.04-arm, ruby: '2.2' } - - { os: ubuntu-24.04-arm, ruby: '1.9' } - - { os: ubuntu-24.04-arm, ruby: '2.0' } - - { os: ubuntu-24.04-arm, ruby: '2.1' } - - { os: ubuntu-24.04-arm, ruby: '2.2' } - # RubyInstaller windows-arm64 builds only exist for Ruby 3.4+ - - { os: windows-11-arm, ruby: '2.0' } - - { os: windows-11-arm, ruby: '2.1' } - - { os: windows-11-arm, ruby: '2.2' } - - { os: windows-11-arm, ruby: '2.3' } - - { os: windows-11-arm, ruby: '2.4' } - - { os: windows-11-arm, ruby: '2.5' } - - { os: windows-11-arm, ruby: '2.6' } - - { os: windows-11-arm, ruby: '2.7' } - - { os: windows-11-arm, ruby: '3.0' } - - { os: windows-11-arm, ruby: '3.1' } - - { os: windows-11-arm, ruby: '3.2' } - - { os: windows-11-arm, ruby: '3.3' } - # RubyInstaller has no 64-bit builds of 1.9 on Windows - - { os: windows-2022, ruby: '1.9' } - - { os: windows-2025, ruby: '1.9' } - - { os: windows-11-arm, ruby: '1.9' } - # TruffleRuby does not support Windows - - { os: windows-2022, ruby: truffleruby } - - { os: windows-2025, ruby: truffleruby } - - { os: windows-11-arm, ruby: truffleruby } - - { os: windows-2022, ruby: truffleruby-head } - - { os: windows-2025, ruby: truffleruby-head } - - { os: windows-11-arm, ruby: truffleruby-head } - - { os: windows-2022, ruby: truffleruby+graalvm } - - { os: windows-2025, ruby: truffleruby+graalvm } - - { os: windows-11-arm, ruby: truffleruby+graalvm } - - { os: windows-2022, ruby: truffleruby+graalvm-head } - - { os: windows-2025, ruby: truffleruby+graalvm-head } - - { os: windows-11-arm, ruby: truffleruby+graalvm-head } + include: ${{ fromJSON(needs.test-matrix.outputs.matrix) }} name: ${{ matrix.os }} ${{ matrix.ruby }} runs-on: ${{ matrix.os }} @@ -113,7 +61,7 @@ jobs: run: | ruby -e "puts 'build compiler: ' + RbConfig::CONFIG.fetch('CC_VERSION_MESSAGE', 'unknown').lines.first" - name: gcc and ridk version (mingw) - if: startsWith(matrix.os, 'windows') + if: runner.os == 'Windows' run: | $abi, $plat = $(ruby -e "STDOUT.write RbConfig::CONFIG['ruby_version'] + ' ' + RUBY_PLATFORM").split(' ') if ($plat.Contains('mingw')) { @@ -154,15 +102,15 @@ jobs: - name: bundle install (bash) run: bundle install shell: bash - if: startsWith(matrix.os, 'windows') + if: runner.os == 'Windows' - name: bundle exec rake --version (bash) run: bundle exec rake --version shell: bash - if: startsWith(matrix.os, 'windows') + if: runner.os == 'Windows' - name: bundle exec rake (bash) run: bundle exec rake shell: bash - if: startsWith(matrix.os, 'windows') + if: runner.os == 'Windows' - name: Test `gem github:` in a Gemfile run: bundle install @@ -179,9 +127,9 @@ jobs: if: "matrix.ruby != 'mingw' && matrix.ruby != 'mswin' && matrix.ruby != 'ucrt'" - name: which rake run: which -a rake - if: "!startsWith(matrix.os, 'windows')" + if: runner.os != 'Windows' - name: where ruby, rake, bundle - if: startsWith(matrix.os, 'windows') + if: runner.os == 'Windows' run: | $ErrorActionPreference = 'Continue' $where = 'ruby', 'rake', 'bundle' @@ -195,7 +143,7 @@ jobs: shell: bash run: echo ~ && bundle install - name: Windows JRuby - if: startsWith(matrix.os, 'windows') && startsWith(matrix.ruby, 'jruby') + if: runner.os == 'Windows' && startsWith(matrix.ruby, 'jruby') run: gem install sassc testDotRubyVersion: diff --git a/generate-test-matrix.rb b/generate-test-matrix.rb new file mode 100644 index 000000000..93fbea527 --- /dev/null +++ b/generate-test-matrix.rb @@ -0,0 +1,77 @@ +require 'json' + +# Returns unique semantic versions and symbolic versions +# +# segment_count = 1 returns unique major versions +# segment_count = 2 returns unique minor versions +# segment_count = 3 returns unique patch versions +def unique_versions(versions, segment_count, *symbolic) + versions.filter_map do |version| + next unless Gem::Version.correct?(version) + + ruby_version = Gem::Version.new(version) + next if ruby_version.prerelease? && ruby_version.segments[-2] != 'p' + + ruby_version.segments[0, segment_count].join('.') + end.uniq + versions.intersection(symbolic) +end + +# Runners +runners = %w[ + macos-14 + macos-15 + macos-15-intel + ubuntu-22.04 + ubuntu-24.04 + ubuntu-22.04-arm + ubuntu-24.04-arm + windows-2022 + windows-2025 + windows-11-arm +].freeze + +macos_runners = runners.select { |runner| runner.start_with?('macos-') } +ubuntu_runners = runners.select { |runner| runner.start_with?('ubuntu-') } +windows_runners, non_windows_runners = runners.partition { |runner| runner.start_with?('windows-') } + +macos_arm64_runners, _macos_x64_runners = macos_runners.partition { |runner| !runner.end_with?('-intel')} +ubuntu_arm64_runners, ubuntu_x64_runners = ubuntu_runners.partition { |runner| runner.end_with?('-arm')} +windows_arm64_runners, windows_x64_runners = windows_runners.partition { |runner| runner.end_with?('-arm') } + +# Versions +ruby_builder_versions = JSON.load(File.read('ruby-builder-versions.json')) +windows_versions = JSON.load(File.read('windows-versions.json')) + +# ruby: each minor release + head +ruby_versions = unique_versions(ruby_builder_versions['ruby'], 2, 'head') +windows_ruby_versions = unique_versions(windows_versions.keys, 2, 'head') +matrix = non_windows_runners.product(ruby_versions) + windows_runners.product(windows_ruby_versions) + +# jruby: each major release + head +jruby_versions = unique_versions(ruby_builder_versions['jruby'], 1, 'head').map { |version| "jruby-#{version}" } +matrix += runners.product(jruby_versions) + +# truffleruby: latest release + head +truffleruby_versions = %w[truffleruby truffleruby-head truffleruby+graalvm truffleruby+graalvm-head] +matrix += non_windows_runners.product(truffleruby_versions) + +# ruby-loco: head +ruby_loco_versions = %w[mingw mswin ucrt] +matrix += windows_x64_runners.product(ruby_loco_versions) + +# asan: latest release + head +asan_versions = %w[asan-release asan] +matrix += ubuntu_x64_runners.sort.last(1).product(asan_versions) + +# https://github.com/ruby/setup-ruby/pull/596#discussion_r1606047680 +matrix -= (ubuntu_runners - %w[ubuntu-22.04]).product(%w[1.9]) +# https://github.com/ruby/setup-ruby/issues/496 +matrix -= ubuntu_runners.product(%w[2.2]) +# These old Rubies fail to compile on macOS arm64 +matrix -= macos_arm64_runners.product(%w[1.9 2.0 2.1 2.2 2.3 2.4 2.5]) +# These old Rubies fail to compile or segfault on Linux arm64 +matrix -= ubuntu_arm64_runners.product(%w[1.9 2.0 2.1 2.2]) +# RubyInstaller windows-arm64 builds only exist for Ruby 3.4+ +matrix -= windows_arm64_runners.product(%w[2.0 2.1 2.2 2.3 2.4 2.5 2.6 2.7 3.0 3.1 3.2 3.3]) + +puts(JSON.generate(matrix.sort.collect { |os, ruby| { os: os, ruby: ruby } }))