Skip to content

Commit a14f65f

Browse files
willwashburnclaude
andauthored
ci(publish): publish @agent-relay/harnesses on release (#1049)
* ci(publish): publish @agent-relay/harnesses on release @agent-relay/harnesses was set up as a public package (no private flag, publishConfig.access public, versioned in lockstep) but was never wired into the publish workflow, so it never reached npm. External SDK consumers (e.g. relayflows) need it for the prebuilt PTY harnesses and the definePtyHarness/createHuman author helpers. Add a publish-harnesses job to the package=all path. It runs after publish-packages — where its exact-version workspace deps (@agent-relay/sdk, @agent-relay/harness-driver) land on the registry — so an external `npm install @agent-relay/harnesses@<v>` can always resolve its dependencies. Mirrors the existing provenance + skip-if-exists publish pattern. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * ci(publish): gate release on publish-harnesses; trim changelog Address PR review: publish-harnesses ran outside the release gate, so a tag/release could be cut even if harness publishing failed. - create-release now needs publish-harnesses and its `if` requires the job to not have failed. It tolerates `skipped` so package=main releases (where publish-harnesses does not run) are not blocked. - summary job lists the harness publish result. - Trim the changelog bullet to impact-first per the repo changelog rule. Leaving the new job's actions on @v4 tags to match the rest of the workflow (the repo uses tag refs throughout; SHA-pinning would be inconsistent and is not the enforced policy here). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent d8d00e2 commit a14f65f

2 files changed

Lines changed: 58 additions & 1 deletion

File tree

.github/workflows/publish.yml

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -964,6 +964,55 @@ jobs:
964964
fi
965965
npm publish --access public --provenance --tag ${{ github.event.inputs.tag }} --ignore-scripts
966966
967+
# Publish @agent-relay/harnesses after the publish-packages matrix, which is
968+
# where its exact-version workspace deps (@agent-relay/sdk and
969+
# @agent-relay/harness-driver) land on the registry. Publishing harnesses
970+
# before those exist would leave a window where
971+
# `npm install @agent-relay/harnesses@<v>` cannot resolve its dependencies —
972+
# the same install race the broker/sdk ordering above is built to avoid.
973+
publish-harnesses:
974+
name: Publish @agent-relay/harnesses
975+
needs: [build, publish-packages]
976+
runs-on: ubuntu-latest
977+
if: github.event.inputs.package == 'all'
978+
979+
steps:
980+
- name: Checkout code
981+
uses: actions/checkout@v4
982+
983+
- name: Setup Node.js
984+
uses: actions/setup-node@v4
985+
with:
986+
node-version: '22.14.0'
987+
registry-url: 'https://registry.npmjs.org'
988+
989+
- name: Download build artifacts
990+
uses: actions/download-artifact@v4
991+
with:
992+
name: build-output
993+
path: .
994+
995+
- name: Update npm for OIDC support
996+
run: npm install -g npm@latest
997+
998+
- name: Dry run check
999+
if: github.event.inputs.dry_run == 'true'
1000+
working-directory: packages/harnesses
1001+
run: npm publish --dry-run --access public --tag ${{ github.event.inputs.tag }} --ignore-scripts
1002+
1003+
- name: Publish to NPM
1004+
if: github.event.inputs.dry_run != 'true'
1005+
working-directory: packages/harnesses
1006+
run: |
1007+
set -euo pipefail
1008+
PKG_NAME=$(node -p "require('./package.json').name")
1009+
PKG_VERSION=$(node -p "require('./package.json').version")
1010+
if npm view "${PKG_NAME}@${PKG_VERSION}" version >/dev/null 2>&1; then
1011+
echo "${PKG_NAME}@${PKG_VERSION} already exists on npm; skipping publish"
1012+
exit 0
1013+
fi
1014+
npm publish --access public --provenance --tag ${{ github.event.inputs.tag }} --ignore-scripts
1015+
9671016
# package=main publishes only the root `agent-relay` tarball, but that
9681017
# tarball pins several @agent-relay/* runtime dependencies to the freshly
9691018
# bumped version. Publish those direct deps first so a main-only release
@@ -1528,13 +1577,18 @@ jobs:
15281577
# Create git tag and release
15291578
create-release:
15301579
name: Create Release
1531-
needs: [build, build-broker, build-standalone, verify-binaries, publish-main]
1580+
needs: [build, build-broker, build-standalone, verify-binaries, publish-main, publish-harnesses]
15321581
runs-on: ubuntu-latest
1582+
# publish-harnesses only runs for package=all; for a package=main release it
1583+
# is skipped, which must not block the tag. Gate on "not failed" rather than
1584+
# "succeeded" so a real harness publish failure stops the release but a
1585+
# skipped one does not.
15331586
if: |
15341587
always() &&
15351588
github.event.inputs.package != 'cli-prerelease' &&
15361589
github.event.inputs.dry_run != 'true' &&
15371590
needs.publish-main.result == 'success' &&
1591+
(needs.publish-harnesses.result == 'success' || needs.publish-harnesses.result == 'skipped') &&
15381592
needs.publish-main.outputs.published == 'true'
15391593
15401594
steps:
@@ -2011,6 +2065,7 @@ jobs:
20112065
publish-sdk-internal-deps,
20122066
publish-broker-packages,
20132067
publish-packages,
2068+
publish-harnesses,
20142069
publish-brand-only,
20152070
publish-sdk-py,
20162071
publish-main,
@@ -2053,6 +2108,7 @@ jobs:
20532108
echo "| Publish SDK Internal Deps | ${{ needs.publish-sdk-internal-deps.result == 'success' && '✅' || (needs.publish-sdk-internal-deps.result == 'skipped' && '⏭️' || '❌') }} ${{ needs.publish-sdk-internal-deps.result }} |" >> $GITHUB_STEP_SUMMARY
20542109
echo "| Publish Broker Packages | ${{ needs.publish-broker-packages.result == 'success' && '✅' || (needs.publish-broker-packages.result == 'skipped' && '⏭️' || '❌') }} ${{ needs.publish-broker-packages.result }} |" >> $GITHUB_STEP_SUMMARY
20552110
echo "| Publish Packages | ${{ needs.publish-packages.result == 'success' && '✅' || (needs.publish-packages.result == 'skipped' && '⏭️' || '❌') }} ${{ needs.publish-packages.result }} |" >> $GITHUB_STEP_SUMMARY
2111+
echo "| Publish Harnesses | ${{ needs.publish-harnesses.result == 'success' && '✅' || (needs.publish-harnesses.result == 'skipped' && '⏭️' || '❌') }} ${{ needs.publish-harnesses.result }} |" >> $GITHUB_STEP_SUMMARY
20562112
echo "| Publish Brand | ${{ needs.publish-brand-only.result == 'success' && '✅' || (needs.publish-brand-only.result == 'skipped' && '⏭️' || '❌') }} ${{ needs.publish-brand-only.result }} |" >> $GITHUB_STEP_SUMMARY
20572113
echo "| Publish Python SDK | ${{ needs.publish-sdk-py.result == 'success' && '✅' || (needs.publish-sdk-py.result == 'skipped' && '⏭️' || '❌') }} ${{ needs.publish-sdk-py.result }} |" >> $GITHUB_STEP_SUMMARY
20582114
echo "| Publish Main | ${{ needs.publish-main.result == 'success' && '✅' || (needs.publish-main.result == 'skipped' && '⏭️' || '❌') }} ${{ needs.publish-main.result }} |" >> $GITHUB_STEP_SUMMARY

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
99

1010
### Added
1111

12+
- `@agent-relay/harnesses` is now published to npm, so SDK consumers can install the prebuilt PTY harnesses and harness-authoring helpers.
1213
- `agent-relay drive` and `agent-relay passthrough` add adaptive predictive echo so typing stays responsive when driving a high-latency or remote agent, and stays invisible on fast local links.
1314
- `@agent-relay/harness-driver` exports a reusable `PredictiveEchoEngine` so other attach UIs (CLI, Electron, browser) can share one predictive-echo implementation.
1415
- `@agent-relay/sdk` `relay.addListener(...)` on a workspace client now receives all workspace-visible events: `events.connect()` opens the relaycast 2.5 workspace stream when no agent client is present, so the documented `relay.addListener('message.created', ...)` quickstart path streams without registering an agent.

0 commit comments

Comments
 (0)