on:
push:
tags:
- "v*.*.*"
name: "Release"
jobs:
crate-info:
name: "Extract crate info"
runs-on: "ubuntu-latest"
outputs:
version: ${{ steps.derive.outputs.version }}
steps:
- id: "derive"
name: "Derive crate info from Git tag"
run: |
FULL_REF="${{ github.ref }}"
REGEX="^refs\/tags\/v(.*)$"
[[ $FULL_REF =~ $REGEX ]];
echo "version=${BASH_REMATCH[1]}" >> $GITHUB_OUTPUT
commit-branch-check:
name: "Check commit branch"
runs-on: "ubuntu-latest"
needs: ["crate-info"]
steps:
- name: "Checkout source code"
uses: "actions/checkout@v4"
with:
fetch-depth: 0
- name: "Check if commit is on master"
run: |
COMMIT_HASH=$(git log -1 --format=%H ${{ github.ref }})
GREP_OUTPUT=$(git log origin/master --format=%H | grep "$COMMIT_HASH")
if [ -z "$GREP_OUTPUT" ]; then
echo "Cannot release commits not on the master branch"
exit 1
fi
package-version-check:
name: "Check package versions"
runs-on: "ubuntu-latest"
needs: ["crate-info"]
steps:
- name: "Checkout source code"
uses: "actions/checkout@v4"
- name: "Check Rust version against Cargo.toml"
run: |
EXPECTED_VERSION="${{ needs.crate-info.outputs.version }}"
ACTUAL_VERSION=$(cargo metadata --no-deps --format-version 1 | jq -r '.packages[] | select(.name == "bellows") | .version')
if [ "$ACTUAL_VERSION" != "$EXPECTED_VERSION" ]; then
echo "Crate version mismatch: expected $EXPECTED_VERSION, found $ACTUAL_VERSION"
exit 1
fi
- name: "Check TypeScript version against package.json"
run: |
EXPECTED_VERSION="${{ needs.crate-info.outputs.version }}"
ACTUAL_VERSION=$(jq -r '.version' bellows-ts/package.json)
if [ "$ACTUAL_VERSION" != "$EXPECTED_VERSION" ]; then
echo "TypeScript package version mismatch: expected $EXPECTED_VERSION, found $ACTUAL_VERSION"
exit 1
fi
build:
name: "Build for ${{ matrix.os }}"
runs-on: "${{ matrix.os }}"
needs: ["crate-info"]
strategy:
matrix:
os:
- "ubuntu-latest"
- "windows-latest"
- "macos-latest"
steps:
- name: "Checkout source code"
uses: "actions/checkout@v4"
- name: "Setup stable toolchain"
uses: "actions-rs/toolchain@v1"
with:
toolchain: "stable"
profile: "minimal"
override: true
- name: "Setup pnpm"
uses: "pnpm/action-setup@v4"
- name: "Setup Node.js"
uses: "actions/setup-node@v4"
with:
node-version: "22"
cache: "pnpm"
- name: "Install Node dependencies"
run: |
pnpm install --frozen-lockfile
- name: "Build crate"
run: |
cargo build --all --all-targets
- name: "Typecheck TypeScript package"
run: |
pnpm --dir bellows-ts typecheck
- name: "Build TypeScript package"
run: |
pnpm --dir bellows-ts build
crates-io-release:
name: "Release to crates.io"
runs-on: "ubuntu-latest"
needs:
- "crate-info"
- "commit-branch-check"
- "package-version-check"
- "build"
steps:
- name: "Checkout source code"
uses: "actions/checkout@v4"
- name: "Login to crates.io"
run: |
cargo login ${{ secrets.CRATES_IO_API_TOKEN }}
- name: "Publish crate"
run: |
cargo publish
npm-release:
name: "Release to npm"
runs-on: "ubuntu-latest"
needs:
- "crate-info"
- "commit-branch-check"
- "package-version-check"
- "build"
steps:
- name: "Checkout source code"
uses: "actions/checkout@v4"
- name: "Setup pnpm"
uses: "pnpm/action-setup@v4"
- name: "Setup Node.js"
uses: "actions/setup-node@v4"
with:
node-version: "22"
cache: "pnpm"
registry-url: "https://registry.npmjs.org"
- name: "Install Node dependencies"
run: |
pnpm install --frozen-lockfile
- name: "Build TypeScript package"
run: |
pnpm --dir bellows-ts build
- name: "Publish TypeScript package"
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
run: |
pnpm --dir bellows-ts publish --no-git-checks --access public