Skip to content

fix(ts,py,rust): refresh web-fallback sessions with the correct key (… #14

fix(ts,py,rust): refresh web-fallback sessions with the correct key (…

fix(ts,py,rust): refresh web-fallback sessions with the correct key (… #14

Workflow file for this run

name: release
# Per-language tags so the three packages version independently
# (majors are aligned by human discipline; minor/patch drift freely):
#
# ts-vX.Y.Z -> npm (TypeScript), guard checks packages/typescript/package.json
# py-vX.Y.Z -> PyPI (Python), guard checks packages/python/pyproject.toml
# rs-vX.Y.Z -> crates.io (Rust), guard checks packages/rust/Cargo.toml
# vX.Y.Z -> Go module version (a plain semver tag is what
# `go get .../v2@vX.Y.Z` resolves; Go tooling cannot
# use a prefixed tag) — publishes only a GitHub Release.
#
# Every tag also gets a GitHub Release. A hyphen in the version part
# (ts-v2.1.0-rc.1) marks a pre-release: npm goes to the `next` dist-tag
# and the Release is flagged pre-release, so `npm install` / `pip
# install` keep resolving the last stable.
#
# npm uses OIDC trusted publishing — no token. Trusted Publisher on the
# npm package: repository ekkx/yaylib, workflow release.yml.
#
# Required repository secrets:
# PYPI_API_TOKEN PyPI API token (scoped to the project)
# CARGO_REGISTRY_TOKEN crates.io API token (scoped to publish-new + publish-update)
on:
push:
tags: ["v*", "ts-v*", "py-v*", "rs-v*"]
permissions:
contents: read
jobs:
guard:
runs-on: ubuntu-latest
outputs:
lang: ${{ steps.v.outputs.lang }}
version: ${{ steps.v.outputs.version }}
prerelease: ${{ steps.v.outputs.prerelease }}
steps:
- uses: actions/checkout@v4
- id: v
name: Resolve language + version from the tag
run: |
set -euo pipefail
ref="$GITHUB_REF_NAME"
case "$ref" in
ts-v*) lang=ts; ver="${ref#ts-v}" ;;
py-v*) lang=py; ver="${ref#py-v}" ;;
rs-v*) lang=rs; ver="${ref#rs-v}" ;;
v*) lang=go; ver="${ref#v}" ;;
*) echo "::error::unrecognized tag $ref"; exit 1 ;;
esac
echo "tag=$ref lang=$lang version=$ver"
if [ "$lang" = ts ]; then
npm_v="$(node -p "require('./packages/typescript/package.json').version")"
if [ "$npm_v" != "$ver" ]; then
echo "::error::package.json version ($npm_v) != tag ($ver)"; exit 1
fi
elif [ "$lang" = py ]; then
py_v="$(grep -E '^version = ' packages/python/pyproject.toml | head -1 | sed -E 's/.*"([^"]+)".*/\1/')"
if [ "$py_v" != "$ver" ]; then
echo "::error::pyproject version ($py_v) != tag ($ver)"; exit 1
fi
elif [ "$lang" = rs ]; then
rs_v="$(grep -E '^version = ' packages/rust/Cargo.toml | head -1 | sed -E 's/.*"([^"]+)".*/\1/')"
if [ "$rs_v" != "$ver" ]; then
echo "::error::Cargo.toml version ($rs_v) != tag ($ver)"; exit 1
fi
fi
case "$ver" in
*-*) echo "prerelease=true" >> "$GITHUB_OUTPUT" ;;
*) echo "prerelease=false" >> "$GITHUB_OUTPUT" ;;
esac
echo "lang=$lang" >> "$GITHUB_OUTPUT"
echo "version=$ver" >> "$GITHUB_OUTPUT"
npm:
needs: guard
if: needs.guard.outputs.lang == 'ts'
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write # OIDC trusted publishing
defaults:
run:
working-directory: packages/typescript
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
# Node 24 bundles npm 11.x, which supports OIDC trusted
# publishing (>= 11.5.1) without an in-place npm self-upgrade
# (that upgrade is flaky and corrupts the global npm).
node-version: 24
registry-url: "https://registry.npmjs.org"
- run: npm --version
- run: npm ci
- run: npm run build
- name: Publish
run: |
if [ "${{ needs.guard.outputs.prerelease }}" = "true" ]; then
npm publish --provenance --access public --tag next
else
npm publish --provenance --access public
fi
pypi:
needs: guard
if: needs.guard.outputs.lang == 'py'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Build
run: |
python -m pip install --upgrade build
python -m build packages/python --outdir dist
- name: Publish
uses: pypa/gh-action-pypi-publish@release/v1
with:
password: ${{ secrets.PYPI_API_TOKEN }}
packages-dir: dist
skip-existing: true
crates:
needs: guard
if: needs.guard.outputs.lang == 'rs'
runs-on: ubuntu-latest
defaults:
run:
working-directory: packages/rust
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- name: Test
run: cargo test
- name: Publish
run: cargo publish
env:
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
github-release:
needs: [guard, npm, pypi, crates]
# npm / pypi / crates are skipped for the other languages; only a real
# failure of the relevant one should block the Release.
if: ${{ always() && needs.guard.result == 'success' && needs.npm.result != 'failure' && needs.pypi.result != 'failure' && needs.crates.result != 'failure' }}
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v4
- name: Create the release
env:
GH_TOKEN: ${{ github.token }}
run: |
flag=""
if [ "${{ needs.guard.outputs.prerelease }}" = "true" ]; then
flag="--prerelease"
fi
# CHANGELOG sections are keyed by plain version (## vX.Y.Z),
# shared by the ts-/py- tags for the same version.
notes_tag="v${{ needs.guard.outputs.version }}"
notes="--generate-notes"
if [ -f CHANGELOG.md ]; then
awk -v ver="$notes_tag" \
'$0=="## "ver{f=1;next} f&&/^## /{exit} f{print}' \
CHANGELOG.md > /tmp/relnotes.md
if [ -s /tmp/relnotes.md ]; then
notes="--notes-file /tmp/relnotes.md --generate-notes"
fi
fi
gh release create "$GITHUB_REF_NAME" \
--title "$GITHUB_REF_NAME" \
$notes $flag