From 06bf919f73f6940d437d157672e01c1a5fba8754 Mon Sep 17 00:00:00 2001 From: Will Washburn Date: Tue, 16 Jun 2026 03:46:38 -0400 Subject: [PATCH] ci(publish): publish @agent-relay/fleet in the release pipeline The root CLI depends on @agent-relay/fleet, so publish-main's "Wait for CLI internal dependencies" loop blocks on @agent-relay/fleet@. But fleet was never wired into the publish workflow, so on the all-package release it is never published and the wait times out: Timed out waiting for CLI @agent-relay/* dependencies: - @agent-relay/fleet@8.8.0 Add a publish-fleet job that runs after publish-harnesses (fleet pins @agent-relay/{harnesses,harness-driver,sdk} by exact version, so it must land after harnesses to avoid an install-resolution race), and add it to publish-main's needs/if so the root package is only published once fleet is on the registry. Note: @agent-relay/fleet@8.7.2 was a manual token publish (no provenance), so its npm Trusted Publisher must be configured for OIDC `npm publish --provenance` to succeed on the next release. Co-Authored-By: Claude Opus 4.8 (1M context) --- .github/workflows/publish.yml | 52 ++++++++++++++++++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 534b1e40c..75d532059 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -1021,6 +1021,55 @@ jobs: fi npm publish --access public --provenance --tag ${{ github.event.inputs.tag }} --ignore-scripts + # Publish @agent-relay/fleet after @agent-relay/harnesses lands on the + # registry. fleet pins @agent-relay/{harnesses,harness-driver,sdk} by exact + # version, so publishing it before harnesses exists would leave a window where + # `npm install @agent-relay/fleet@` cannot resolve its dependencies — the + # same install race the broker/sdk/harnesses ordering above is built to avoid. + # The root CLI depends on @agent-relay/fleet, so this must finish before + # publish-main (wired via publish-main's needs). + publish-fleet: + name: Publish fleet + needs: [build, publish-harnesses] + runs-on: ubuntu-latest + if: github.event.inputs.package == 'all' + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '22.14.0' + registry-url: 'https://registry.npmjs.org' + + - name: Download build artifacts + uses: actions/download-artifact@v4 + with: + name: build-output + path: . + + - name: Update npm for OIDC support + run: npm install -g npm@latest + + - name: Dry run check + if: github.event.inputs.dry_run == 'true' + working-directory: packages/fleet + run: npm publish --dry-run --access public --tag ${{ github.event.inputs.tag }} --ignore-scripts + + - name: Publish to NPM + if: github.event.inputs.dry_run != 'true' + working-directory: packages/fleet + run: | + set -euo pipefail + PKG_NAME=$(node -p "require('./package.json').name") + PKG_VERSION=$(node -p "require('./package.json').version") + if npm view "${PKG_NAME}@${PKG_VERSION}" version >/dev/null 2>&1; then + echo "${PKG_NAME}@${PKG_VERSION} already exists on npm; skipping publish" + exit 0 + fi + npm publish --access public --provenance --tag ${{ github.event.inputs.tag }} --ignore-scripts + # package=main publishes only the root `agent-relay` tarball, but that # tarball pins several @agent-relay/* runtime dependencies to the freshly # bumped version. Publish those direct deps first so a main-only release @@ -1443,7 +1492,7 @@ jobs: # Publish main package publish-main: name: Publish Main Package - needs: [build, verify-binaries, publish-packages, publish-main-runtime-deps] + needs: [build, verify-binaries, publish-packages, publish-fleet, publish-main-runtime-deps] runs-on: ubuntu-latest outputs: published: ${{ steps.publish_root.outputs.published }} @@ -1453,6 +1502,7 @@ jobs: needs.build.result == 'success' && (needs.verify-binaries.result == 'success' || (needs.verify-binaries.result == 'skipped' && github.event.inputs.package == 'cli-prerelease')) && (needs.publish-packages.result == 'success' || needs.publish-packages.result == 'skipped') && + (needs.publish-fleet.result == 'success' || needs.publish-fleet.result == 'skipped') && (needs.publish-main-runtime-deps.result == 'success' || needs.publish-main-runtime-deps.result == 'skipped') steps: