Skip to content

Adopt scientist-labs/rust-gem-release@v0 for releases#19

Merged
xrl merged 9 commits into
mainfrom
migrate-to-rust-gem-release
Jun 19, 2026
Merged

Adopt scientist-labs/rust-gem-release@v0 for releases#19
xrl merged 9 commits into
mainfrom
migrate-to-rust-gem-release

Conversation

@xrl

@xrl xrl commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

Summary

Migrates clusterkit's release pipeline to the shared scientist-labs/rust-gem-release@v0 reusable workflow (pinned at the moving v0 major, currently rust-gem-release 0.2.0), and adds the two consumer prerequisites a precompiled fat gem needs to actually load at install time. Mirrors the red-candle 1.8.0 migration, which is the proven template for this rollout.

The shared workflow can publish, per gem: a source gem + arm64-darwin + x86_64-linux + aarch64-linux precompiled gems. This PR enables source + arm64-darwin and holds the two linux legs off for now (see Known gap below).

Files changed

  • .github/workflows/release.yml (modified) — replaces the 65-line hand-rolled single-platform Release workflow (manual dispatch + sed version-bump + single-ubuntu source-gem push) with the canonical thin caller. Triggers on version tags ([0-9]+.[0-9]+.[0-9]+, plus v-prefixed and .pre/.* prerelease variants — this gem has shipped both bare 0.2.6.pre and v0.2.6.pre) and workflow_dispatch. permissions: contents: write. Passes gem-name: clusterkit and the version loader; ext-name/gemspec/platform-gem-env all use defaults (everything is named clusterkit).
  • lib/clusterkit/clusterkit.rb (modified) — PREREQ 1: ABI require-shim. Replaces the flat require_relative "clusterkit.bundle" loader with the red-candle pattern that resolves through $LOAD_PATH, trying the ABI-versioned subdir lib/clusterkit/<major.minor>/clusterkit (where fat gems install one binary per Ruby ABI) and falling back to the flat clusterkit/clusterkit dev path. require, not require_relative, because RubyGems installs native extensions outside the gem's lib/.
  • clusterkit.gemspec (modified) — PREREQ 2: env-gated platform branch. When RUST_GEM_PLATFORM is set: spec.platform = <plat>, spec.extensions = [], and re-adds the native artifacts via explicit Dir["lib/clusterkit/*/clusterkit.{bundle,so}"] globs. The globs are required because .gitignore excludes **.bundle/**.so and the existing spec.files is built from git ls-files, which would otherwise ship zero bundles in a platform gem. Unset env → unchanged source gem.
  • .github/workflows/build.yml (added) — PR-CI caller for the shared build.yml@v0 (test-command: bundle exec rake spec).
  • .github/workflows/ci.yml (deleted) — superseded by build.yml.

Safety

  • publish defaults to DRY-RUN on workflow_dispatch (default: false → builds but does not push to RubyGems).
  • On a tag push publish is true, but the RubyGems push remains token-gated: an empty RUBYGEMS_API_KEY makes the push step a safe no-op.

Known gap — linux precompiled legs held off

build-x86_64-linux and build-aarch64-linux are set to false in the caller. The extension links BLAS/LAPACK and ext/clusterkit's default openblas-static feature compiles OpenBLAS from C+Fortran source, which the oxidize-rb cross-gem MUSL container can't provision (no gfortran/cmake; rust-gem-release@v0 exposes no input to apt-install packages or to select an openblas-system feature on the linux legs). Darwin is clean — extconf passes --no-default-features + macos-accelerate, linking the system Accelerate framework natively. Re-enable the two linux legs once rust-gem-release can provision/select system OpenBLAS.

Validation

  • ruby -ryaml loads both workflow YAMLs OK.
  • actionlint clean (exit 0) on release.yml and build.yml.
  • Gemspec loads correctly under both branches: source → platform=ruby, extensions=["ext/clusterkit/extconf.rb"]; RUST_GEM_PLATFORM=arm64-darwinplatform=arm64-darwin, extensions=[].

DRAFT — do not merge until a publish=false dry-run is green; trigger with: gh workflow run release.yml -f publish=false --ref migrate-to-rust-gem-release

🤖 Generated with Claude Code

xrl and others added 4 commits June 18, 2026 14:31
Replace the hand-rolled single-platform Release workflow with the shared
reusable rust-gem-release caller (pinned @v0), and add the two consumer
prerequisites a precompiled fat gem needs to load at runtime.

- .github/workflows/release.yml: canonical thin caller. Tag-push + manual
  dispatch (publish defaults to false = dry-run). gem-name=clusterkit;
  version-command loads ClusterKit::VERSION. Linux precompiled legs disabled
  for now (build-x86_64-linux/aarch64-linux=false) because the BLAS/LAPACK
  ext links openblas-static (from-source Fortran build) which the cross-gem
  MUSL container cannot provision; ship source + arm64-darwin first.
- lib/clusterkit/clusterkit.rb: ABI require-shim. Resolves the native ext via
  $LOAD_PATH, trying the ABI-versioned subdir (lib/clusterkit/<major.minor>/)
  that fat gems install into, falling back to the flat dev-build path.
- clusterkit.gemspec: env-gated platform branch. When RUST_GEM_PLATFORM is
  set, sets spec.platform, clears extensions, and re-adds the native bundles
  via explicit Dir[] globs (git-ls-files drops them via .gitignore **.bundle).
- .github/workflows/build.yml: PR-CI caller for the shared build workflow,
  replacing the hand-rolled ci.yml (deleted).

Mirrors the red-candle migration (the proven template for this rollout).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
clusterkit links BLAS/LAPACK; the default openblas-static feature compiles
OpenBLAS from C+Fortran source, which the stock rb-sys-dock cross image can't
provision. Switch the linux legs to the system OpenBLAS path:

- release.yml: set linux-cross-image-repo: ghcr.io/scientist-labs/rust-gem-cross
  (+ linux-cross-image-tag 0.9.128) so rb-sys-dock builds against the
  deps-enriched image (libopenblas-dev liblapack-dev gfortran), and flip
  build-x86_64-linux/build-aarch64-linux to true. Add the label-gated
  pull_request dry-run trigger + if-gate and the robust publish expression,
  matching the green gems.
- ext/clusterkit/extconf.rb: select the openblas-system Cargo feature on linux
  (links the apt-provided system BLAS instead of compiling it). This must live
  in committed code: rb-sys-dock does not forward host env to extconf and a
  .cargo/config.toml [env] reaches cargo-spawned procs, not mkmf.
- Cargo.lock: bump rb-sys 0.9.124 -> 0.9.128 so rb-sys-dock resolves the
  :0.9.128 image tag we pre-seed.
- Rakefile: guard the dev-only rspec require behind begin/rescue LoadError,
  pass the loaded gemspec to ExtensionTask (so native:<platform> exists), and
  set cross_platform to the shipped union (x86_64-linux, aarch64-linux,
  arm64-darwin).
- lib/clusterkit.rb: add the versioned-ABI require shim (try
  clusterkit/<minor>/clusterkit first, fall back to flat) so the precompiled
  linux gems load.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@xrl xrl added the dry-run-release Run the full precompiled release matrix as a publish=false dry-run label Jun 18, 2026
@xrl xrl added dry-run-release Run the full precompiled release matrix as a publish=false dry-run and removed dry-run-release Run the full precompiled release matrix as a publish=false dry-run labels Jun 18, 2026
@xrl xrl added dry-run-release Run the full precompiled release matrix as a publish=false dry-run and removed dry-run-release Run the full precompiled release matrix as a publish=false dry-run labels Jun 18, 2026
…r-target

openblas-src (pkg-config-rs) ignores the unsuffixed PKG_CONFIG_PATH/LIBDIR
when host triple (x86_64) != target (aarch64) and only honors the
target-suffixed forms. With only the global vars set, pkg-config fell back
to the system .pc and resolved the HOST x86_64 openblas, so the aarch64 link
got -L /usr/lib/x86_64-linux-gnu/... and the cross linker rejected the
incompatible .so (cannot find -lopenblas). Switch to the per-target
PKG_CONFIG_PATH_aarch64-unknown-linux-gnu / PKG_CONFIG_LIBDIR_... forms so
openblas-src emits the arm64 libdir; keep PKG_CONFIG_ALLOW_CROSS global.

Also pin to @0.10.0 and, while grinding the cross link green, build ONLY
the aarch64 leg (full matrix restored once green).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@xrl xrl added dry-run-release Run the full precompiled release matrix as a publish=false dry-run and removed dry-run-release Run the full precompiled release matrix as a publish=false dry-run labels Jun 18, 2026
The per-target pkg-config scoping made the aarch64-linux leg build the
system-OpenBLAS cross gem green (run 27794379705: clusterkit-0.2.6-aarch64-linux.gem).
Re-enable darwin + x86_64-linux so the full precompiled set ships again.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@xrl xrl added dry-run-release Run the full precompiled release matrix as a publish=false dry-run and removed dry-run-release Run the full precompiled release matrix as a publish=false dry-run labels Jun 18, 2026
Pin both the release.yml and build.yml callers to the explicit
scientist-labs/rust-gem-release @0.10.0 version and update the doc
comments that referenced the @v0 moving major.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@xrl xrl marked this pull request as ready for review June 18, 2026 23:15
@xrl xrl added dry-run-release Run the full precompiled release matrix as a publish=false dry-run and removed dry-run-release Run the full precompiled release matrix as a publish=false dry-run labels Jun 18, 2026
@xrl xrl merged commit f72c23e into main Jun 19, 2026
21 of 23 checks passed
@xrl xrl deleted the migrate-to-rust-gem-release branch June 19, 2026 00:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dry-run-release Run the full precompiled release matrix as a publish=false dry-run

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant