Attach npm provenance only when the repository is public #3
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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 }} |