From 64599acb23810dc20bd8df61b52dd189a6f66594 Mon Sep 17 00:00:00 2001 From: Chris Oliver Date: Tue, 8 Sep 2026 20:19:48 -0500 Subject: [PATCH] Skip the yjit release variants for series without a supported YJIT MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The release matrix asked for a yjit and a no_yjit tarball of every version. For 1.8 through 3.1 those were the same build under two names: no YJIT before 3.1, and 3.1's C implementation was experimental. Ruby 3.1 is now yjit: false in the recipes alongside the older series. build.yml's plan job computes the Linux matrix from the series' yjit setting — both variants per target when it has YJIT, otherwise no_yjit only — and the macOS job follows the same flag. package.rb keeps building a hand-requested --yjit on such a series under the requested name, with a warning, so nothing that used to work stops working. Claude-Session: https://claude.ai/code/session_01BFx21Nhpz1gdB1iNi3ZpT9 --- .github/workflows/build.yml | 43 ++++++++++++++++++++----------------- README.md | 10 +++++---- libexec/package.rb | 9 ++++---- recipes/series.yml | 4 ++-- 4 files changed, 36 insertions(+), 30 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index aa17287..8204dec 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -23,13 +23,15 @@ env: BOOTSTRAP_VERSION: "3.4.7" jobs: - # What this version's series allows: old series build for Linux only, and get a smoke - # test their stdlib can pass. See recipes/series.yml. + # What this version's series allows: old series build for Linux only, without a yjit + # variant, and get a smoke test their stdlib can pass. See recipes/series.yml. plan: runs-on: ubuntu-latest outputs: macos: ${{ steps.info.outputs.macos }} legacy: ${{ steps.info.outputs.legacy }} + yjit: ${{ steps.info.outputs.yjit }} + linux-matrix: ${{ steps.matrix.outputs.linux }} steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - uses: ruby/setup-ruby@v1 @@ -37,11 +39,23 @@ jobs: ruby-version: .ruby-version - id: info run: bin/recipe-info "${{ inputs.version }}" >> "$GITHUB_OUTPUT" + - id: matrix + env: + YJIT: ${{ steps.info.outputs.yjit }} + run: | + # Both variants per target when the series has YJIT, otherwise no_yjit only. + if [[ "$YJIT" == "true" ]]; then yjits='[true, false]'; else yjits='[false]'; fi + echo "linux=$(jq -c -n --argjson yjits "$yjits" '{include: [ + {runner: "ubuntu-22.04", target: "x86_64_linux"}, + {runner: "ubuntu-22.04-arm", target: "arm64_linux"} + ] | map(. as $t | $yjits[] | $t + {yjit: .})}')" >> "$GITHUB_OUTPUT" build-macos: needs: plan if: needs.plan.outputs.macos == 'true' runs-on: macos-14 + env: + YJIT: ${{ needs.plan.outputs.yjit }} steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 @@ -59,12 +73,14 @@ jobs: env: JDX_RUBY_BASERUBY: ${{ steps.setup-ruby.outputs.ruby-prefix }}/bin/ruby JDX_RUBY_RUSTUP_HOME: ${{ github.workspace }}/.build/rustup-macos - run: bin/package "${{ inputs.version }}" --target macos --yjit --output rubies + run: | + if [[ "$YJIT" == "true" ]]; then yjit_arg="--yjit"; else yjit_arg="--no-yjit"; fi + bin/package "${{ inputs.version }}" --target macos "$yjit_arg" --output rubies - name: Upload portable Ruby uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: - name: ruby-${{ inputs.version }}-macos-yjit-true + name: ruby-${{ inputs.version }}-macos-yjit-${{ needs.plan.outputs.yjit }} path: rubies/ - name: Test portable Ruby @@ -72,27 +88,14 @@ jobs: mkdir -p portable-ruby tar --strip-components 1 -C portable-ruby -xf rubies/*.tar.gz export PATH="${PWD}/portable-ruby/bin:${PATH}" - ruby --version --yjit + if [[ "$YJIT" == "true" ]]; then ruby --version --yjit; else ruby --version; fi ruby -r debug -r bigdecimal -r json -r yaml -r reline -e "true" build-linux: needs: plan strategy: fail-fast: false - matrix: - include: - - runner: ubuntu-22.04 - target: x86_64_linux - yjit: true - - runner: ubuntu-22.04 - target: x86_64_linux - yjit: false - - runner: ubuntu-22.04-arm - target: arm64_linux - yjit: true - - runner: ubuntu-22.04-arm - target: arm64_linux - yjit: false + matrix: ${{ fromJson(needs.plan.outputs.linux-matrix) }} runs-on: ${{ matrix.runner }} steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 @@ -172,7 +175,7 @@ jobs: mkdir -p portable-ruby tar --strip-components 1 -C portable-ruby -xf rubies/*.tar.gz export PATH="${PWD}/portable-ruby/bin:${PATH}" - if [[ "${{ matrix.yjit }}" == "true" && "$LEGACY" != "true" ]]; then + if [[ "${{ matrix.yjit }}" == "true" ]]; then ruby --version --yjit else ruby --version diff --git a/README.md b/README.md index c820473..0db9c2a 100644 --- a/README.md +++ b/README.md @@ -53,8 +53,9 @@ arm64 macOS configuration at all. Because they are built against glibc 2.17 like everything else here, the tarballs run on any Ubuntu LTS from 20.04 (Focal) on, and on other distributions of that vintage or newer. -`--yjit` on a series without YJIT prints a warning and builds without it under the -requested artifact name, so the release matrix still produces every file it expects. +Series with `yjit: false` (everything up to 3.1, whose C-based YJIT was experimental) get +only the `no_yjit` variants in a release. A hand-run `bin/package --yjit` on one prints a +warning and builds without YJIT under the requested name rather than failing. ## SSL certificates @@ -78,8 +79,9 @@ dispatches that for every recipe that has no release yet; it runs on a schedule, the versions you name instead. On a fresh fork the default means every recipe, so the first run is a big one; use `only` to start smaller. -Series can opt out of the macOS build with `macos: false` in `recipes/series.yml`; the -end-of-life series do, and release Linux tarballs only. +Series can opt out of the macOS build with `macos: false` in `recipes/series.yml`, and out +of the yjit variants with `yjit: false`; the end-of-life series do both, and release Linux +`no_yjit` tarballs only. No secrets are required. Optional ones: diff --git a/libexec/package.rb b/libexec/package.rb index a44cec0..d882fd4 100755 --- a/libexec/package.rb +++ b/libexec/package.rb @@ -108,13 +108,14 @@ def deep_merge(left, right) end end - # Old series have no YJIT to enable. The release workflow still asks for both variants, - # so rather than fail half the matrix, build the same Ruby under the requested name. + # Old series have no YJIT worth shipping. The release workflow doesn't ask for the yjit + # variant of those, but a hand-run request is honoured by building the same Ruby under + # the requested name rather than failing. def validate_yjit! return unless yjit return if @series["yjit"] - warn "warning: Ruby #{version} predates YJIT; building without it under the --yjit artifact name" + warn "warning: Ruby #{version} has no supported YJIT; building without it under the --yjit artifact name" end def validate_host! @@ -349,7 +350,7 @@ def build_openssl end def build_ruby! - ensure_rust! if yjit && @series["yjit"] == "rust" + ensure_rust! if yjit && @series["yjit"] source = extract_source("ruby", @ruby_recipe) apply_source_patches(source) remove_extensions(source) if package_version < Gem::Version.new("1.9") diff --git a/recipes/series.yml b/recipes/series.yml index a8c048f..247f49a 100644 --- a/recipes/series.yml +++ b/recipes/series.yml @@ -27,7 +27,7 @@ defaults: rubygems: ~ # dependency to install RubyGems from, for Rubies without it bundler: [] # bundler versions to gem install mjit_cc: ~ - yjit: rust # rust | c (3.1) | false + yjit: rust # rust | false — false also drops the yjit release variant test: modern # modern | legacy test_native_gem: ~ macos: true # false skips the macOS build in the release workflow @@ -198,7 +198,7 @@ series: extra_out_ext: [gdbm, dbm] bundled_gems: ~ mjit_cc: /usr/bin/cc - yjit: c # YJIT was C in 3.1; no Rust needed + yjit: false # 3.1's C YJIT was experimental; 3.2 is where it became real test: legacy macos: false test_native_gem: { name: msgpack, version: 1.4.2 }