Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 16 additions & 3 deletions .github/workflows/build-gems.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ concurrency:
jobs:
ci-data:
uses: ./.github/workflows/native-gem-matrix.yml
with:
# Release branches build the platforms and Ruby versions pinned in their
# snapshot, if they have one.
snapshot: ${{ startsWith(github.ref_name, 'release-') }}

native:
name: Build native gems
Expand All @@ -27,7 +31,7 @@ jobs:

- uses: ruby/setup-ruby@v1
with:
ruby-version: "4.0"
ruby-version: ${{ fromJSON(needs.ci-data.outputs.result).latest-ruby-version }}

- uses: oxidize-rb/actions/cross-gem@v1
id: cross-gem
Expand All @@ -43,8 +47,10 @@ jobs:

smoke-test:
name: Smoke test native gem (${{ matrix.ruby-platform }})
needs: native
needs: [ci-data, native]
runs-on: ${{ matrix.os }}
env:
BUILT: ${{ contains(fromJSON(needs.ci-data.outputs.result).supported-ruby-platforms, matrix.ruby-platform) }}
strategy:
fail-fast: false
matrix:
Expand All @@ -62,16 +68,23 @@ jobs:
- ruby-platform: arm64-darwin
os: macos-15
steps:
- name: Skip platforms that aren't built
if: env.BUILT != 'true'
run: echo "::notice::${{ matrix.ruby-platform }} isn't built for this ref, skipping"

- uses: ruby/setup-ruby@v1
if: env.BUILT == 'true'
with:
ruby-version: "4.0"
ruby-version: ${{ fromJSON(needs.ci-data.outputs.result).latest-ruby-version }}

- uses: actions/download-artifact@v8
if: env.BUILT == 'true'
with:
name: cross-gem-${{ matrix.ruby-platform }}
path: pkg/

- name: Smoke gem install
if: env.BUILT == 'true'
shell: bash
run: |
gem install pkg/wasmtime-*.gem --verbose
Expand Down
16 changes: 5 additions & 11 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,11 @@ env:

jobs:
ci-data:
runs-on: ubuntu-latest
outputs:
result: ${{ steps.fetch.outputs.result }}
steps:
- id: fetch
uses: oxidize-rb/actions/fetch-ci-data@1.4.3
with:
stable-ruby-versions: |
# See https://github.com/bytecodealliance/wasmtime-rb/issues/286
# for details.
exclude: [head]
uses: ./.github/workflows/native-gem-matrix.yml
with:
# Release branches test the Ruby versions pinned in their snapshot, if
# they have one.
snapshot: ${{ startsWith(github.base_ref || github.ref_name, 'release-') }}

ci:
runs-on: ${{ matrix.os }}
Expand Down
60 changes: 58 additions & 2 deletions .github/workflows/native-gem-matrix.yml
Original file line number Diff line number Diff line change
@@ -1,18 +1,46 @@
---
name: Native gem matrix

# Resolves the Ruby platforms to build native gems for and the Ruby versions to
# build and test against.
#
# By default, these are the live lists from oxidize-rb, which change as Ruby
# versions and platforms are added or dropped. Release branches and tags pin
# them instead in `.github/release-matrix.json`, so that a patch release builds
# the same gems as the release before it. release-bump.yml writes the file for
# every release from `main`, so tags and the release branches created from
# them have it; `main` itself keeps using the live lists:
#
# {
# "supported-ruby-platforms": ["x86_64-linux", ...],
# "stable-ruby-versions": ["3.3", "3.4", ...]
# }
on:
workflow_call:
inputs:
snapshot:
description: Use `.github/release-matrix.json` if `ref` has one
required: false
type: boolean
default: false
ref:
description: Ref to read the snapshot from (defaults to the ref the workflow runs on)
required: false
type: string
default: ""
outputs:
result:
description: Supported Ruby platforms and stable Ruby versions
description: >-
Supported Ruby platforms (`supported-ruby-platforms`), stable Ruby
versions (`stable-ruby-versions`) and the latest of them
(`latest-ruby-version`)
value: ${{ jobs.resolve.outputs.result }}

jobs:
resolve:
runs-on: ubuntu-latest
outputs:
result: ${{ steps.fetch.outputs.result }}
result: ${{ steps.resolve.outputs.result }}
steps:
- id: fetch
uses: oxidize-rb/actions/fetch-ci-data@1.4.3
Expand All @@ -24,5 +52,33 @@ jobs:
# 3.0 is deprecated as stable ruby version according to:
# https://github.com/oxidize-rb/actions/blob/main/fetch-ci-data/evaluate.rb#L54
exclude: [arm-linux, arm-linux-musl, x64-mingw32]
# See https://github.com/bytecodealliance/wasmtime-rb/issues/286 for
# why `head` is excluded.
stable-ruby-versions: |
exclude: [head]

- uses: actions/checkout@v7
if: inputs.snapshot
with:
ref: ${{ inputs.ref }}
sparse-checkout: .github/release-matrix.json
sparse-checkout-cone-mode: false

- id: resolve
env:
LIVE: ${{ steps.fetch.outputs.result }}
SNAPSHOT: ${{ inputs.snapshot }}
run: |
result=$LIVE
file=.github/release-matrix.json
if [ "$SNAPSHOT" = true ] && [ -f "$file" ]; then
if ! jq -e '(.["supported-ruby-platforms"] | type == "array") and (.["stable-ruby-versions"] | type == "array")' "$file" >/dev/null; then
echo "::error::$file must have supported-ruby-platforms and stable-ruby-versions arrays"
exit 1
fi
echo "::notice::Using the platforms and Ruby versions in $file"
result=$(jq -c --slurpfile snapshot "$file" '. + $snapshot[0]' <<<"$result")
fi
result=$(jq -c '.["latest-ruby-version"] = (.["stable-ruby-versions"] | max_by(split(".") | map(tonumber)))' <<<"$result")
echo "$result" | jq .
echo "result=$result" >> "$GITHUB_OUTPUT"
19 changes: 19 additions & 0 deletions .github/workflows/release-bump.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,14 @@ concurrency:
group: release-bump-${{ inputs.branch || 'main' }}

jobs:
ci-data:
permissions:
contents: read
uses: ./.github/workflows/native-gem-matrix.yml

bump:
name: Prepare release pull request
needs: ci-data
runs-on: ubuntu-latest
permissions:
contents: write
Expand Down Expand Up @@ -147,6 +153,19 @@ jobs:
ruby "$RUNNER_TEMP/release.rb" changelog-entry "$VERSION" "$PREVIOUS" "$REPO_URL"
git diff

# Releases from `main` record the platforms and Ruby versions they're
# built for, so that release branches created from their tags keep
# building the same ones (see native-gem-matrix.yml). Release branches
# keep theirs.
- name: Snapshot the platforms and Ruby versions
if: steps.version.outputs.version && env.TARGET_BRANCH == 'main'
env:
MATRIX: ${{ needs.ci-data.outputs.result }}
run: |
jq '{"supported-ruby-platforms": .["supported-ruby-platforms"], "stable-ruby-versions": .["stable-ruby-versions"]}' <<<"$MATRIX" > .github/release-matrix.json
git add .github/release-matrix.json
git diff --cached -- .github/release-matrix.json

# Pull requests opened with GITHUB_TOKEN don't run the required checks, so
# the branches are only pushed, and a maintainer opens the pull requests
# from the links in the run summary.
Expand Down
34 changes: 29 additions & 5 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,21 @@ concurrency:
jobs:
ci-data:
uses: ./.github/workflows/native-gem-matrix.yml
with:
# This workflow always runs from `main`, but may build an older release
# branch or tag. The live lists of platforms and Ruby versions move on
# over time, and an older branch may not build for the new ones, so
# everything except `main` builds the ones pinned in its
# `.github/release-matrix.json`, if it has one. A patch release then
# ships the same gems as the release before it.
#
# The ref being built is the tag to release, else the `ref` of a dry run,
# else the ref the workflow runs on. A dry run of a release branch (e.g.
# `ref: release-48`) therefore builds exactly what its release will
# build, and a dry run of `main` uses the live lists, like `main`'s next
# release (see release-bump.yml).
snapshot: ${{ (inputs.tag || inputs.ref || github.ref_name) != 'main' }}
ref: ${{ inputs.tag || inputs.ref }}

build:
name: Build native gems
Expand All @@ -50,7 +65,7 @@ jobs:

- uses: ruby/setup-ruby@v1
with:
ruby-version: "4.0"
ruby-version: ${{ fromJSON(needs.ci-data.outputs.result).latest-ruby-version }}

- uses: oxidize-rb/actions/cross-gem@v1
id: cross-gem
Expand All @@ -66,8 +81,10 @@ jobs:

smoke-test:
name: Smoke test native gem (${{ matrix.ruby-platform }})
needs: build
needs: [ci-data, build]
runs-on: ${{ matrix.os }}
env:
BUILT: ${{ contains(fromJSON(needs.ci-data.outputs.result).supported-ruby-platforms, matrix.ruby-platform) }}
strategy:
fail-fast: false
matrix:
Expand All @@ -85,16 +102,23 @@ jobs:
- ruby-platform: arm64-darwin
os: macos-15
steps:
- name: Skip platforms that aren't built
if: env.BUILT != 'true'
run: echo "::notice::${{ matrix.ruby-platform }} isn't built for this ref, skipping"

- uses: ruby/setup-ruby@v1
if: env.BUILT == 'true'
with:
ruby-version: "4.0"
ruby-version: ${{ fromJSON(needs.ci-data.outputs.result).latest-ruby-version }}

- uses: actions/download-artifact@v8
if: env.BUILT == 'true'
with:
name: cross-gem-${{ matrix.ruby-platform }}
path: pkg/

- name: Smoke gem install
if: env.BUILT == 'true'
shell: bash
run: |
gem install pkg/wasmtime-*.gem --verbose
Expand All @@ -104,7 +128,7 @@ jobs:

release:
name: Release
needs: [build, smoke-test]
needs: [ci-data, build, smoke-test]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
Expand All @@ -113,7 +137,7 @@ jobs:

- uses: oxidize-rb/actions/setup-ruby-and-rust@v1
with:
ruby-version: "4.0"
ruby-version: ${{ fromJSON(needs.ci-data.outputs.result).latest-ruby-version }}
bundler-cache: true
cargo-cache: true
cache-version: v1
Expand Down
10 changes: 6 additions & 4 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,12 @@ pick the version following [Versioning](#versioning).
1. Open the pull request from the link in the workflow run's summary. Pull
requests opened by workflows don't run the required checks, so they have to
be opened by a maintainer.
1. Review the changelog and merge the pull request. This starts the
[Release tag] workflow, which tags the version and runs the release
workflow: it pushes the gem to RubyGems and creates a draft release on
GitHub.
1. Review the changelog and `.github/release-matrix.json`, and merge the pull
request. The JSON file lists the platforms and Ruby versions the gem is
built for; it pins them for later patch releases from a release branch.
Merging starts the [Release tag] workflow, which tags the version and runs
the release workflow: it pushes the gem to RubyGems and creates a draft
release on GitHub.
1. Edit the release notes if needed and publish the draft release.
1. If the release changes the supported versions, update the table in
[SECURITY.md](SECURITY.md).
Expand Down
Loading