2
3
# Publishes the smbcloud-auth (sdk/gems/auth) and smbcloud-model
4
# (sdk/gems/model) Ruby gems to RubyGems.
5
-# Builds pre-compiled native gems for the supported Unix platforms, plus a
6
-# source gem as a fallback for unsupported environments.
5
+# Native gems are cross-compiled on Linux with rb-sys-dock, so the darwin gems
6
+# get the generic `arm64-darwin` / `x86_64-darwin` platforms (a gem built with a
7
+# runner's Ruby gets e.g. `arm64-darwin-23`, which only matches that macOS
8
+# release). Each native gem is fat: one extension per Ruby minor >= 3.1. A
9
+# source gem covers every other platform and Ruby.
10
+#
11
+# Pull requests that touch the gems build everything but publish nothing.
12
#
13
# Required secrets:
14
# RUBYGEMS_API_KEY — RubyGems.org API key with push access to smbcloud-auth and
23
ref:
24
description: "Git ref to build from (defaults to the tag)"
25
required: false
26
+ pull_request:
27
+ paths:
28
+ - "sdk/gems/auth/**"
29
+ - "sdk/gems/model/**"
30
+ - ".github/workflows/release-sdk-gem.yml"
31
32
permissions:
33
contents: read
38
jobs:
39
# ── Build native gems ──────────────────────────────────────────────────────
40
build-gems:
31
- name: Build ${{ matrix.gem }} gem (${{ matrix.name }})
32
- runs-on: ${{ matrix.runner }}
41
+ name: Build ${{ matrix.gem }} gem (${{ matrix.platform }})
42
+ runs-on: ubuntu-latest
43
strategy:
44
fail-fast: false
45
matrix:
46
gem: [auth, model]
37
- name: [linux-x64, linux-arm64, darwin-arm64, darwin-x64]
38
- include:
39
- - { name: linux-x64, runner: ubuntu-latest, platform: x86_64-linux }
40
- - {
41
- name: linux-arm64,
42
- runner: ubuntu-24.04-arm,
43
- platform: aarch64-linux,
44
- }
45
- - { name: darwin-arm64, runner: macos-latest, platform: arm64-darwin }
46
- - {
47
- name: darwin-x64,
48
- runner: macos-15-intel,
49
- platform: x86_64-darwin,
50
- }
51
- # Windows is excluded: rb-sys bindgen fails because RubyInstaller is
52
- # MinGW-based and its rbconfig emits GCC flags that are incompatible
53
- # with the MSVC clang used by bindgen. The source gem provides a
54
- # fallback for Windows users (compiled at install time).
47
+ platform: [x86_64-linux, aarch64-linux, arm64-darwin, x86_64-darwin]
48
49
steps:
50
- name: Checkout
55
- name: Set the release version
56
shell: bash
57
run: |
65
- if [[ "${GITHUB_REF_TYPE}" == "tag" ]]; then
58
+ if [[ "${GITHUB_EVENT_NAME}" == "pull_request" ]]; then
59
+ release_version="$(sed -n "s/.*VERSION = '\(.*\)'/\1/p" sdk/gems/${{ matrix.gem }}/lib/${{ matrix.gem }}/version.rb)"
60
+ elif [[ "${GITHUB_REF_TYPE}" == "tag" ]]; then
61
release_version="${GITHUB_REF_NAME#v}"
62
else
63
release_version="${{ github.event.inputs.tag }}"
66
echo "RELEASE_VERSION=${release_version}" >> "$GITHUB_ENV"
67
68
- name: Wait for Rust crate dependencies on crates.io
69
+ if: github.event_name != 'pull_request'
70
shell: bash
71
run: |
72
for crate_name in smbcloud-auth-sdk smbcloud-model smbcloud-network; do
86
done
87
done
88
93
- - name: Install system dependencies (Linux)
94
- if: runner.os == 'Linux'
95
- run: sudo apt-get update -q && sudo apt-get install -y libclang-dev
96
-
89
- name: Read Rust toolchain
90
shell: bash
91
run: |
101
with:
102
toolchain: ${{ env.RUST_TOOLCHAIN }}
103
104
+ # The container build uses this lockfile, so resolve the published
105
+ # smbcloud-* crates for this release on the host first.
106
- name: Resolve the published Rust crate dependencies
107
shell: bash
108
run: cargo generate-lockfile --manifest-path sdk/gems/${{ matrix.gem }}/Cargo.toml
109
116
- # Scope the Rust cache to the gem's own Cargo workspace so its registry
117
- # deps are cached independently from the main workspace.
118
- - name: Setup Rust cache
119
- uses: Swatinem/rust-cache@v2
120
- with:
121
- key: sdk-gem-${{ matrix.gem }}-${{ matrix.name }}
122
- workspaces: sdk/gems/${{ matrix.gem }}
123
-
110
- name: Setup Ruby
111
uses: ruby/setup-ruby@v1
112
with:
114
bundler-cache: true
115
working-directory: sdk/gems/${{ matrix.gem }}
116
131
- - name: Build native gem
132
- working-directory: sdk/gems/${{ matrix.gem }}
133
- shell: bash
134
- run: bundle exec rake native gem
117
+ - name: Cross-compile native gem
118
+ id: cross-gem
119
+ uses: oxidize-rb/actions/cross-gem@v1
120
+ with:
121
+ platform: ${{ matrix.platform }}
122
+ ruby-versions: ">= 3.1"
123
+ working-directory: sdk/gems/${{ matrix.gem }}
124
+ cache-version: ${{ matrix.gem }}
125
126
- name: Upload gem artifact
127
uses: actions/upload-artifact@v7
128
with:
139
- name: gem-${{ matrix.gem }}-${{ matrix.name }}
140
- path: sdk/gems/${{ matrix.gem }}/pkg/*.gem
129
+ name: gem-${{ matrix.gem }}-${{ matrix.platform }}
130
+ path: ${{ steps.cross-gem.outputs.gem-path }}
131
132
# ── Build source gem (fallback for unsupported platforms) ──────────────────
133
build-source-gem:
146
- name: Set the release version
147
shell: bash
148
run: |
159
- if [[ "${GITHUB_REF_TYPE}" == "tag" ]]; then
149
+ if [[ "${GITHUB_EVENT_NAME}" == "pull_request" ]]; then
150
+ release_version="$(sed -n "s/.*VERSION = '\(.*\)'/\1/p" sdk/gems/${{ matrix.gem }}/lib/${{ matrix.gem }}/version.rb)"
151
+ elif [[ "${GITHUB_REF_TYPE}" == "tag" ]]; then
152
release_version="${GITHUB_REF_NAME#v}"
153
else
154
release_version="${{ github.event.inputs.tag }}"
169
exit 1
170
fi
171
172
+ # The source gem ships Cargo.lock; resolve it against the release's
173
+ # published crates rather than shipping the committed lock.
174
+ - name: Resolve the published Rust crate dependencies
175
+ shell: bash
176
+ run: cargo generate-lockfile --manifest-path sdk/gems/${{ matrix.gem }}/Cargo.toml
177
+
178
- name: Setup Ruby
179
uses: ruby/setup-ruby@v1
180
with:
196
push-gems:
197
name: Push ${{ matrix.gem }} to RubyGems
198
needs: [build-gems, build-source-gem]
199
+ if: github.event_name == 'workflow_dispatch'
200
runs-on: ubuntu-latest
201
strategy:
202
fail-fast: false
212
- name: Set the release version
213
shell: bash
214
run: |
216
- if [[ "${GITHUB_REF_TYPE}" == "tag" ]]; then
215
+ if [[ "${GITHUB_EVENT_NAME}" == "pull_request" ]]; then
216
+ release_version="$(sed -n "s/.*VERSION = '\(.*\)'/\1/p" sdk/gems/${{ matrix.gem }}/lib/${{ matrix.gem }}/version.rb)"
217
+ elif [[ "${GITHUB_REF_TYPE}" == "tag" ]]; then
218
release_version="${GITHUB_REF_NAME#v}"
219
else
220
release_version="${{ github.event.inputs.tag }}"