From 2103c5938bac353eaadcd69c92c3e68f6fe5d66b Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 7 Jul 2026 18:21:28 +0000 Subject: [PATCH 1/8] fix(rspec-gem): publish musl-compatible precompiled gems for Alpine The precompiled *-linux gems are glibc-only. Since 0.13.0 the native extension references __res_init (a glibc-exclusive resolver symbol), so loading the gem on musl-based distros like Alpine fails with: LoadError: Error relocating .../rspec_trunk_flaky_tests.so: __res_init: symbol not found Cross-compiling the extension against musl produces a .so that links against musl's libc and drops the glibc-only symbol references. - Build x86_64-linux-musl and aarch64-linux-musl gems in the release workflow (rake-compiler-dock/oxidize-rb already support these targets). - Add a test-musl-gem job that installs each musl gem inside an official ruby:*-alpine container and requires + exercises the native extension (env_parse) to catch __res_init-style relocation regressions. Gate publishing on it. setup-ruby has no Alpine support, so the artifact is downloaded on the host and run via docker. - Advertise the musl platforms in the load-error message, gem README, and the dev Gemfile.lock PLATFORMS list. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01RumF5roNQnj2XsBS6erPVn --- .github/workflows/release_ruby_gem.yml | 67 ++++++++++++++++++- rspec-trunk-flaky-tests/Gemfile.lock | 2 + rspec-trunk-flaky-tests/README.md | 4 +- .../lib/rspec_trunk_flaky_tests.rb | 6 +- 4 files changed, 76 insertions(+), 3 deletions(-) diff --git a/.github/workflows/release_ruby_gem.yml b/.github/workflows/release_ruby_gem.yml index 41cf199b..d1e21a3b 100644 --- a/.github/workflows/release_ruby_gem.yml +++ b/.github/workflows/release_ruby_gem.yml @@ -49,7 +49,9 @@ jobs: matrix: platform: - x86_64-linux + - x86_64-linux-musl - aarch64-linux + - aarch64-linux-musl - arm64-darwin - x86_64-darwin - ruby @@ -154,9 +156,72 @@ jobs: artifact-pattern: cross-gem-${{ matrix.platform.name }} knapsack-pro-test-suite-token-rspec: ${{ secrets.KNAPSACK_PRO_TEST_SUITE_TOKEN_RSPEC }} + # The glibc-linked *-linux gems fail to load on Alpine/musl (e.g. + # "Error relocating ... __res_init: symbol not found"). The musl-targeted gems + # must therefore be validated inside an Alpine container rather than on the + # glibc-based ubuntu runners used by test-ruby-gem. ruby/setup-ruby does not + # support Alpine, so we download the artifact on the host and exercise the gem + # inside an official ruby:*-alpine image via docker. + test-musl-gem: + name: Test ${{ matrix.platform.name }} gem on Alpine (ruby ${{ matrix.ruby-version }}) + runs-on: ${{ matrix.platform.os }} + needs: cross-gem + strategy: + fail-fast: false + matrix: + # A representative spread of Ruby ABIs with reliable Alpine images. The + # __res_init failure is a libc-linkage issue, so it reproduces + # independently of the Ruby version — no need to cover every ABI here. + ruby-version: ["3.1", "3.4"] + platform: + - name: x86_64-linux-musl + os: ubuntu-latest + - name: aarch64-linux-musl + os: ubuntu-24.04-arm + steps: + - uses: actions/download-artifact@v4 + with: + pattern: cross-gem-${{ matrix.platform.name }} + path: pkg + merge-multiple: true + + - name: Load and exercise musl gem on Alpine + shell: bash + run: | + set -euxo pipefail + GEM_FILE=$(ls pkg/rspec_trunk_flaky_tests-*.gem | head -n 1) + echo "Testing gem: ${GEM_FILE}" + + # Runtime check: require dlopens the native extension (this is where a + # glibc-only build dies on musl), then call into it to confirm it is + # functional and not merely loadable. + cat > musl_load_test.rb <<'RUBY' + require 'rspec_trunk_flaky_tests' + puts 'loaded native extension OK' + info = env_parse({ + 'GITHUB_ACTIONS' => 'true', + 'GITHUB_REF' => 'abc', + 'GITHUB_RUN_ID' => '12345', + 'GITHUB_REPOSITORY' => 'analytics-cli' + }, []) + abort 'env_parse returned nil' if info.nil? + abort "unexpected platform: #{info.platform}" unless info.platform.to_s == 'GITHUB_ACTIONS' + puts "env_parse OK on musl: #{info.platform}" + RUBY + + docker run --rm \ + -e GEM_FILE="${GEM_FILE}" \ + -v "${PWD}:/work" -w /work \ + "ruby:${{ matrix.ruby-version }}-alpine" \ + sh -euxc ' + gem install rspec-core --no-document + gem install "${GEM_FILE}" --local --no-document + ruby musl_load_test.rb + ' + publish_ruby_gem: runs-on: ubuntu-latest - needs: test-ruby-gem + needs: [test-ruby-gem, test-musl-gem] steps: - uses: actions/checkout@v4 diff --git a/rspec-trunk-flaky-tests/Gemfile.lock b/rspec-trunk-flaky-tests/Gemfile.lock index 192bc91a..b6d2e435 100644 --- a/rspec-trunk-flaky-tests/Gemfile.lock +++ b/rspec-trunk-flaky-tests/Gemfile.lock @@ -30,11 +30,13 @@ GEM rspec-support (3.13.2) PLATFORMS + aarch64-linux-musl arm64-darwin arm64-linux ruby x86_64-darwin x86_64-linux + x86_64-linux-musl DEPENDENCIES rake diff --git a/rspec-trunk-flaky-tests/README.md b/rspec-trunk-flaky-tests/README.md index 9b54cbb8..8ef91c21 100644 --- a/rspec-trunk-flaky-tests/README.md +++ b/rspec-trunk-flaky-tests/README.md @@ -63,7 +63,9 @@ bundle exec rake native[x86_64-linux] Supported platforms: - `x86_64-linux` +- `x86_64-linux-musl` (Alpine and other musl-based distros) - `aarch64-linux` +- `aarch64-linux-musl` (Alpine and other musl-based distros) - `arm64-darwin` - `x86_64-darwin` @@ -249,7 +251,7 @@ To release a new version: 1. Trigger the workflow manually via GitHub Actions UI or API 2. Provide the release tag (version number) as input 3. The workflow will: - - Build the gem for all supported platforms (`x86_64-linux`, `aarch64-linux`, `arm64-darwin`, `x86_64-darwin`) + - Build the gem for all supported platforms (`x86_64-linux`, `x86_64-linux-musl`, `aarch64-linux`, `aarch64-linux-musl`, `arm64-darwin`, `x86_64-darwin`) - Test the gem on all platforms with Ruby versions 3.0, 3.1, 3.2, 3.3, and 3.4 - Publish the gem to RubyGems if all tests pass diff --git a/rspec-trunk-flaky-tests/lib/rspec_trunk_flaky_tests.rb b/rspec-trunk-flaky-tests/lib/rspec_trunk_flaky_tests.rb index 2cfb671b..c028304c 100644 --- a/rspec-trunk-flaky-tests/lib/rspec_trunk_flaky_tests.rb +++ b/rspec-trunk-flaky-tests/lib/rspec_trunk_flaky_tests.rb @@ -15,7 +15,11 @@ this dependency. It does not include a precompiled native extension. Precompiled native gems are available for: - x86_64-linux, aarch64-linux, arm64-darwin, x86_64-darwin + x86_64-linux, x86_64-linux-musl, aarch64-linux, aarch64-linux-musl, + arm64-darwin, x86_64-darwin + + The *-linux-musl gems support musl-based distributions such as Alpine. + Upgrade to a recent bundler/rubygems so the musl variant is selected. If you are on a supported platform and seeing this error, make sure bundler is selecting the native variant for your platform: From 6b8f3f8ed34e68f3093b379eb343b288db20510a Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 7 Jul 2026 18:34:46 +0000 Subject: [PATCH 2/8] Slim musl test to one Ruby version, drop musl note from load error Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01RumF5roNQnj2XsBS6erPVn --- .github/workflows/release_ruby_gem.yml | 10 ++++++---- rspec-trunk-flaky-tests/lib/rspec_trunk_flaky_tests.rb | 3 --- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/.github/workflows/release_ruby_gem.yml b/.github/workflows/release_ruby_gem.yml index d1e21a3b..6492ee2c 100644 --- a/.github/workflows/release_ruby_gem.yml +++ b/.github/workflows/release_ruby_gem.yml @@ -169,10 +169,12 @@ jobs: strategy: fail-fast: false matrix: - # A representative spread of Ruby ABIs with reliable Alpine images. The - # __res_init failure is a libc-linkage issue, so it reproduces - # independently of the Ruby version — no need to cover every ABI here. - ruby-version: ["3.1", "3.4"] + # The __res_init failure is a libc-linkage issue: every per-Ruby .so in + # a musl gem is linked the same way, so one Ruby version proves the + # linkage for all. Per-Ruby load-path/ABI coverage is already handled by + # test-ruby-gem. We do exercise both arches, since each is a separately + # built artifact. + ruby-version: ["3.4"] platform: - name: x86_64-linux-musl os: ubuntu-latest diff --git a/rspec-trunk-flaky-tests/lib/rspec_trunk_flaky_tests.rb b/rspec-trunk-flaky-tests/lib/rspec_trunk_flaky_tests.rb index c028304c..c7787499 100644 --- a/rspec-trunk-flaky-tests/lib/rspec_trunk_flaky_tests.rb +++ b/rspec-trunk-flaky-tests/lib/rspec_trunk_flaky_tests.rb @@ -18,9 +18,6 @@ x86_64-linux, x86_64-linux-musl, aarch64-linux, aarch64-linux-musl, arm64-darwin, x86_64-darwin - The *-linux-musl gems support musl-based distributions such as Alpine. - Upgrade to a recent bundler/rubygems so the musl variant is selected. - If you are on a supported platform and seeing this error, make sure bundler is selecting the native variant for your platform: From 8ead614a47b64dfe7ae10674c3987c8a745d0d05 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 7 Jul 2026 18:48:31 +0000 Subject: [PATCH 3/8] Run real smoke specs in musl gem test; tidy comments MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace the synthetic env_parse call with the same RSpec smoke specs that test-ruby-gem runs, executed inside an Alpine container against the precompiled musl gem. This exercises the full runtime on musl — native extension load, quarantine lookup over TLS/DNS, result serialization, and upload — rather than just confirming the extension loads. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01RumF5roNQnj2XsBS6erPVn --- .github/workflows/release_ruby_gem.yml | 59 +++++++++++++------------- 1 file changed, 29 insertions(+), 30 deletions(-) diff --git a/.github/workflows/release_ruby_gem.yml b/.github/workflows/release_ruby_gem.yml index 6492ee2c..9554bb65 100644 --- a/.github/workflows/release_ruby_gem.yml +++ b/.github/workflows/release_ruby_gem.yml @@ -156,12 +156,12 @@ jobs: artifact-pattern: cross-gem-${{ matrix.platform.name }} knapsack-pro-test-suite-token-rspec: ${{ secrets.KNAPSACK_PRO_TEST_SUITE_TOKEN_RSPEC }} - # The glibc-linked *-linux gems fail to load on Alpine/musl (e.g. - # "Error relocating ... __res_init: symbol not found"). The musl-targeted gems - # must therefore be validated inside an Alpine container rather than on the - # glibc-based ubuntu runners used by test-ruby-gem. ruby/setup-ruby does not - # support Alpine, so we download the artifact on the host and exercise the gem - # inside an official ruby:*-alpine image via docker. + # test-ruby-gem covers glibc/darwin via ruby/setup-ruby, which has no Alpine + # support. So we validate the musl gems in an official ruby:*-alpine image: + # the artifact is downloaded on the host and the smoke specs run inside the + # container via docker. One Ruby version per arch is enough — the __res_init + # failure is a libc-linkage issue shared by every per-Ruby .so in a gem, and + # per-Ruby coverage already lives in test-ruby-gem. test-musl-gem: name: Test ${{ matrix.platform.name }} gem on Alpine (ruby ${{ matrix.ruby-version }}) runs-on: ${{ matrix.platform.os }} @@ -169,11 +169,6 @@ jobs: strategy: fail-fast: false matrix: - # The __res_init failure is a libc-linkage issue: every per-Ruby .so in - # a musl gem is linked the same way, so one Ruby version proves the - # linkage for all. Per-Ruby load-path/ABI coverage is already handled by - # test-ruby-gem. We do exercise both arches, since each is a separately - # built artifact. ruby-version: ["3.4"] platform: - name: x86_64-linux-musl @@ -181,44 +176,48 @@ jobs: - name: aarch64-linux-musl os: ubuntu-24.04-arm steps: + - uses: actions/checkout@v4 + - uses: actions/download-artifact@v4 with: pattern: cross-gem-${{ matrix.platform.name }} path: pkg merge-multiple: true - - name: Load and exercise musl gem on Alpine + - name: Run smoke specs against the musl gem on Alpine shell: bash + env: + TRUNK_PUBLIC_API_ADDRESS: https://api.trunk-staging.io + TRUNK_ORG_URL_SLUG: trunk-staging-org + TRUNK_API_TOKEN: ${{ secrets.TRUNK_STAGING_ORG_API_TOKEN }} + TRUNK_TEST_COLLECTION_ID: T5yKSn9h + TRUNK_VARIANT: ${{ matrix.platform.name }} run: | set -euxo pipefail GEM_FILE=$(ls pkg/rspec_trunk_flaky_tests-*.gem | head -n 1) echo "Testing gem: ${GEM_FILE}" - # Runtime check: require dlopens the native extension (this is where a - # glibc-only build dies on musl), then call into it to confirm it is - # functional and not merely loadable. - cat > musl_load_test.rb <<'RUBY' - require 'rspec_trunk_flaky_tests' - puts 'loaded native extension OK' - info = env_parse({ - 'GITHUB_ACTIONS' => 'true', - 'GITHUB_REF' => 'abc', - 'GITHUB_RUN_ID' => '12345', - 'GITHUB_REPOSITORY' => 'analytics-cli' - }, []) - abort 'env_parse returned nil' if info.nil? - abort "unexpected platform: #{info.platform}" unless info.platform.to_s == 'GITHUB_ACTIONS' - puts "env_parse OK on musl: #{info.platform}" - RUBY + # Forward the (non-secret) GitHub CI context so the gem detects CI and + # derives repo metadata just as it does in test-ruby-gem on the host. + env | grep -E '^GITHUB_' > "${RUNNER_TEMP}/ci.env" || true + # Run the same specs test-ruby-gem uses, inside Alpine, against the + # precompiled musl gem. This dlopens the native extension (where a + # glibc-only build dies on musl with __res_init), fetches the + # quarantine list over TLS/DNS, serializes results in the extension, + # and uploads — exercising the full runtime, not just gem loading. docker run --rm \ + --env-file "${RUNNER_TEMP}/ci.env" \ -e GEM_FILE="${GEM_FILE}" \ + -e TRUNK_PUBLIC_API_ADDRESS -e TRUNK_ORG_URL_SLUG -e TRUNK_API_TOKEN \ + -e TRUNK_TEST_COLLECTION_ID -e TRUNK_VARIANT \ -v "${PWD}:/work" -w /work \ "ruby:${{ matrix.ruby-version }}-alpine" \ sh -euxc ' - gem install rspec-core --no-document + gem install rspec --no-document gem install "${GEM_FILE}" --local --no-document - ruby musl_load_test.rb + cd .github/actions/test_ruby_gem_uploads + rspec -Ispec spec/test_spec.rb spec/multiple_exception_spec.rb --format documentation ' publish_ruby_gem: From 24ef31da4b48cd38fb8846913e274a504e8e1d7c Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 7 Jul 2026 18:53:23 +0000 Subject: [PATCH 4/8] Trim test-musl-gem comment Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01RumF5roNQnj2XsBS6erPVn --- .github/workflows/release_ruby_gem.yml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/.github/workflows/release_ruby_gem.yml b/.github/workflows/release_ruby_gem.yml index 9554bb65..a1d2b8d3 100644 --- a/.github/workflows/release_ruby_gem.yml +++ b/.github/workflows/release_ruby_gem.yml @@ -157,11 +157,7 @@ jobs: knapsack-pro-test-suite-token-rspec: ${{ secrets.KNAPSACK_PRO_TEST_SUITE_TOKEN_RSPEC }} # test-ruby-gem covers glibc/darwin via ruby/setup-ruby, which has no Alpine - # support. So we validate the musl gems in an official ruby:*-alpine image: - # the artifact is downloaded on the host and the smoke specs run inside the - # container via docker. One Ruby version per arch is enough — the __res_init - # failure is a libc-linkage issue shared by every per-Ruby .so in a gem, and - # per-Ruby coverage already lives in test-ruby-gem. + # support. So we validate the musl gems in an official ruby:*-alpine image test-musl-gem: name: Test ${{ matrix.platform.name }} gem on Alpine (ruby ${{ matrix.ruby-version }}) runs-on: ${{ matrix.platform.os }} From 2f16f08bd550a35eea735173748675d84bfae9c9 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 7 Jul 2026 19:30:42 +0000 Subject: [PATCH 5/8] Ship -linux-gnu/-linux-musl gems; require Ruby >= 3.1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace the bare x86_64-linux/aarch64-linux builds with explicit -linux-gnu and -linux-musl variants, and drop Ruby 3.0 from the build and test matrices (required_ruby_version >= 3.1). Shipping bare -linux alongside -linux-musl is a combination the rake-compiler-dock maintainers warn against — it triggers bundler resolution failures on some rubygems/bundler versions. The explicit gnu/musl split resolves unambiguously, but requires rubygems 3.3.22+ / bundler 2.3.21+, which first ships with Ruby 3.1. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01RumF5roNQnj2XsBS6erPVn --- .github/workflows/release_ruby_gem.yml | 12 ++++++------ rspec-trunk-flaky-tests/README.md | 12 ++++++------ rspec-trunk-flaky-tests/Rakefile | 6 +++--- .../lib/rspec_trunk_flaky_tests.rb | 4 ++-- .../rspec_trunk_flaky_tests.gemspec | 2 +- 5 files changed, 18 insertions(+), 18 deletions(-) diff --git a/.github/workflows/release_ruby_gem.yml b/.github/workflows/release_ruby_gem.yml index a1d2b8d3..1d0f9f14 100644 --- a/.github/workflows/release_ruby_gem.yml +++ b/.github/workflows/release_ruby_gem.yml @@ -48,9 +48,9 @@ jobs: strategy: matrix: platform: - - x86_64-linux + - x86_64-linux-gnu - x86_64-linux-musl - - aarch64-linux + - aarch64-linux-gnu - aarch64-linux-musl - arm64-darwin - x86_64-darwin @@ -98,7 +98,7 @@ jobs: with: platform: ${{ matrix.platform }} working-directory: rspec-trunk-flaky-tests - ruby-versions: 3.0,3.1,3.2,3.3,3.4,4.0 + ruby-versions: 3.1,3.2,3.3,3.4,4.0 - name: Validate ruby platform gem if: matrix.platform == 'ruby' @@ -117,11 +117,11 @@ jobs: needs: [ci-data, cross-gem] strategy: matrix: - ruby-version: ["3.0", "3.1", "3.2", "3.3", "3.4", "4.0"] + ruby-version: ["3.1", "3.2", "3.3", "3.4", "4.0"] platform: - - name: x86_64-linux + - name: x86_64-linux-gnu os: ubuntu-latest - - name: aarch64-linux + - name: aarch64-linux-gnu os: ubuntu-24.04-arm - name: arm64-darwin os: macos-latest diff --git a/rspec-trunk-flaky-tests/README.md b/rspec-trunk-flaky-tests/README.md index 8ef91c21..9729f67f 100644 --- a/rspec-trunk-flaky-tests/README.md +++ b/rspec-trunk-flaky-tests/README.md @@ -15,7 +15,7 @@ The gem includes a native Rust extension (`rspec_trunk_flaky_tests`) that provid ## Prerequisites -- Ruby 3.0 or later +- Ruby 3.1 or later - Bundler - Rust and Cargo (for building the native extension) - `rb-sys` gem (installed automatically via dependencies) @@ -57,14 +57,14 @@ The gem will be built and available in `pkg/`. Build the native extension for a specific platform: ```bash -bundle exec rake native[x86_64-linux] +bundle exec rake native[x86_64-linux-gnu] ``` Supported platforms: -- `x86_64-linux` +- `x86_64-linux-gnu` - `x86_64-linux-musl` (Alpine and other musl-based distros) -- `aarch64-linux` +- `aarch64-linux-gnu` - `aarch64-linux-musl` (Alpine and other musl-based distros) - `arm64-darwin` - `x86_64-darwin` @@ -251,8 +251,8 @@ To release a new version: 1. Trigger the workflow manually via GitHub Actions UI or API 2. Provide the release tag (version number) as input 3. The workflow will: - - Build the gem for all supported platforms (`x86_64-linux`, `x86_64-linux-musl`, `aarch64-linux`, `aarch64-linux-musl`, `arm64-darwin`, `x86_64-darwin`) - - Test the gem on all platforms with Ruby versions 3.0, 3.1, 3.2, 3.3, and 3.4 + - Build the gem for all supported platforms (`x86_64-linux-gnu`, `x86_64-linux-musl`, `aarch64-linux-gnu`, `aarch64-linux-musl`, `arm64-darwin`, `x86_64-darwin`) + - Test the gem on all platforms with Ruby versions 3.1, 3.2, 3.3, 3.4, and 4.0 - Publish the gem to RubyGems if all tests pass The workflow automatically handles cross-compilation, testing, and publishing for all supported platforms. diff --git a/rspec-trunk-flaky-tests/Rakefile b/rspec-trunk-flaky-tests/Rakefile index 6102f638..fe8e1926 100644 --- a/rspec-trunk-flaky-tests/Rakefile +++ b/rspec-trunk-flaky-tests/Rakefile @@ -16,10 +16,10 @@ end desc 'Build native extension for a provided platform' task :native, [:platform] do |_t, platform:| Dir.chdir '..' do - if platform == 'x86_64-linux' - sh 'bundle', 'exec', 'rb-sys-dock', '--platform', platform, '--build', '--directory', 'rspec-trunk-flaky-tests', '--ruby-versions', '3.0,3.1,3.2,3.3,3.4,4.0', '--', 'sudo yum install -y perl-IPC-Cmd' + if %w[x86_64-linux-gnu x86_64-linux].include?(platform) + sh 'bundle', 'exec', 'rb-sys-dock', '--platform', platform, '--build', '--directory', 'rspec-trunk-flaky-tests', '--ruby-versions', '3.1,3.2,3.3,3.4,4.0', '--', 'sudo yum install -y perl-IPC-Cmd' else - sh 'bundle', 'exec', 'rb-sys-dock', '--platform', platform, '--build', '--directory', 'rspec-trunk-flaky-tests', '--ruby-versions', '3.0,3.1,3.2,3.3,3.4,4.0' + sh 'bundle', 'exec', 'rb-sys-dock', '--platform', platform, '--build', '--directory', 'rspec-trunk-flaky-tests', '--ruby-versions', '3.1,3.2,3.3,3.4,4.0' end end end diff --git a/rspec-trunk-flaky-tests/lib/rspec_trunk_flaky_tests.rb b/rspec-trunk-flaky-tests/lib/rspec_trunk_flaky_tests.rb index c7787499..a8e053ba 100644 --- a/rspec-trunk-flaky-tests/lib/rspec_trunk_flaky_tests.rb +++ b/rspec-trunk-flaky-tests/lib/rspec_trunk_flaky_tests.rb @@ -15,8 +15,8 @@ this dependency. It does not include a precompiled native extension. Precompiled native gems are available for: - x86_64-linux, x86_64-linux-musl, aarch64-linux, aarch64-linux-musl, - arm64-darwin, x86_64-darwin + x86_64-linux-gnu, x86_64-linux-musl, aarch64-linux-gnu, + aarch64-linux-musl, arm64-darwin, x86_64-darwin If you are on a supported platform and seeing this error, make sure bundler is selecting the native variant for your platform: diff --git a/rspec-trunk-flaky-tests/rspec_trunk_flaky_tests.gemspec b/rspec-trunk-flaky-tests/rspec_trunk_flaky_tests.gemspec index 7a7cce90..c4cc2ed9 100644 --- a/rspec-trunk-flaky-tests/rspec_trunk_flaky_tests.gemspec +++ b/rspec-trunk-flaky-tests/rspec_trunk_flaky_tests.gemspec @@ -2,7 +2,7 @@ Gem::Specification.new do |s| # trunk-ignore(rubocop/Gemspec/RequiredRubyVersion) - s.required_ruby_version = '>= 3.0' + s.required_ruby_version = '>= 3.1' s.name = 'rspec_trunk_flaky_tests' s.version = '0.0.0' # trunk-ignore(rubocop/Layout/LineLength) From d62af6ff2786634bc05cfda181a51a3a67c0299f Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 7 Jul 2026 20:02:45 +0000 Subject: [PATCH 6/8] Address review: drop unnecessary Gemfile.lock platforms, fix musl test comment MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Revert Gemfile.lock PLATFORMS to the original set; the cross-gem build containers are glibc x86_64 hosts that cross-compile, so bundler only needs x86_64-linux (the alias for -gnu) there — the added musl/gnu entries weren't necessary. - Correct the inaccurate comment on the musl smoke-test step (it described the old gnu-on-musl load failure, not what this test does). Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01RumF5roNQnj2XsBS6erPVn --- .github/workflows/release_ruby_gem.yml | 8 +++----- rspec-trunk-flaky-tests/Gemfile.lock | 2 -- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/.github/workflows/release_ruby_gem.yml b/.github/workflows/release_ruby_gem.yml index 1d0f9f14..ba71bd64 100644 --- a/.github/workflows/release_ruby_gem.yml +++ b/.github/workflows/release_ruby_gem.yml @@ -197,11 +197,9 @@ jobs: # derives repo metadata just as it does in test-ruby-gem on the host. env | grep -E '^GITHUB_' > "${RUNNER_TEMP}/ci.env" || true - # Run the same specs test-ruby-gem uses, inside Alpine, against the - # precompiled musl gem. This dlopens the native extension (where a - # glibc-only build dies on musl with __res_init), fetches the - # quarantine list over TLS/DNS, serializes results in the extension, - # and uploads — exercising the full runtime, not just gem loading. + # Run the same specs test-ruby-gem uses, but inside Alpine against the + # precompiled musl gem, so the musl build is exercised end to end + # (quarantine lookup, result serialization, upload) on a musl host. docker run --rm \ --env-file "${RUNNER_TEMP}/ci.env" \ -e GEM_FILE="${GEM_FILE}" \ diff --git a/rspec-trunk-flaky-tests/Gemfile.lock b/rspec-trunk-flaky-tests/Gemfile.lock index b6d2e435..192bc91a 100644 --- a/rspec-trunk-flaky-tests/Gemfile.lock +++ b/rspec-trunk-flaky-tests/Gemfile.lock @@ -30,13 +30,11 @@ GEM rspec-support (3.13.2) PLATFORMS - aarch64-linux-musl arm64-darwin arm64-linux ruby x86_64-darwin x86_64-linux - x86_64-linux-musl DEPENDENCIES rake From 8d654f79184e9475e712029cd5bdda5d2629834e Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 7 Jul 2026 20:18:04 +0000 Subject: [PATCH 7/8] Fold musl Alpine smoke test into test_ruby_gem_uploads action Add an `alpine` input to the shared test_ruby_gem_uploads action. When set, it skips the host (ruby/setup-ruby + bundler) steps and instead runs the smoke specs inside a ruby:*-alpine container via docker against the precompiled musl gem. test-musl-gem now just calls the action with alpine: true, gated on the musl matrix entries. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01RumF5roNQnj2XsBS6erPVn --- .../actions/test_ruby_gem_uploads/action.yaml | 44 ++++++++++++++- .github/workflows/release_ruby_gem.yml | 53 +++++-------------- 2 files changed, 57 insertions(+), 40 deletions(-) diff --git a/.github/actions/test_ruby_gem_uploads/action.yaml b/.github/actions/test_ruby_gem_uploads/action.yaml index 900c6b02..0e444adb 100644 --- a/.github/actions/test_ruby_gem_uploads/action.yaml +++ b/.github/actions/test_ruby_gem_uploads/action.yaml @@ -33,6 +33,10 @@ inputs: knapsack-pro-test-suite-token-rspec: description: Optional Knapsack Pro test suite token for RSpec required: true + alpine: + description: Run the smoke specs inside a musl (Alpine) container via docker instead of on the host + required: false + default: "false" runs: using: composite @@ -40,6 +44,7 @@ runs: - uses: actions/checkout@v4 - uses: ruby/setup-ruby@v1 + if: inputs.alpine != 'true' with: ruby-version: ${{ inputs.ruby-version }} bundler-cache: true @@ -51,8 +56,41 @@ runs: path: ${{ github.action_path }} merge-multiple: true + - name: Run smoke specs in a musl (Alpine) container + if: inputs.alpine == 'true' + shell: bash + working-directory: ${{ github.action_path }} + env: + TRUNK_PUBLIC_API_ADDRESS: ${{ inputs.trunk-public-api-address }} + TRUNK_ORG_URL_SLUG: ${{ inputs.trunk-org-slug }} + TRUNK_API_TOKEN: ${{ inputs.trunk-token }} + TRUNK_TEST_COLLECTION_ID: ${{ inputs.test-collection-id }} + TRUNK_VARIANT: ${{ inputs.variant }} + run: | + set -euxo pipefail + GEM_FILE=$(ls rspec_trunk_flaky_tests-*.gem | head -n 1) + REL="${GITHUB_ACTION_PATH#"${GITHUB_WORKSPACE}"/}" + + # Forward the (non-secret) GitHub CI context so the gem detects CI and + # derives repo metadata just as it does on the host. + env | grep -E '^GITHUB_' > "${RUNNER_TEMP}/ci.env" || true + + docker run --rm \ + --env-file "${RUNNER_TEMP}/ci.env" \ + -e GEM_FILE="${GEM_FILE}" \ + -e TRUNK_PUBLIC_API_ADDRESS -e TRUNK_ORG_URL_SLUG -e TRUNK_API_TOKEN \ + -e TRUNK_TEST_COLLECTION_ID -e TRUNK_VARIANT \ + -v "${GITHUB_WORKSPACE}:/work" -w "/work/${REL}" \ + "ruby:${{ inputs.ruby-version }}-alpine" \ + sh -euxc ' + gem install rspec --no-document + gem install "./${GEM_FILE}" --local --no-document + rspec -Ispec spec/test_spec.rb spec/multiple_exception_spec.rb --format documentation + ' + - name: Setup gem id: setup-gem + if: inputs.alpine != 'true' shell: bash working-directory: ${{ github.action_path }} run: | @@ -81,6 +119,7 @@ runs: - name: Run regular tests id: run-regular-tests + if: inputs.alpine != 'true' shell: bash working-directory: ${{ github.action_path }} run: | @@ -94,6 +133,7 @@ runs: - name: Run variant quarantine test without variant (should fail - not quarantined) id: run-variant-test-no-variant + if: inputs.alpine != 'true' shell: bash working-directory: ${{ github.action_path }} run: | @@ -115,6 +155,7 @@ runs: - name: Run variant quarantine test with variant (should pass - quarantined) id: run-variant-test-with-variant + if: inputs.alpine != 'true' shell: bash working-directory: ${{ github.action_path }} run: | @@ -136,6 +177,7 @@ runs: - name: Run quarantine lookup failure abort test (should fail fast, skip slow_test) id: run-quarantine-abort-test + if: inputs.alpine != 'true' shell: bash working-directory: ${{ github.action_path }} run: | @@ -161,7 +203,7 @@ runs: - name: Run knapsack_pro queue and verify a single local bundle shell: bash - if: inputs.knapsack-pro-test-suite-token-rspec != '' + if: inputs.alpine != 'true' && inputs.knapsack-pro-test-suite-token-rspec != '' working-directory: ${{ github.action_path }} env: KNAPSACK_PRO_TEST_DIR: spec diff --git a/.github/workflows/release_ruby_gem.yml b/.github/workflows/release_ruby_gem.yml index ba71bd64..7b113794 100644 --- a/.github/workflows/release_ruby_gem.yml +++ b/.github/workflows/release_ruby_gem.yml @@ -157,7 +157,8 @@ jobs: knapsack-pro-test-suite-token-rspec: ${{ secrets.KNAPSACK_PRO_TEST_SUITE_TOKEN_RSPEC }} # test-ruby-gem covers glibc/darwin via ruby/setup-ruby, which has no Alpine - # support. So we validate the musl gems in an official ruby:*-alpine image + # support. The same action runs the musl gems inside a ruby:*-alpine + # container (alpine: true) so they are validated on a musl host. test-musl-gem: name: Test ${{ matrix.platform.name }} gem on Alpine (ruby ${{ matrix.ruby-version }}) runs-on: ${{ matrix.platform.os }} @@ -174,45 +175,19 @@ jobs: steps: - uses: actions/checkout@v4 - - uses: actions/download-artifact@v4 + - name: Test musl gem uploads → analytics-cli-ruby-gem (staging) + uses: ./.github/actions/test_ruby_gem_uploads with: - pattern: cross-gem-${{ matrix.platform.name }} - path: pkg - merge-multiple: true - - - name: Run smoke specs against the musl gem on Alpine - shell: bash - env: - TRUNK_PUBLIC_API_ADDRESS: https://api.trunk-staging.io - TRUNK_ORG_URL_SLUG: trunk-staging-org - TRUNK_API_TOKEN: ${{ secrets.TRUNK_STAGING_ORG_API_TOKEN }} - TRUNK_TEST_COLLECTION_ID: T5yKSn9h - TRUNK_VARIANT: ${{ matrix.platform.name }} - run: | - set -euxo pipefail - GEM_FILE=$(ls pkg/rspec_trunk_flaky_tests-*.gem | head -n 1) - echo "Testing gem: ${GEM_FILE}" - - # Forward the (non-secret) GitHub CI context so the gem detects CI and - # derives repo metadata just as it does in test-ruby-gem on the host. - env | grep -E '^GITHUB_' > "${RUNNER_TEMP}/ci.env" || true - - # Run the same specs test-ruby-gem uses, but inside Alpine against the - # precompiled musl gem, so the musl build is exercised end to end - # (quarantine lookup, result serialization, upload) on a musl host. - docker run --rm \ - --env-file "${RUNNER_TEMP}/ci.env" \ - -e GEM_FILE="${GEM_FILE}" \ - -e TRUNK_PUBLIC_API_ADDRESS -e TRUNK_ORG_URL_SLUG -e TRUNK_API_TOKEN \ - -e TRUNK_TEST_COLLECTION_ID -e TRUNK_VARIANT \ - -v "${PWD}:/work" -w /work \ - "ruby:${{ matrix.ruby-version }}-alpine" \ - sh -euxc ' - gem install rspec --no-document - gem install "${GEM_FILE}" --local --no-document - cd .github/actions/test_ruby_gem_uploads - rspec -Ispec spec/test_spec.rb spec/multiple_exception_spec.rb --format documentation - ' + alpine: "true" + ruby-version: ${{ matrix.ruby-version }} + trunk-token: ${{ secrets.TRUNK_STAGING_ORG_API_TOKEN }} + trunk-public-api-address: https://api.trunk-staging.io + trunk-org-slug: trunk-staging-org + test-collection-id: T5yKSn9h + platform: ${{ matrix.platform.name }} + variant: ${{ matrix.platform.name }} + artifact-pattern: cross-gem-${{ matrix.platform.name }} + knapsack-pro-test-suite-token-rspec: ${{ secrets.KNAPSACK_PRO_TEST_SUITE_TOKEN_RSPEC }} publish_ruby_gem: runs-on: ubuntu-latest From 90fd0886e4c5b925a49cd47c4a17173c5912ea29 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 7 Jul 2026 20:31:55 +0000 Subject: [PATCH 8/8] Trim code comments on musl test to a minimum Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01RumF5roNQnj2XsBS6erPVn --- .github/actions/test_ruby_gem_uploads/action.yaml | 3 +-- .github/workflows/release_ruby_gem.yml | 4 +--- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/.github/actions/test_ruby_gem_uploads/action.yaml b/.github/actions/test_ruby_gem_uploads/action.yaml index 0e444adb..cac664b5 100644 --- a/.github/actions/test_ruby_gem_uploads/action.yaml +++ b/.github/actions/test_ruby_gem_uploads/action.yaml @@ -71,8 +71,7 @@ runs: GEM_FILE=$(ls rspec_trunk_flaky_tests-*.gem | head -n 1) REL="${GITHUB_ACTION_PATH#"${GITHUB_WORKSPACE}"/}" - # Forward the (non-secret) GitHub CI context so the gem detects CI and - # derives repo metadata just as it does on the host. + # Forward the (non-secret) GitHub CI context into the container. env | grep -E '^GITHUB_' > "${RUNNER_TEMP}/ci.env" || true docker run --rm \ diff --git a/.github/workflows/release_ruby_gem.yml b/.github/workflows/release_ruby_gem.yml index 7b113794..cf9714db 100644 --- a/.github/workflows/release_ruby_gem.yml +++ b/.github/workflows/release_ruby_gem.yml @@ -156,9 +156,7 @@ jobs: artifact-pattern: cross-gem-${{ matrix.platform.name }} knapsack-pro-test-suite-token-rspec: ${{ secrets.KNAPSACK_PRO_TEST_SUITE_TOKEN_RSPEC }} - # test-ruby-gem covers glibc/darwin via ruby/setup-ruby, which has no Alpine - # support. The same action runs the musl gems inside a ruby:*-alpine - # container (alpine: true) so they are validated on a musl host. + # Validate the musl gems inside Alpine (ruby/setup-ruby has no Alpine support). test-musl-gem: name: Test ${{ matrix.platform.name }} gem on Alpine (ruby ${{ matrix.ruby-version }}) runs-on: ${{ matrix.platform.os }}