Skip to content

Attach npm provenance only when the repository is public #3

Attach npm provenance only when the repository is public

Attach npm provenance only when the repository is public #3

Workflow file for this run

name: Publish
# Publishes to npm. Provenance attestation (OIDC) is added when the repository
# is public — npm cannot mint it from a private source.
# Requires either npm Trusted Publishing configured for
# SkyLink-API/SkyLink-API-TypeScript-SDK, or an NPM_ACCESS_TOKEN repository secret
# (automation token) as a fallback.
#
# Every push to main lints, tests and builds; when package.json holds a version
# that is not on npm yet, it is published. Pushing a `v*` tag still works and
# additionally asserts the tag matches the package version.
on:
push:
branches: [main]
tags: ["v*"]
workflow_dispatch:
permissions:
contents: read
concurrency:
group: publish
cancel-in-progress: false
jobs:
publish:
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: "22.x"
cache: npm
registry-url: "https://registry.npmjs.org"
- run: npm ci
- name: Verify the tag matches the package version
if: startsWith(github.ref, 'refs/tags/')
run: |
TAG="${GITHUB_REF_NAME#v}"
VERSION=$(node -p "require('./package.json').version")
echo "tag=$TAG package=$VERSION"
if [ "$TAG" != "$VERSION" ]; then
echo "::error::Tag v$TAG does not match package version $VERSION"
exit 1
fi
- name: Verify src/version.ts matches package.json
run: |
PKG=$(node -p "require('./package.json').version")
SRC=$(node -p "require('fs').readFileSync('src/version.ts','utf8').match(/\"([^\"]+)\"/)[1]")
if [ "$PKG" != "$SRC" ]; then
echo "::error::src/version.ts ($SRC) does not match package.json ($PKG)"
exit 1
fi
- run: npm run lint
- run: npm run typecheck
- run: npm test
- run: npm run build
- name: Check whether this version is already on npm
id: npm
run: |
VERSION=$(node -p "require('./package.json').version")
if npm view "skylink-api@$VERSION" version >/dev/null 2>&1; then
echo "unpublished=false" >> "$GITHUB_OUTPUT"
echo "skylink-api@$VERSION already exists on npm — publish will be skipped."
else
echo "unpublished=true" >> "$GITHUB_OUTPUT"
echo "skylink-api@$VERSION is not on npm yet — it will be published."
fi
- name: Publish to npm
if: steps.npm.outputs.unpublished == 'true'
# npm refuses to mint provenance from a private repository. The flag is
# therefore added only when the source is public, so making the repo
# public is the single action needed to get attestation back — nothing
# here has to change. An unknown visibility is treated as private, which
# costs the attestation rather than the release.
run: |
if [ "${{ github.event.repository.visibility }}" = "public" ]; then
npm publish --provenance --access public
else
echo "::warning::Repository is not public — publishing without provenance."
npm publish --access public
fi
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_ACCESS_TOKEN }}