Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 75 additions & 5 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -1,28 +1,84 @@
name: Publish package

on:
release:
types: [published]
workflow_dispatch:

permissions: {}

jobs:
publish-npm:
name: Publish to npm (OIDC)
name: Publish release to npm (OIDC)
runs-on: ubuntu-latest
permissions:
contents: read
# Needed to create the GitHub release and its package-version tag.
contents: write
Comment thread
github-advanced-security[bot] marked this conversation as resolved.
Fixed
Comment thread
tomayac marked this conversation as resolved.
Dismissed
# Needed by npm trusted publishing to mint an OIDC token.
id-token: write
steps:
- name: Checkout repo
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0

- name: Setup environment (node + install)
uses: ./.github/actions/node-setup
with:
node-version: 24

- name: Read package metadata
id: package
shell: bash
run: |
set -euo pipefail
name="$(node -p "JSON.parse(require('node:fs').readFileSync('package.json', 'utf8')).name")"
version="$(node -p "JSON.parse(require('node:fs').readFileSync('package.json', 'utf8')).version")"

if [[ -z "${name}" || -z "${version}" ]]; then
echo "package.json must define both name and version." >&2
exit 1
fi

echo "name=${name}" >> "${GITHUB_OUTPUT}"
echo "version=${version}" >> "${GITHUB_OUTPUT}"
echo "tag_name=${version}" >> "${GITHUB_OUTPUT}"

- name: Ensure workflow is running on the default branch
env:
DEFAULT_BRANCH: ${{ github.event.repository.default_branch }}
shell: bash
run: |
set -euo pipefail

if [[ "${GITHUB_REF_TYPE}" != "branch" || "${GITHUB_REF_NAME}" != "${DEFAULT_BRANCH}" ]]; then
echo "Releases must be published from ${DEFAULT_BRANCH}; this run is using ${GITHUB_REF_NAME}." >&2
exit 1
fi

- name: Ensure package version is releasable
env:
GH_TOKEN: ${{ github.token }}
PACKAGE_NAME: ${{ steps.package.outputs.name }}
VERSION: ${{ steps.package.outputs.version }}
TAG_NAME: ${{ steps.package.outputs.tag_name }}
shell: bash
run: |
set -euo pipefail

if git ls-remote --exit-code --tags origin "refs/tags/${TAG_NAME}" >/dev/null 2>&1; then
echo "Tag ${TAG_NAME} already exists." >&2
exit 1
fi

if gh release view "${TAG_NAME}" >/dev/null 2>&1; then
echo "Release ${TAG_NAME} already exists." >&2
exit 1
fi

if npm view "${PACKAGE_NAME}@${VERSION}" version >/dev/null 2>&1; then
echo "Package ${PACKAGE_NAME}@${VERSION} is already published to npm." >&2
exit 1
fi

- name: Build and validate package
run: npm run prepublishOnly

Expand All @@ -34,4 +90,18 @@
registry-url: https://registry.npmjs.org

- name: Publish to npm
run: npm publish --provenance --access public
run: npm publish --provenance --access public --tag latest

- name: Create GitHub release
env:
GH_TOKEN: ${{ github.token }}
PACKAGE_NAME: ${{ steps.package.outputs.name }}
VERSION: ${{ steps.package.outputs.version }}
TAG_NAME: ${{ steps.package.outputs.tag_name }}
shell: bash
run: |
set -euo pipefail
gh release create "${TAG_NAME}" \
--target "${GITHUB_SHA}" \
--title "${TAG_NAME}" \
--notes "Published ${PACKAGE_NAME}@${VERSION} to npm."