Skip to content

chore: trigger release-please rerun (#78) #47

chore: trigger release-please rerun (#78)

chore: trigger release-please rerun (#78) #47

name: Release
on:
push:
branches: [main]
# Manual re-publish escape hatch: (re)test, build and publish an already-created
# release to GHPR — e.g. if this publish job failed after release-please had
# already cut the tag/release.
workflow_dispatch:
inputs:
tag:
description: 'Release tag to (re)publish, e.g. apm-v0.2.0'
required: true
type: string
# release-please opens/labels the Release PR and creates tags + GitHub Releases;
# the publish job additionally needs to write packages to GHPR. Least-privilege is
# tightened again per-job below.
permissions:
contents: write
pull-requests: write
packages: write
# Serialize release passes on main so a Release-PR merge that lands while another
# push to main is still mid-flight can never produce two concurrent publishes.
concurrency:
group: release-${{ github.ref }}
cancel-in-progress: false
jobs:
# ---------------------------------------------------------------------------
# Job A — maintain the Release PR and, when it is merged, cut the tag+Release.
# On a normal feature merge this only updates the accumulating Release PR
# (next version + CHANGELOG) and does nothing else. On a Release-PR merge it
# sets releases_created=true and emits tag_name (e.g. v0.2.0).
# ---------------------------------------------------------------------------
release-please:
runs-on: ubuntu-latest
# Only on a push to main. A manual workflow_dispatch is a publish-only re-run,
# so this job is skipped there (no Release-PR side effects).
if: github.event_name == 'push'
outputs:
releases_created: ${{ steps.release.outputs.releases_created }}
tag_name: ${{ steps.release.outputs.tag_name }}
steps:
- name: Run release-please
id: release
uses: googleapis/release-please-action@v5
with:
token: ${{ secrets.GITHUB_TOKEN }}
config-file: release-please-config.json
manifest-file: .release-please-manifest.json
# ---------------------------------------------------------------------------
# Job B — publish to GHPR, gated on a release having just been created.
#
# THE GITHUB_TOKEN GOTCHA (why this lives here and not in a separate
# `release: published` workflow): a tag/Release created by the built-in
# GITHUB_TOKEN does NOT emit events that trigger other workflow runs (GitHub's
# deliberate loop-prevention). A standalone publish.yaml keyed on
# `release: published` would therefore silently never fire. So we publish in
# THIS same run, gated on release-please's releases_created output.
# ---------------------------------------------------------------------------
publish:
needs: release-please
# !cancelled() lets this run on a manual dispatch even though release-please
# is skipped there. The tag guard below still gates it: auto-publish only when
# a release was cut, manual publish only on workflow_dispatch.
if: |
!cancelled() &&
(needs.release-please.outputs.releases_created == 'true' || github.event_name == 'workflow_dispatch')
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
env:
# Auto-release: the tag release-please just cut. Manual dispatch: the tag input.
RELEASE_TAG: ${{ needs.release-please.outputs.tag_name || inputs.tag }}
steps:
- name: Checkout release tag
uses: actions/checkout@v7
with:
ref: ${{ env.RELEASE_TAG }}
- name: Setup pnpm
uses: pnpm/action-setup@v6
- name: Setup Node.js
uses: actions/setup-node@v7
with:
# Pinned >= 22.12.0: @commitlint/cli (a devDependency installed below)
# declares engines.node ">=22.12.0"; node 20 is also EOL on runners.
node-version: '22.12.0'
cache: pnpm
registry-url: https://npm.pkg.github.com
scope: '@nais'
# Belt-and-suspenders: release-please sets package.json version == the tag it
# created, so this always passes — but it guards against a hand-edited or
# drifted version ever shipping under the wrong tag.
- name: Verify package version matches release tag
run: |
PKG_VERSION="$(node -p "require('./package.json').version")"
TAG="$RELEASE_TAG"
# Tags are 'apm-v<semver>' (release-please derives the component from the
# package name). Strip the component prefix and the leading 'v' to get the
# bare version; also tolerate a plain 'v<semver>' tag.
EXPECTED="${TAG#apm-}"
EXPECTED="${EXPECTED#v}"
if [ "$PKG_VERSION" != "$EXPECTED" ]; then
echo "::error::package.json version ($PKG_VERSION) does not match release tag $TAG (expected version $EXPECTED)."
exit 1
fi
echo "package.json version $PKG_VERSION matches release tag $TAG"
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Test
run: pnpm test
- name: Build
run: pnpm build
# NOTE ON npm PROVENANCE (--provenance): intentionally OMITTED, and we do not
# request `id-token: write`. npm build provenance/attestations are a public-npm
# (registry.npmjs.org) feature — the CLI uploads a Sigstore bundle to that
# registry's attestation API. GitHub Package Registry (npm.pkg.github.com) does
# not implement that API, so `--provenance` here would produce nothing
# verifiable. Re-add `id-token: write` + `--provenance` only if @nais/apm ever
# moves to npmjs.org. For GHPR-native attestation, use
# actions/attest-build-provenance instead (separate mechanism).
#
# Same-org publish: secrets.GITHUB_TOKEN can publish @nais/apm to the nais org's
# GHPR, so no PAT is needed.
- name: Publish to GitHub Package Registry
run: pnpm publish --no-git-checks
env:
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}