Publish to NPM #52
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 to NPM | |
| # Manual, on-demand publishing (mirrors the DxMessaging release route): dispatch this workflow | |
| # to publish the current package.json version. The publish step is re-runnable (it skips a | |
| # version already on the registry) and attaches build provenance. | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| dry_run: | |
| description: "Pack and report the version/dist-tag without publishing" | |
| type: boolean | |
| default: false | |
| concurrency: | |
| group: publish-npm | |
| cancel-in-progress: false | |
| permissions: | |
| contents: read | |
| jobs: | |
| publish: | |
| name: Publish npm package | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 15 | |
| permissions: | |
| contents: read | |
| id-token: write # required for `npm publish --provenance` | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v7 | |
| with: | |
| persist-credentials: false | |
| - name: Set up Node.js | |
| uses: actions/setup-node@v6 | |
| with: | |
| node-version: "22" | |
| registry-url: "https://registry.npmjs.org" | |
| - name: Pack and resolve version / dist-tag | |
| id: pack | |
| run: | | |
| set -euo pipefail | |
| pkg="$(jq -r '.name' package.json)" | |
| ver="$(jq -r '.version' package.json)" | |
| if [ -z "${pkg}" ] || [ "${pkg}" = "null" ] || [ -z "${ver}" ] || [ "${ver}" = "null" ]; then | |
| echo "::error::package.json is missing name or version." | |
| exit 1 | |
| fi | |
| # rc/alpha/beta/preview pre-releases publish under the "next" dist-tag; stable under "latest". | |
| if printf '%s' "${ver}" | grep -qiE '\-(rc|alpha|beta|preview)'; then | |
| npm_tag="next" | |
| else | |
| npm_tag="latest" | |
| fi | |
| package_file="$(npm pack --json | jq -r '.[0].filename')" | |
| { | |
| echo "pkg=${pkg}" | |
| echo "ver=${ver}" | |
| echo "npm_tag=${npm_tag}" | |
| echo "package_file=${package_file}" | |
| } >> "${GITHUB_OUTPUT}" | |
| echo "Prepared ${pkg}@${ver} -> dist-tag '${npm_tag}' (${package_file})." | |
| - name: Publish to npm with provenance | |
| if: ${{ inputs.dry_run == false }} | |
| env: | |
| NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} | |
| PKG: ${{ steps.pack.outputs.pkg }} | |
| VER: ${{ steps.pack.outputs.ver }} | |
| NPM_TAG: ${{ steps.pack.outputs.npm_tag }} | |
| PACKAGE_FILE: ${{ steps.pack.outputs.package_file }} | |
| run: | | |
| set -euo pipefail | |
| # Re-runnable: skip if this exact name@version is already on the registry (a prior run may | |
| # have published it before failing downstream). npm publish is otherwise irreversible. | |
| if npm view "${PKG}@${VER}" version >/dev/null 2>&1; then | |
| echo "::notice::${PKG}@${VER} is already on the registry; skipping publish." | |
| else | |
| npm publish "${PACKAGE_FILE}" --provenance --access public --tag "${NPM_TAG}" | |
| echo "::notice::Published ${PKG}@${VER} to dist-tag '${NPM_TAG}'." | |
| fi | |
| - name: Dry-run summary | |
| if: ${{ inputs.dry_run == true }} | |
| run: | | |
| echo "Dry run: would publish ${{ steps.pack.outputs.pkg }}@${{ steps.pack.outputs.ver }} to dist-tag '${{ steps.pack.outputs.npm_tag }}'." |