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 }