Skip to content

fix: keep multi-line interpolations from reporting false errors (#36) #3

fix: keep multi-line interpolations from reporting false errors (#36)

fix: keep multi-line interpolations from reporting false errors (#36) #3

Workflow file for this run

name: Release
on:
push:
branches:
- main
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
jobs:
verify:
runs-on: ubuntu-24.04
timeout-minutes: 20
permissions:
contents: read
steps:
- name: Checkout
uses: actions/checkout@v7
with:
persist-credentials: false
- uses: ./.github/actions/setup
# The same gate as a local `yarn verify`: formatting, lint, typecheck, unit, scaling, the
# packed artifact, e2e on the default TypeScript, and the package API and contents checks. A
# regression any of them catches never reaches the release or prerelease job below, both of
# which wait on this job (`needs: verify`) instead of running it again themselves.
- name: Verify
run: yarn verify
release:
needs: verify
runs-on: ubuntu-24.04
timeout-minutes: 20
permissions:
contents: write
pull-requests: write
id-token: write
steps:
- name: Checkout
uses: actions/checkout@v7
with:
# Full history: scripts/changelog.cjs asks git which commits touched each changeset file,
# and a shallow checkout's tip commit has no parent, which reads as having added every
# file in the tree and credits whoever pushed last instead of whoever wrote the change.
fetch-depth: 0
# Safe with changesets/action's default push mode (push-with-git-cli: false, unset here):
# it pushes the version branch and any release tags through its own Octokit client,
# authenticated by the github-token input, not this checkout's persisted git credential.
persist-credentials: false
# Sets up Node.js without a registry-url: nothing in this job runs npm. @changesets/cli
# publishes through Yarn (package.json packageManager), and Yarn never reads the .npmrc
# that registry-url would write; it takes the publish registry from package.json
# publishConfig.
- uses: ./.github/actions/setup
- name: Create Release Pull Request or Publish
id: changesets
# Pinned to a commit, not a tag: this action can push commits and publish the package.
# v2.1.2, 2026-09-07 (github.com/changesets/action, "development branch ... compatible
# with Changesets v3"). The v1 line only supports Changesets v2 and uses different
# (camelCase) input names; this repository's @changesets/cli is 3.x.
uses: changesets/action@ae32849d5ba541f9ae29e40e22a623bc13562f51 # v2.1.2
with:
create-github-releases: true
publish-script: yarn changeset-publish
version-script: yarn changeset-version
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# No NPM_TOKEN: publishing relies on npm trusted publishing (OIDC), configured on
# npmjs.com for this package against this repository and this workflow file (see
# docs/maintenance.md, "Releases"). `yarn npm publish` (invoked by `changeset-publish`
# through @changesets/cli 3.x's own package-manager detection) exchanges the id-token
# permission above for a short-lived npm token on its own whenever it runs under
# GitHub Actions. Yarn 4.10.0 added that exchange (yarnpkg/berry#6898) and 4.10.3
# fixed it for scoped packages such as this one (#6911), so 4.10.3 is the floor: any
# package.json packageManager pin at or above it keeps OIDC publishing working.
# Yarn's npmPublishProvenance setting, read from its YARN_-prefixed environment form:
# `yarn npm publish` signs a provenance statement linking the published tarball to this
# workflow run, through the same id-token permission. Yarn builds that statement before
# it contacts the registry and has no fallback, so publishing requires the id-token:
# write permission above and a runner that reaches Sigstore's Fulcio
# (https://fulcio.sigstore.dev) and Rekor (https://rekor.sigstore.dev). When either is
# down, the publish fails with nothing published; re-run this job once Sigstore recovers
# (docs/maintenance.md, "Releases").
YARN_NPM_PUBLISH_PROVENANCE: 'true'
prerelease:
needs: verify
runs-on: ubuntu-24.04
timeout-minutes: 20
permissions:
contents: write
id-token: write
steps:
- name: Checkout
uses: actions/checkout@v7
with:
# Full history: scripts/changelog.cjs, invoked by `changeset version` below, asks git
# which commits touched each changeset file (same reason as the release job's checkout).
fetch-depth: 0
# Left at the default (true): unlike the release job, which lets changesets/action push
# through its own Octokit client, this job pushes the prerelease tag with a plain `git
# push`, which needs the token actions/checkout persists into the local git config.
- uses: ./.github/actions/setup
# Every push to main runs this job, including the one that merges the "Version Packages"
# pull request; that merge consumes every pending changeset, so every step below is gated on
# this check and the job no-ops once there is nothing left to snapshot or publish.
- name: Check for pending changesets
id: changesets
run: |
shopt -s nullglob
count=0
for f in .changeset/*.md; do
[ "$(basename "$f")" = "README.md" ] && continue
count=$((count + 1))
done
echo "has_pending=$([ "$count" -gt 0 ] && echo true || echo false)" >> "$GITHUB_OUTPUT"
- name: Configure git identity
if: steps.changesets.outputs.has_pending == 'true'
run: |
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
# Snapshot version bump, in place and never committed: .changeset/config.json's `snapshot`
# block (useCalculatedVersion, prereleaseTemplate) turns this into a calculated version like
# 1.1.0-prerelease-20260927190000 instead of the un-configured default, 0.0.0-prerelease-<id>.
# This also rewrites CHANGELOG.md through the same scripts/changelog.cjs generator an
# ordinary `changeset version` uses, which scripts/prerelease-notes.ts reads below.
- name: Snapshot version bump
id: version
if: steps.changesets.outputs.has_pending == 'true'
run: |
yarn changeset-version --snapshot prerelease
echo "name=$(node -p "require('./package.json').name")" >> "$GITHUB_OUTPUT"
echo "version=$(node -p "require('./package.json').version")" >> "$GITHUB_OUTPUT"
- name: Publish to npm test tag
if: steps.changesets.outputs.has_pending == 'true'
# No git tag from changesets (--no-git-tag): the next step creates one itself, annotated
# and named after the snapshot version, once the publish above has actually succeeded.
run: |
yarn changeset-publish --tag test --no-git-tag
echo "Published ${{ steps.version.outputs.name }}@${{ steps.version.outputs.version }} to the npm \`test\` dist-tag." >> "$GITHUB_STEP_SUMMARY"
env:
# Same OIDC-to-npm-token exchange and provenance signing as the release job's publish
# step; see the comment on that step for the full mechanism and its requirements.
YARN_NPM_PUBLISH_PROVENANCE: 'true'
- name: Create git tag and GitHub prerelease
if: steps.changesets.outputs.has_pending == 'true'
env:
GH_TOKEN: ${{ github.token }}
run: |
ref="${{ steps.version.outputs.name }}@${{ steps.version.outputs.version }}"
node --experimental-strip-types scripts/prerelease-notes.ts > "$RUNNER_TEMP/prerelease-notes.md"
git tag -a "$ref" -m "$ref"
git push origin "refs/tags/$ref"
gh release create "$ref" --prerelease --title "$ref" --notes-file "$RUNNER_TEMP/prerelease-notes.md"