Files
routstrd/.github/workflows/release.yml
T
redshift 8d41ae8e3f ci: publish routstrd to npm on tag via trusted publishing
Add a tag-gated publish-npm job that publishes to npm with provenance
using OIDC trusted publishing (no token). Triggered on the same v* tag
push that builds the binaries: a release: published trigger would never
fire, since the release job creates the GitHub Release with the default
GITHUB_TOKEN and GitHub suppresses workflow runs from that token.

Add the repository/bugs fields required by npm provenance.
2026-10-04 21:33:18 +08:00

175 lines
5.5 KiB
YAML

name: Release
on:
pull_request:
workflow_dispatch:
push:
tags:
- "v*"
permissions:
contents: read
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false
- uses: oven-sh/setup-bun@v2
with:
bun-version: 1.4.0
- run: bun install --frozen-lockfile
- name: Verify tag version
if: startsWith(github.ref, 'refs/tags/v')
run: |
package_version="$(bun -p "require('./package.json').version")"
test "${GITHUB_REF_NAME}" = "v${package_version}"
- run: bun run lint
- run: bun test
build:
needs: validate
strategy:
fail-fast: false
matrix:
include:
- runner: ubuntu-24.04
target: bun-linux-x64
platform: linux
arch: x64
- runner: ubuntu-24.04-arm
target: bun-linux-arm64
platform: linux
arch: arm64
- runner: macos-15-intel
target: bun-darwin-x64
platform: darwin
arch: x64
- runner: macos-15
target: bun-darwin-arm64
platform: darwin
arch: arm64
runs-on: ${{ matrix.runner }}
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false
- uses: oven-sh/setup-bun@v2
with:
bun-version: 1.4.0
- run: bun install --frozen-lockfile
- name: Build standalone executable
run: >-
bun build --compile
--target=${{ matrix.target }}
--no-compile-autoload-dotenv
--no-compile-autoload-bunfig
src/index.ts
--outfile=build/routstrd
- name: Smoke test executable
run: |
package_version="$(bun -p "require('./package.json').version")"
test "$(build/routstrd --version)" = "${package_version}"
build/routstrd --help >/dev/null
- name: Package executable
run: |
package_version="$(bun -p "require('./package.json').version")"
tar -C build -czf \
"routstrd-v${package_version}-${{ matrix.platform }}-${{ matrix.arch }}.tar.gz" \
routstrd
- uses: actions/upload-artifact@v4
with:
name: routstrd-${{ matrix.platform }}-${{ matrix.arch }}
path: routstrd-*.tar.gz
if-no-files-found: error
publish-npm:
# Runs on tag push (same trigger that builds the binaries and GitHub
# Release). Not `release: published` — the `release` job below creates the
# GitHub Release with the default GITHUB_TOKEN, and GitHub suppresses
# workflow runs for events generated by that token.
#
# One-time setup on npm:
# npm trust github routstrd \
# --file release.yml \
# --repo Routstr/routstrd \
# --allow-publish
if: startsWith(github.ref, 'refs/tags/v')
needs: [validate, build]
runs-on: ubuntu-latest
timeout-minutes: 15
permissions:
contents: read
id-token: write # required for npm trusted publishing + provenance
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false
- uses: oven-sh/setup-bun@v2
with:
bun-version: 1.4.0
- uses: actions/setup-node@v4
with:
node-version: 22
# Trusted publishing requires npm >= 11.5.1; Node 22 ships npm 10.x.
- run: npm install -g npm@latest
- run: bun install --frozen-lockfile
- name: Publish to npm
# `npm publish` triggers prepublishOnly -> `bun run build`, so dist/
# is produced here. Skips gracefully if the version already exists.
run: |
version="$(bun -p "require('./package.json').version")"
if npm view "routstrd@${version}" version >/dev/null 2>&1; then
echo "::warning::routstrd@${version} is already published to npm — skipping publish"
exit 0
fi
npm publish --access public --provenance
release:
if: startsWith(github.ref, 'refs/tags/v')
needs: build
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false
- uses: actions/download-artifact@v4
with:
pattern: routstrd-*
merge-multiple: true
- name: Create checksums
run: shasum -a 256 routstrd-*.tar.gz > SHA256SUMS
- name: Serve artifacts for installer smoke test
run: |
version="${GITHUB_REF_NAME#v}"
mkdir -p "serve/v${version}"
cp "routstrd-v${version}-linux-x64.tar.gz" SHA256SUMS "serve/v${version}/"
- name: Smoke test install.sh against the built artifacts
run: |
version="${GITHUB_REF_NAME#v}"
python3 -m http.server 8137 --bind 127.0.0.1 --directory serve &
server_pid=$!
trap 'kill "${server_pid}"' EXIT
sleep 1
sh install.sh \
--version "${version}" \
--platform linux \
--arch x64 \
--dir /tmp/routstrd-install-smoke \
--download-base-url http://127.0.0.1:8137
test "$(/tmp/routstrd-install-smoke/routstrd --version)" = "${version}"
- name: Publish GitHub Release
env:
GH_TOKEN: ${{ github.token }}
run: >-
gh release create "${GITHUB_REF_NAME}"
routstrd-*.tar.gz SHA256SUMS install.sh
--repo "${GITHUB_REPOSITORY}"
--verify-tag
--generate-notes
--title "${GITHUB_REF_NAME}"