Skip to content

publish

publish #57

Workflow file for this run

# Publishes all @agentruntimecontrolprotocol/* workspace packages to npm and
# GitHub Packages after the `test` workflow succeeds on main, skipping any
# package whose local version is already on the target registry. The workspace
# root (package.json `"private": true`) is never published.
#
# Required repo configuration:
# - npm Trusted Publisher must be configured on every
# @agentruntimecontrolprotocol/* package (npmjs.com → package → Settings →
# Trusted Publishers) pointing at:
# repository: agentruntimecontrolprotocol/typescript-sdk
# workflow: publish.yml
# environment: (none)
# With trusted publishers in place the workflow authenticates to npm via
# the OIDC token GitHub Actions mints from `id-token: write`; no NPM_TOKEN
# secret is needed.
# - The built-in GITHUB_TOKEN is used for GitHub Packages; the job grants
# `packages: write` below.
# - `id-token: write` is required for both npm publish (trusted publisher
# handshake) and npm provenance (sigstore attestation).
name: publish
on:
workflow_run:
workflows: ["test"]
types: [completed]
branches: [main]
workflow_dispatch:
concurrency:
group: publish-${{ github.ref }}
cancel-in-progress: false
jobs:
publish:
name: publish to npm + GitHub Packages
runs-on: ubuntu-latest
# Only run if the test workflow succeeded (or this was manually dispatched).
if: >
github.event_name == 'workflow_dispatch' ||
(github.event.workflow_run.conclusion == 'success' &&
github.event.workflow_run.head_branch == 'main')
permissions:
contents: read
id-token: write # required for npm provenance
packages: write # required for GitHub Packages publish
steps:
- name: Checkout
uses: actions/checkout@v6
with:
# For workflow_run, check out the exact commit that passed CI.
ref: ${{ github.event.workflow_run.head_sha || github.sha }}
fetch-depth: 1
- name: Setup pnpm
# pnpm/action-setup v4.0.0
uses: pnpm/action-setup@0e279bb959325dab635dd2c09392533439d90093 # v4.0.0
with:
version: 9.15.0
run_install: false
- name: Setup Node.js
# No registry-url/scope: that would cause setup-node to write an
# `_authToken=${NODE_AUTH_TOKEN}` line into ~/.npmrc, which then
# short-circuits the trusted-publisher OIDC handshake when no token is
# present. The npm publish step passes --registry explicitly instead.
uses: actions/setup-node@v6
with:
node-version: "22"
cache: "pnpm"
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Build
run: pnpm run build
- name: Collect publishable packages
id: collect
run: |
set -euo pipefail
# Walk packages/ to depth 3 so packages/middleware/<name>/package.json
# is included alongside packages/<name>/package.json.
{
find packages -maxdepth 3 -name "package.json" \
-not -path "*/node_modules/*" \
-not -path "*/dist/*" \
| while IFS= read -r manifest; do
dir=$(dirname "$manifest")
private=$(node -p "require('./$manifest').private || false")
[ "$private" = "false" ] && echo "$dir"
done
} > .publish-dirs.txt
echo "Packages to consider:"
cat .publish-dirs.txt
- name: Publish to npm
# No NODE_AUTH_TOKEN: npm CLI uses the OIDC token from `id-token: write`
# against the npmjs.com trusted-publisher configured for each package.
run: |
set -euo pipefail
published=0
skipped=0
while IFS= read -r dir; do
[ -z "$dir" ] && continue
name=$(node -p "require('./$dir/package.json').name")
local_ver=$(node -p "require('./$dir/package.json').version")
# npm view exits non-zero if the package was never published.
npm_ver=$(npm view "$name" version --registry=https://registry.npmjs.org 2>/dev/null || echo "")
if [ "$local_ver" = "$npm_ver" ]; then
echo " [skip] $name@$local_ver — already on npm"
skipped=$((skipped + 1))
else
echo "[publish] $name@$local_ver (npm has '${npm_ver:-nothing}')"
# publishConfig in each package.json carries access=public and
# provenance=true; --provenance here is the CLI counterpart that
# activates the OIDC token flow in GitHub Actions.
(cd "$dir" && npm publish --provenance --registry=https://registry.npmjs.org)
published=$((published + 1))
fi
done < .publish-dirs.txt
echo ""
echo "npm — published: $published skipped: $skipped"
- name: Setup Node.js (GitHub Packages registry)
uses: actions/setup-node@v6
with:
node-version: "22"
registry-url: "https://npm.pkg.github.com"
scope: "@agentruntimecontrolprotocol"
- name: Publish to GitHub Packages
env:
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# GitHub Packages doesn't participate in the sigstore provenance
# flow; override the publishConfig.provenance=true set per-package.
NPM_CONFIG_PROVENANCE: "false"
run: |
set -euo pipefail
published=0
skipped=0
while IFS= read -r dir; do
[ -z "$dir" ] && continue
name=$(node -p "require('./$dir/package.json').name")
local_ver=$(node -p "require('./$dir/package.json').version")
gh_ver=$(npm view "$name" version --registry=https://npm.pkg.github.com 2>/dev/null || echo "")
if [ "$local_ver" = "$gh_ver" ]; then
echo " [skip] $name@$local_ver — already on GitHub Packages"
skipped=$((skipped + 1))
else
echo "[publish] $name@$local_ver (GitHub Packages has '${gh_ver:-nothing}')"
(cd "$dir" && npm publish --registry=https://npm.pkg.github.com)
published=$((published + 1))
fi
done < .publish-dirs.txt
echo ""
echo "GitHub Packages — published: $published skipped: $skipped"