Skip to content

chore(release): parameterize release.py and stamp 0.19.1-djbclark.2 #2

chore(release): parameterize release.py and stamp 0.19.1-djbclark.2

chore(release): parameterize release.py and stamp 0.19.1-djbclark.2 #2

Workflow file for this run

name: "Ruby gems"
# Builds platform-specific gems for the Ruby SDK. Each gem bundles the
# secretspec-ffi staticlib (into vendor/); at `gem install` mkmf compiles a tiny
# C glue and statically links that archive, so the resolver is embedded in the
# extension and one platform gem serves every Ruby ABI.
#
# NOTE: as with the Python wheels, the Linux gem here links the runner's glibc.
# A portable release build should use a baseline toolchain. That is the
# remaining follow-up; the build + bundling mechanism below is what is
# validated. Install requires a C compiler and Ruby headers.
#
# The Windows gem (x64-mingw-ucrt) bundles a staticlib from the
# `x86_64-pc-windows-gnu` Rust target (declared in rust-toolchain.toml):
# RubyInstaller's devkit is MinGW, whose linker cannot consume MSVC `.lib`
# archives, while the GNU target emits the same `lib<name>.a` naming the
# staging script and mkmf extension already assume. setup-ruby's MSYS2 devkit
# supplies the mingw gcc that aws-lc-sys and the other C deps compile with;
# NASM assembles aws-lc's x86_64 assembly. The SDK itself is exercised on
# every PR by the devenv-based sdks.yml; this workflow only builds the
# distributable gems.
on:
workflow_call:
workflow_dispatch:
push:
tags:
- v**
# PR runs are scoped to changes in the Ruby SDK or this workflow. Core
# resolver and FFI changes are verified on PRs by the devenv-based test.yml,
# sdks.yml, and ffi-build.yml; the full matrix here still runs on tags and
# manual dispatch.
pull_request:
paths:
- "secretspec-rb/**"
- ".github/workflows/ruby-gems.yml"
- "scripts/sync-sdk-versions.sh"
- "scripts/copy-mingw-import-libs.sh"
permissions:
contents: read
jobs:
gems:
name: ${{ matrix.target }}
runs-on: ${{ matrix.runner }}
strategy:
fail-fast: false
matrix:
include:
- { target: x86_64-linux, runner: ubuntu-latest }
- { target: aarch64-linux, runner: ubuntu-24.04-arm }
- { target: arm64-darwin, runner: macos-latest, deployment_target: "12.0" }
- { target: x64-mingw-ucrt, runner: windows-latest }
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Sync SDK package versions
run: bash scripts/sync-sdk-versions.sh
- name: Install Rust (pinned by rust-toolchain.toml)
run: rustup toolchain install
# See the header: the Windows gem links with RubyInstaller's MinGW
# devkit, so the staticlib must come from the GNU target, not the
# runner's default MSVC one. stage-staticlib.sh reads CARGO_BUILD_TARGET
# to locate the per-target artifact.
- name: Target the GNU toolchain (Windows)
if: runner.os == 'Windows'
shell: bash
run: echo "CARGO_BUILD_TARGET=x86_64-pc-windows-gnu" >> "$GITHUB_ENV"
- name: Install NASM (aws-lc-sys assembly, Windows)
if: runner.os == 'Windows'
uses: ilammy/setup-nasm@72793074d3c8cdda771dba85f6deafe00623038b # v1.5.2
# Placed after the CARGO_BUILD_TARGET/toolchain setup so the cache key
# reflects them; keyed per matrix target (the automatic key covers only
# the job id, toolchain, and lockfile).
- name: Cache Rust builds
uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
with:
key: ${{ matrix.target }}
- uses: ruby/setup-ruby@95ef2b042f9d7a56d8268cba8559e2842e2ad01b # v1.321.0
with:
ruby-version: "3.3"
- name: Stage the staticlib and build the platform gem
shell: bash
env:
MACOSX_DEPLOYMENT_TARGET: ${{ matrix.deployment_target }}
EXPECTED_GEM_PLATFORM: ${{ matrix.target }}
run: |
bash secretspec-rb/scripts/stage-staticlib.sh
cd secretspec-rb
gem build secretspec.gemspec
ruby -rrubygems/package -e '
gem = Dir["secretspec-*.gem"].fetch(0)
platform = Gem::Package.new(gem).spec.platform.to_s
expected = ENV.fetch("EXPECTED_GEM_PLATFORM")
abort "expected gem platform #{expected}, got #{platform}" unless platform == expected
'
- name: Smoke test the gem
shell: bash
run: |
cd secretspec-rb
# Installing compiles the extension (spec.extensions) against the
# bundled vendor/libsecretspec_ffi.a -- no Rust toolchain needed here.
gem install --no-document --install-dir "$RUNNER_TEMP/gemhome" secretspec-*.gem
# Run outside the repo so only the installed extension satisfies require.
cd "$RUNNER_TEMP"
GEM_HOME="$RUNNER_TEMP/gemhome" GEM_PATH="$RUNNER_TEMP/gemhome" \
ruby -e 'require "secretspec"; puts "abi " + Secretspec.abi_version'
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: gem-${{ matrix.target }}
path: secretspec-rb/*.gem
publish:
name: publish to RubyGems
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
needs: [gems]
runs-on: ubuntu-latest
# Must match the "Environment" configured on rubygems.org's pending
# trusted publisher for the "secretspec" gem (see RELEASE.md) -- RubyGems
# matches trusted publishers by repo + workflow filename + environment,
# no ID or role value is issued or needed.
environment: release
permissions:
id-token: write # RubyGems Trusted Publishing (OIDC), no token needed
contents: read
steps:
- uses: ruby/setup-ruby@95ef2b042f9d7a56d8268cba8559e2842e2ad01b # v1.321.0
with:
ruby-version: "3.3"
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
path: gems
merge-multiple: true
- name: Configure RubyGems credentials (OIDC trusted publishing)
uses: rubygems/configure-rubygems-credentials@dc5a8d8553e6ee01fc26761a49e99e733d17954a # v2.1.0
- name: gem push
run: |
for gem in gems/*.gem; do
gem push "$gem"
done