From 0cc546c022a8d84666c2a7647ee32f9ec05c2b14 Mon Sep 17 00:00:00 2001 From: John Mitsch Date: Mon, 27 Apr 2026 16:14:57 -0400 Subject: [PATCH 1/7] fix(ruby): drop hardcoded macOS bundle path from base gemspec The base gemspec listed lib/quicknode_sdk.bundle in s.files, which broke release CI on Linux where only lib/quicknode_sdk.so exists. Platform-specific native libs are added by build-platform-gem.rb (and the inline equivalent in release.yml), so the base spec should not enumerate any native artifact. --- ruby/quicknode_sdk.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ruby/quicknode_sdk.gemspec b/ruby/quicknode_sdk.gemspec index e8e3b64..16af320 100644 --- a/ruby/quicknode_sdk.gemspec +++ b/ruby/quicknode_sdk.gemspec @@ -4,7 +4,7 @@ Gem::Specification.new do |s| s.summary = "Quicknode SDK for Ruby" s.authors = ["Quicknode"] s.license = "MIT" - s.files = Dir["lib/**/*.rb"] + Dir["sig/**/*.rbs"] + ["lib/quicknode_sdk.bundle", "README.md"] + s.files = Dir["lib/**/*.rb"] + Dir["sig/**/*.rbs"] + ["README.md"] s.required_ruby_version = ">= 3.0" s.add_runtime_dependency "hashie", "~> 5.0" end From 43aff7e377d3b8e8019518e78d0f6a8421f3e218 Mon Sep 17 00:00:00 2001 From: John Mitsch Date: Mon, 27 Apr 2026 16:16:00 -0400 Subject: [PATCH 2/7] fix(ruby): load native lib by stem so .bundle/.so both resolve Move the native artifact under lib/quicknode_sdk/ and require it via "quicknode_sdk/quicknode_sdk" so Ruby's loader picks the platform- appropriate extension automatically. Without this, Linux platform gems (.so) cannot be loaded by the entry-point .rb, which hardcoded .bundle. --- .gitignore | 4 ++-- Justfile | 2 +- ruby/lib/quicknode_sdk.rb | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index 57b2ece..867717b 100644 --- a/.gitignore +++ b/.gitignore @@ -70,5 +70,5 @@ docs/superpowers/ notes.md # Ruby native extension (built locally by `just ruby-build`) -ruby/lib/*.bundle -ruby/lib/*.so +ruby/lib/quicknode_sdk/*.bundle +ruby/lib/quicknode_sdk/*.so diff --git a/Justfile b/Justfile index abc8499..af9810e 100644 --- a/Justfile +++ b/Justfile @@ -15,7 +15,7 @@ node-build: ruby-build: cargo build -p sdk-ruby --release - cp target/release/libquicknode_sdk.dylib ruby/lib/quicknode_sdk.bundle + cp target/release/libquicknode_sdk.dylib ruby/lib/quicknode_sdk/quicknode_sdk.bundle # Requires: maturin on PATH (e.g. pipx install maturin or brew install maturin) macos-dist-python: diff --git a/ruby/lib/quicknode_sdk.rb b/ruby/lib/quicknode_sdk.rb index f1509ce..dc46431 100644 --- a/ruby/lib/quicknode_sdk.rb +++ b/ruby/lib/quicknode_sdk.rb @@ -1,4 +1,4 @@ -require_relative "quicknode_sdk.bundle" +require_relative "quicknode_sdk/quicknode_sdk" require_relative "quicknode_sdk/wrap" require_relative "quicknode_sdk/native_delegator" require_relative "quicknode_sdk/clients/admin" From 9d6ab66735f425a1d10033eb8287a97120715c6d Mon Sep 17 00:00:00 2001 From: John Mitsch Date: Mon, 27 Apr 2026 16:16:43 -0400 Subject: [PATCH 3/7] fix(ruby): stage native lib under lib/quicknode_sdk/ for macOS dist build Mirror the loader-path change in macos-build-and-publish so the macOS arm64 platform gem ships the bundle at lib/quicknode_sdk/quicknode_sdk.bundle, matching what quicknode_sdk.rb now requires. --- Justfile | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Justfile b/Justfile index af9810e..90e0ab0 100644 --- a/Justfile +++ b/Justfile @@ -61,10 +61,11 @@ macos-build-and-publish version: just macos-dist-python just macos-dist-node just macos-dist-ruby - # Stage the compiled bundle under ruby/lib so the platform gem picks it up, + # Stage the compiled bundle under ruby/lib/quicknode_sdk so the platform gem picks it up, # then build the arm64-darwin gem. - cp dist/quicknode_sdk.bundle ruby/lib/quicknode_sdk.bundle - cd ruby && ruby ../scripts/build-platform-gem.rb arm64-darwin lib/quicknode_sdk.bundle && gem build quicknode_sdk_platform.gemspec && rm quicknode_sdk_platform.gemspec && cd .. + mkdir -p ruby/lib/quicknode_sdk + cp dist/quicknode_sdk.bundle ruby/lib/quicknode_sdk/quicknode_sdk.bundle + cd ruby && ruby ../scripts/build-platform-gem.rb arm64-darwin lib/quicknode_sdk/quicknode_sdk.bundle && gem build quicknode_sdk_platform.gemspec && rm quicknode_sdk_platform.gemspec && cd .. mv ruby/*.gem dist/ gh release upload "v{{version}}" dist/*.whl dist/index.darwin-arm64.node dist/*.gem --clobber echo "Uploaded macOS arm64 artifacts to v{{version}}" From 0dcc43afe544e6bb8e930c1cc444bccd3e27aba8 Mon Sep 17 00:00:00 2001 From: John Mitsch Date: Mon, 27 Apr 2026 16:17:13 -0400 Subject: [PATCH 4/7] fix(ruby): build Linux platform gems with native lib under lib/quicknode_sdk/ Update both Linux build paths (cross and native), the strip target, and the inline platform gemspec's spec.files entry to use the new lib/quicknode_sdk/quicknode_sdk.so location. --- .github/workflows/release.yml | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index baef973..fe21667 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -188,21 +188,23 @@ jobs: if: matrix.cross run: | cargo zigbuild --release -p sdk-ruby --target ${{ matrix.target }} - cp target/${{ matrix.target }}/release/libquicknode_sdk.so ruby/lib/quicknode_sdk.so + mkdir -p ruby/lib/quicknode_sdk + cp target/${{ matrix.target }}/release/libquicknode_sdk.so ruby/lib/quicknode_sdk/quicknode_sdk.so - name: Build native extension (native) if: '!matrix.cross' run: | cargo build --release -p sdk-ruby - cp target/release/libquicknode_sdk.so ruby/lib/quicknode_sdk.so + mkdir -p ruby/lib/quicknode_sdk + cp target/release/libquicknode_sdk.so ruby/lib/quicknode_sdk/quicknode_sdk.so - name: Strip debug symbols run: | if [ "${{ matrix.cross }}" = "true" ]; then sudo apt-get install -y llvm - llvm-strip ruby/lib/quicknode_sdk.so + llvm-strip ruby/lib/quicknode_sdk/quicknode_sdk.so else - strip ruby/lib/quicknode_sdk.so + strip ruby/lib/quicknode_sdk/quicknode_sdk.so fi - name: Build platform gem @@ -212,7 +214,7 @@ jobs: spec = Gem::Specification.load('quicknode_sdk.gemspec') spec.platform = Gem::Platform.new('${{ matrix.gem_platform }}') spec.extensions = [] - spec.files += ['lib/quicknode_sdk.so'] + spec.files += ['lib/quicknode_sdk/quicknode_sdk.so'] File.write('quicknode_sdk_platform.gemspec', spec.to_ruby) " gem build quicknode_sdk_platform.gemspec From 35efdfc49cdc7179933bd8c3d5ec59a1418b6605 Mon Sep 17 00:00:00 2001 From: John Mitsch Date: Mon, 27 Apr 2026 16:17:39 -0400 Subject: [PATCH 5/7] build(ruby): stop publishing non-functional source gem The source gem ships no extconf.rb and no precompiled native lib, so gem install on platforms without a published platform gem produces an unloadable install. Drop the source-gem build and update the publisher to expect 3 platform gems instead of 4. --- .github/workflows/publish-rubygems.yml | 10 ++-------- .github/workflows/release.yml | 5 ----- 2 files changed, 2 insertions(+), 13 deletions(-) diff --git a/.github/workflows/publish-rubygems.yml b/.github/workflows/publish-rubygems.yml index ac7287f..d89a01e 100644 --- a/.github/workflows/publish-rubygems.yml +++ b/.github/workflows/publish-rubygems.yml @@ -46,14 +46,8 @@ jobs: exit 1 fi done - # Source gem has no platform suffix, e.g. quicknode_sdk-0.1.0.gem - if ! ls dist/quicknode_sdk-[0-9]*.gem 2>/dev/null | grep -Ev '(x86_64-linux|aarch64-linux|arm64-darwin)\.gem$' >/dev/null; then - echo "Missing source gem (quicknode_sdk-.gem)" - ls -la dist/ - exit 1 - fi - if [ "$gem_count" -ne 4 ]; then - echo "Expected 4 gems (3 platform + 1 source), got $gem_count" + if [ "$gem_count" -ne 3 ]; then + echo "Expected 3 platform gems, got $gem_count" ls -la dist/ exit 1 fi diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index fe21667..b7bb419 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -220,11 +220,6 @@ jobs: gem build quicknode_sdk_platform.gemspec rm quicknode_sdk_platform.gemspec - - name: Build source gem - if: matrix.target == 'x86_64-unknown-linux-gnu' - working-directory: ruby - run: gem build quicknode_sdk.gemspec - - uses: actions/upload-artifact@v4 with: name: ruby-${{ matrix.target }} From b6ce97ac9d75812d0d4236072e10d45eb0e546f2 Mon Sep 17 00:00:00 2001 From: John Mitsch Date: Mon, 27 Apr 2026 16:19:09 -0400 Subject: [PATCH 6/7] fix(ruby): missed CI cleanup for source-gem removal Update remaining stale references to the old lib/quicknode_sdk.bundle path and the obsolete "source gem compiles on install" comment in release.yml. Also extend solargraph's exclude list to cover the .so variant now that Linux platform gems ship a native artifact too. --- .github/workflows/release.yml | 3 ++- CLAUDE.md | 2 +- ruby/.solargraph.yml | 3 ++- scripts/build-platform-gem.rb | 2 +- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b7bb419..d9e27a5 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -159,7 +159,8 @@ jobs: cross: true gem_platform: aarch64-linux # musl targets are excluded: Rust cdylib is incompatible with musl (no dynamic linker). - # Users on musl Linux (e.g. Alpine) will use the source gem which compiles on install. + # Users on platforms without a published platform gem (musl Linux, Windows) will get + # a normal RubyGems "no compatible platform" error at install time. # Placeholder for future macOS support: # - target: aarch64-apple-darwin # cross: false diff --git a/CLAUDE.md b/CLAUDE.md index 1cc0ddb..80de430 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -34,7 +34,7 @@ just node-build # npm install + build + test ```bash just ruby-build # cargo build + copy .bundle artifact ``` -The build compiles `crates/ruby` and copies the resulting `libquicknode_sdk.dylib` to `ruby/lib/quicknode_sdk.bundle` (macOS) or equivalent `.so` on Linux. +The build compiles `crates/ruby` and copies the resulting `libquicknode_sdk.dylib` to `ruby/lib/quicknode_sdk/quicknode_sdk.bundle` (macOS) or equivalent `.so` on Linux. The native lib lives under `lib/quicknode_sdk/` so `require_relative "quicknode_sdk/quicknode_sdk"` picks the platform extension automatically. ## Verification diff --git a/ruby/.solargraph.yml b/ruby/.solargraph.yml index 690a5d0..2a4783b 100644 --- a/ruby/.solargraph.yml +++ b/ruby/.solargraph.yml @@ -1,7 +1,8 @@ include: - "lib/**/*.rb" exclude: - - "lib/quicknode_sdk.bundle" + - "lib/quicknode_sdk/quicknode_sdk.bundle" + - "lib/quicknode_sdk/quicknode_sdk.so" - "examples/**/*" require_paths: - lib diff --git a/scripts/build-platform-gem.rb b/scripts/build-platform-gem.rb index 7ea923e..d619fdf 100755 --- a/scripts/build-platform-gem.rb +++ b/scripts/build-platform-gem.rb @@ -3,7 +3,7 @@ # that includes a prebuilt native library. Run from the ruby/ directory. # # Usage: ruby ../scripts/build-platform-gem.rb -# Example: ruby ../scripts/build-platform-gem.rb arm64-darwin lib/quicknode_sdk.bundle +# Example: ruby ../scripts/build-platform-gem.rb arm64-darwin lib/quicknode_sdk/quicknode_sdk.bundle platform, lib_file = ARGV abort "Usage: build-platform-gem.rb " unless platform && lib_file From 9e4d2ecb12e2bbe931cb39af647e2c572cd3ebea Mon Sep 17 00:00:00 2001 From: John Mitsch Date: Mon, 27 Apr 2026 16:23:53 -0400 Subject: [PATCH 7/7] fix(just): restore parameterized 'release' recipe name The recipe takes a version argument (just release 0.2.0); the prior 'release_version' name with no parameter would have made the {{version}} substitutions silently empty. --- Justfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Justfile b/Justfile index 90e0ab0..09691a2 100644 --- a/Justfile +++ b/Justfile @@ -78,7 +78,7 @@ lint: # Bump version across all manifests, commit, and tag for release. # Usage: just release 0.2.0 -release_version: +release version: sed -i.bak 's/^version = ".*"/version = "{{version}}"/' Cargo.toml && rm Cargo.toml.bak sed -i.bak 's/^version = ".*"/version = "{{version}}"/' pyproject.toml && rm pyproject.toml.bak uv lock