Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 46 additions & 2 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,8 @@ jobs:
permissions:
contents: read
id-token: write # npm trusted publishing, so there is no npm token
outputs:
version: ${{ steps.publish.outputs.version }}
steps:
- uses: actions/checkout@v7
with:
Expand All @@ -156,7 +158,12 @@ jobs:
registry-url: "https://registry.npmjs.org"
- run: npm ci
# prepublishOnly builds the bundle.
- run: npm publish --access public
- name: Publish
id: publish
run: |
version="$(node -p "require('./package.json').version")"
npm publish --access public
echo "version=$version" >> "$GITHUB_OUTPUT"

# Same shape as publish-npm. Tagging is a separate job, so nothing here needs
# write access to the repository.
Expand Down Expand Up @@ -285,10 +292,47 @@ jobs:
)
}}
runs-on: ubuntu-latest
timeout-minutes: 5
# npm metadata is normally visible within about five minutes. Leave 2.5x that
# window for propagation, plus enough time to mint the token and dispatch.
timeout-minutes: 15
environment: release
permissions: {}
steps:
- name: Wait for package to become available
if: ${{ needs.publish-npm.result == 'success' || needs.publish-npm-preview.outputs.published == 'true' }}
env:
PACKAGE: "@agentclientprotocol/codex-acp"
VERSION: ${{ needs.publish-npm-preview.outputs.version || needs.publish-npm.outputs.version }}
#language=bash
run: |
if [ -z "$VERSION" ]; then
echo "::error::The publish job did not report a package version."
exit 1
fi

deadline=$((SECONDS + 750))
while (( SECONDS < deadline )); do
if timeout 10s npm pack "$PACKAGE@$VERSION" \
--dry-run \
--ignore-scripts \
--silent \
--registry=https://registry.npmjs.org \
--prefer-online \
--fetch-retries=0 >/dev/null 2>&1; then
echo "$PACKAGE@$VERSION is available from npm."
exit 0
fi

remaining=$((deadline - SECONDS))
if (( remaining > 0 )); then
echo "Waiting for $PACKAGE@$VERSION to become available (${remaining}s remaining)..."
sleep 10
fi
done

echo "::error::$PACKAGE@$VERSION was not available from npm after 12.5 minutes."
exit 1

- name: Generate token scoped to the registry repo
uses: actions/create-github-app-token@v3
id: registry-token
Expand Down
14 changes: 9 additions & 5 deletions docs/RELEASES.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,12 @@ handling for preview versions.
version in the working tree, then publishes to npm. The `prepublishOnly` hook
builds the bundle before publication. After publishing, `publish-tag-preview`
creates the tag and `trigger-registry-update` dispatches the registry update
independently; neither waits for the other. The registry job is shared with the
stable path. A tag failure can be retried on its own with **Re-run failed jobs**,
leaving the successful npm publish untouched.
independently; neither waits for the other. Before dispatching, the registry job
polls npm for the exact published version for up to 12.5 minutes, including
downloading its tarball, so the registry never checks while npm is still
propagating the package. The registry job is shared with the stable path. A tag
failure can be retried on its own with **Re-run failed jobs**, leaving the
successful npm publish untouched.

Previews start directly on push, without waiting for the
[`CI`](../.github/workflows/ci.yml) workflow or the `release-please` job. The
Expand All @@ -72,8 +75,9 @@ still requires the `verify` job to pass.

The publish step runs `npm publish --access public --tag preview` and sets
`published=true` only after it succeeds. Both downstream jobs use that output
to proceed with preview tagging and registry dispatch. This is a real publish,
with no dry-run stage.
to proceed with preview tagging and the registry availability check. This is a
real publish, with no dry-run stage; the later dry run downloads the published
tarball to verify it has propagated.

A stable and a preview dispatch can never collide — a release merge publishes
stable and skips the preview, every other push does the reverse — so the registry
Expand Down