Skip to content

publish

publish #53

Workflow file for this run

# Publishes all @agentruntimecontrolprotocol/* workspace packages to npm after the `test` workflow
# succeeds on main, skipping any package whose local version is already on the
# registry. The workspace root (package.json `"private": true`) is never
# published.
#
# Required repo configuration:
# - Secret: NPM_TOKEN (npm automation token with publish rights to the
# @agentruntimecontrolprotocol scope — create at npmjs.com → Access Tokens → Automation)
# - Settings > Actions > General > Workflow permissions: "Read and write"
# is NOT required; this workflow only needs id-token:write (set below)
# for npm provenance.
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
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
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
uses: actions/setup-node@v6
with:
node-version: "22"
cache: "pnpm"
registry-url: "https://registry.npmjs.org"
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Build
run: pnpm run build
- name: Publish workspace packages
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
run: |
set -euo pipefail
# Collect every publishable (non-private) package directory by
# scanning packages/ and packages/middleware/*.
mapfile -t PACKAGE_DIRS < <(
find packages -maxdepth 2 -name "package.json" \
-not -path "*/node_modules/*" \
| while IFS= read -r manifest; do
dir=$(dirname "$manifest")
private=$(node -p "require('./$manifest').private || false")
[ "$private" = "false" ] && echo "$dir"
done
)
published_count=0
skipped_count=0
for dir in "${PACKAGE_DIRS[@]}"; do
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 2>/dev/null || echo "")
if [ "$local_ver" = "$npm_ver" ]; then
echo " [skip] $name@$local_ver — already on npm"
skipped_count=$((skipped_count + 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)
published_count=$((published_count + 1))
fi
done
echo ""
echo "Done — published: $published_count skipped: $skipped_count"