# Publishes the packages to npm on a version tag, and copies them to the # pdsjs.dev PDS's own npm registry (@pdsjs/npm). changeset publish takes # every package whose version is not on npm, so a package releases for the # first time with no changeset at all. on: push: {refs: [refs/tags/v*]} superseded: finish image: node:22-trixie cache: [/root/.local/share/pnpm/store, /root/.cache/node/corepack] runners: [ci.knotless.dev] secrets: [NPM_TOKEN, PDSJS_SITE_TOKEN] env: COREPACK_ENABLE_DOWNLOAD_PROMPT: "0" PDS_HOST: pds.pdsjs.dev steps: - name: check credentials run: | if [ -z "${NPM_TOKEN:-}" ]; then echo "NPM_TOKEN is not granted, so this tag would publish nothing." echo "Seal it to ci.knotless.dev with knotless secret. It is an npm automation token with publish rights for the @pdsjs scope." exit 1 fi # A tag that does not name the versioned state would mislabel every # package, and changeset publish cannot be taken back. - name: check the tag names the versioned state run: | tag="${KNOTLESS_RUN_REF#refs/tags/}" core=$(node -p 'require("./packages/core/package.json").version') if [ "v$core" != "$tag" ]; then echo "the tag is $tag but @pdsjs/core is $core" exit 1 fi pending=$(ls .changeset/*.md 2>/dev/null | grep -cv README || true) if [ "$pending" != "0" ]; then echo "$pending changesets are pending. Run version-packages first." exit 1 fi - name: publish to npm run: | corepack enable pnpm install --frozen-lockfile pnpm run build { echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" echo "git-checks=false" } > .npmrc pnpm exec changeset publish --no-git-tag # Every public package goes up at its current version, less the versions # the PDS holds, so a run after a gap fills it in. Like a mirror, it never # fails a release on its own. - name: publish to the PDS run: | if [ -z "${PDSJS_SITE_TOKEN:-}" ]; then echo "PDSJS_SITE_TOKEN is not granted, so the PDS copy is skipped" exit 0 fi registry="https://$PDS_HOST/npm/" status=$(node -e "fetch('$registry-/ping').then((r) => console.log(r.status)).catch(() => console.log(0))") if [ "$status" != "200" ]; then echo "$registry answered $status to the ping, so the PDS registry is off and this step skips" exit 0 fi echo "//$PDS_HOST/npm/:_authToken=${PDSJS_SITE_TOKEN}" >> .npmrc for dir in packages/*/; do name=$(node -p "require('./$dir/package.json').name" 2>/dev/null) || continue private=$(node -p "Boolean(require('./$dir/package.json').private)") version=$(node -p "require('./$dir/package.json').version") [ "$private" = "true" ] && continue if npm view "$name@$version" version --registry "$registry" >/dev/null 2>&1; then echo "$name@$version is on the PDS already" continue fi # pnpm rewrites workspace:* ranges as it packs, as changesets does. if (cd "$dir" && pnpm publish --registry "$registry" --no-git-checks --access public); then echo "published $name@$version to the PDS" else echo "the PDS refused $name@$version; the release stands on npmjs" fi done