-
Notifications
You must be signed in to change notification settings - Fork 7
256 lines (229 loc) · 8.57 KB
/
ruby-release.yml
File metadata and controls
256 lines (229 loc) · 8.57 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
# This workflow handles cross-platform gem building and publishing.
#
# Runs on:
# - Push to main: Release readiness check (builds gems, doesn't publish)
# - Release events: Builds and publishes gems to RubyGems.org
#
# To publish a new Ruby SDK version:
# 1. Ensure eppo_core is published first if ruby-sdk depends on a new version.
# 2. Create a GitHub release with tag format: ruby-sdk@x.x.x (e.g., ruby-sdk@3.7.5)
# 3. The workflow will cross-compile gems for all platforms
# 4. If successful, gems are automatically published to RubyGems.org
name: Ruby SDK - Release
on:
push:
branches:
- main
paths:
- 'ruby-sdk/**'
- '.github/workflows/ruby-release.yml'
release:
types: [published]
env:
CARGO_TERM_COLOR: always
jobs:
# Cross-compile gems for multiple platforms using rb-sys-dock.
#
# This job runs on pushes to main and releases to catch issues
# before we attempt a release (e.g., rb-sys updates, Docker image
# changes, new Ruby versions, platform toolchain issues).
#
# Important: This job always builds against the PUBLISHED eppo_core
# from crates.io, not the local version. This is intentional for
# releases (we want published gems to use published dependencies),
# and a technical limitation for main pushes (rb-sys-dock runs builds
# inside Docker and only mounts the ruby-sdk directory, so we cannot
# use the cargo config override like ruby_test does).
#
# Implications:
# - If ruby-sdk needs an unpublished eppo_core change, this job will
# fail until eppo_core is published.
# - We use continue-on-error for main pushes so these expected failures
# don't block merging. The failure is still visible as a warning.
# - On releases, failures are hard blockers to prevent broken publishes.
# - We skip PRs to avoid noise (ruby_test already validates functionality).
cross_gems:
runs-on: ubuntu-latest
if: ${{ github.event_name == 'push' || (github.event_name == 'release' && startsWith(github.ref_name, 'ruby-sdk@')) }}
continue-on-error: ${{ github.event_name != 'release' }}
defaults:
run:
working-directory: ruby-sdk
strategy:
fail-fast: false
matrix:
_:
- platform: x86_64-linux
- platform: x86_64-linux-musl
- platform: aarch64-linux
- platform: aarch64-linux-musl
- platform: arm-linux
- platform: arm64-darwin
# - platform: x64-mingw32
# - platform: x86-mingw-ucrt
steps:
- uses: actions/checkout@v6
- uses: oxidize-rb/actions/setup-ruby-and-rust@v1
with:
ruby-version: "3.4"
bundler-cache: true
cargo-cache: true
cargo-vendor: true
cache-version: v3-${{ matrix._.platform }}
- name: Set vars
id: vars
run: |
echo "rb-sys-version=$(bundle exec ruby -rrb_sys -e 'puts RbSys::VERSION')" >> $GITHUB_OUTPUT
- uses: "ruby/setup-ruby@v1"
with:
ruby-version: "3.4"
bundler-cache: true
- name: Configure environment
shell: bash
id: configure
run: |
: Configure environment
echo "RB_SYS_DOCK_UID=$(id -u)" >> $GITHUB_ENV
echo "RB_SYS_DOCK_GID=$(id -g)" >> $GITHUB_ENV
rb_sys_version="$((grep rb_sys Gemfile.lock | head -n 1 | grep -oE '[0-9]+\.[0-9]+\.[0-9]+') || (gem info rb_sys --remote | grep -oE '[0-9]+\.[0-9]+\.[0-9]+') || echo "latest")"
rb_sys_dock_cache_dir="$HOME/.cache/rb-sys-$rb_sys_version"
mkdir -p "$rb_sys_dock_cache_dir"
echo "RB_SYS_DOCK_CACHE_DIR=$rb_sys_dock_cache_dir" >> $GITHUB_ENV
echo "rb_sys_version=$rb_sys_version" >> $GITHUB_OUTPUT
- name: Setup caching
uses: actions/cache@v5
with:
path: |
${{ env.RB_SYS_DOCK_CACHE_DIR }}
ruby-sdk/tmp/rb-sys-dock/${{ matrix._.platform }}/target
key: rb-sys-dock-v0-${{ matrix._.platform }}-${{ hashFiles('**/Gemfile.lock', '**/Cargo.lock') }}
save-always: true
restore-keys: |
rb-sys-dock-v0-${{ matrix._.platform }}-
- name: Install cargo-cache
uses: oxidize-rb/actions/cargo-binstall@v1
id: install-cargo-cache
with:
crate: cargo-cache
version: 0.8.3
strategies: quick-install
- name: Clean the cargo cache
uses: oxidize-rb/actions/post-run@v1
with:
run: cargo-cache --autoclean
cwd: ruby-sdk
always: true
- name: Setup rb-sys
shell: bash
working-directory: ruby-sdk
run: |
version="${{ steps.configure.outputs.rb_sys_version }}"
echo "Installing rb_sys@$version"
if [ "$version" = "latest" ]; then
gem install rb_sys
else
gem install rb_sys -v $version
fi
- name: Build gem
shell: bash
run: |
: Compile gem
echo "Docker Working Directory: $(pwd)"
set -x
# We can't parallelize the Ruby versions because they get
# bundled into the same gem.
#
# However, not parallelizing versions is actually helpful
# because Cargo is able to reuse most of compile work
# between versions.
rb-sys-dock \
--platform ${{ matrix._.platform }} \
--mount-toolchains \
--ruby-versions 4.0,3.4,3.3,3.2,3.1,3.0 \
--build \
-- ${{ matrix._.rb-sys-dock-setup }}
- name: Smoke gem install
if: matrix._.platform == 'x86_64-linux' # GitHub actions architecture
run: |
gem install pkg/eppo-server-sdk-*.gem --verbose
script="EppoClient::init(EppoClient::Config.new('placeholder')); EppoClient::Client.instance.shutdown"
ruby -reppo_client -e "$script" 2>&1 || { echo "❌ Failed to run smoke test"; exit 1; }
echo "✅ Successfully installed gem"
env:
EPPO_LOG: "eppo=debug"
- name: Set outputs
id: set-outputs
shell: bash
run: |
: Set output
echo "gem-path=ruby-sdk/$(find pkg -name '*-${{ matrix._.platform }}.gem')" >> $GITHUB_OUTPUT
- name: Upload the cross-compiled gems
uses: actions/upload-artifact@v6
with:
name: cross-gem-${{ matrix._.platform }}
path: ${{ steps.set-outputs.outputs.gem-path }}
# Publish gems to RubyGems.org.
#
# This job is protected by TWO conditions:
# 1. github.event_name == 'release' - must be a GitHub release event
# 2. startsWith(github.ref_name, 'ruby-sdk@') - tag must match pattern ruby-sdk@x.x.x
#
# This prevents accidental publishing from:
# - Pushes to main (builds gems but doesn't publish)
# - Manual workflow dispatch
# - Releases for other packages (eppo_core@x.x.x, rust-sdk@x.x.x)
publish_ruby:
name: Publish to RubyGems
runs-on: ubuntu-latest
if: ${{ github.event_name == 'release' && startsWith(github.ref_name, 'ruby-sdk@') }}
needs: cross_gems
steps:
- uses: actions/checkout@v6
with:
submodules: true
- uses: actions/setup-node@v6
with:
node-version: "20"
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: "4.0"
- name: Download the cross-compiled gems
uses: actions/download-artifact@v7
with:
pattern: cross-gem-*
merge-multiple: true
- name: Check Cargo.lock
# Ensure that Cargo.lock matches Cargo.toml
run: cargo update --workspace --locked --verbose
working-directory: ruby-sdk
- name: Install dependencies
run: bundle install
working-directory: ruby-sdk
- name: Build
run: bundle exec rake build
working-directory: ruby-sdk
- name: Move the downloaded artifacts
run: |
mv *.gem ruby-sdk/pkg
- name: Publish to RubyGems
working-directory: ruby-sdk/pkg/
env:
RUBYGEMS_API_KEY: "${{ secrets.RUBYGEMS_API_KEY }}"
run: |
mkdir -p $HOME/.gem
touch $HOME/.gem/credentials
chmod 0600 $HOME/.gem/credentials
printf -- "---\n:rubygems_api_key: ${RUBYGEMS_API_KEY}\n" > $HOME/.gem/credentials
ls -l
for i in *.gem; do
if [ -f "$i" ]; then
if ! gem push "$i" >push.out; then
gemerr=$?
sed 's/^/::error:: /' push.out
if ! grep -q "Repushing of gem" push.out; then
exit $gemerr
fi
fi
fi
done