Skip to content
Merged
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
195 changes: 179 additions & 16 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ jobs:
build-broker:
name: Build broker (${{ matrix.target }})
runs-on: ${{ matrix.os }}
if: github.event.inputs.package == 'all' || github.event.inputs.package == 'main' || github.event.inputs.package == 'sdk' || github.event.inputs.package == 'sdk-py'
if: github.event.inputs.package == 'all' || github.event.inputs.package == 'main' || github.event.inputs.package == 'cli-prerelease' || github.event.inputs.package == 'sdk' || github.event.inputs.package == 'sdk-py'
strategy:
fail-fast: false
matrix:
Expand Down Expand Up @@ -532,7 +532,7 @@ jobs:
smoke-broker-packages:
name: Smoke ${{ matrix.platform }}
needs: [build, build-broker]
if: github.event.inputs.package == 'all' || github.event.inputs.package == 'sdk'
if: github.event.inputs.package == 'all' || github.event.inputs.package == 'main' || github.event.inputs.package == 'cli-prerelease' || github.event.inputs.package == 'sdk'
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
Expand Down Expand Up @@ -742,13 +742,13 @@ jobs:
# Publish the SDK's exact-version internal runtime dependencies before the
# SDK. @agent-relay/sdk imports these packages at runtime and pins them to
# the release version, so they must exist on the registry before the SDK can
# be installed from npm. This also gives us one repair path for a partial
# publish: run package=workflow-types with custom_version=<broken-sdk-version>.
# be installed from npm. The root CLI depends on @agent-relay/sdk too, so
# package=main and package=cli-prerelease also need this chain.
publish-sdk-internal-deps:
name: Publish SDK internal dep ${{ matrix.package }}
needs: [build, smoke-broker-packages]
runs-on: ubuntu-latest
if: github.event.inputs.package == 'all' || github.event.inputs.package == 'sdk'
if: github.event.inputs.package == 'all' || github.event.inputs.package == 'main' || github.event.inputs.package == 'cli-prerelease' || github.event.inputs.package == 'sdk'
strategy:
fail-fast: false
max-parallel: 3
Expand Down Expand Up @@ -850,7 +850,7 @@ jobs:
name: Publish ${{ matrix.broker_pkg }}
needs: [build, build-broker, smoke-broker-packages]
runs-on: ubuntu-latest
if: github.event.inputs.package == 'all' || github.event.inputs.package == 'sdk'
if: github.event.inputs.package == 'all' || github.event.inputs.package == 'main' || github.event.inputs.package == 'cli-prerelease' || github.event.inputs.package == 'sdk'
strategy:
fail-fast: false
max-parallel: 5
Expand Down Expand Up @@ -946,7 +946,15 @@ jobs:
if: github.event.inputs.dry_run != 'true'
continue-on-error: true
working-directory: packages/${{ matrix.broker_pkg }}
run: npm publish --access public --provenance --tag ${{ github.event.inputs.tag }} --ignore-scripts
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

- name: Wait before retry
if: github.event.inputs.dry_run != 'true' && steps.publish_1.outcome == 'failure'
Expand All @@ -957,7 +965,15 @@ jobs:
if: github.event.inputs.dry_run != 'true' && steps.publish_1.outcome == 'failure'
continue-on-error: true
working-directory: packages/${{ matrix.broker_pkg }}
run: npm publish --access public --provenance --tag ${{ github.event.inputs.tag }} --ignore-scripts
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

- name: Wait before retry
if: github.event.inputs.dry_run != 'true' && steps.publish_2.outcome == 'failure'
Expand All @@ -967,7 +983,15 @@ jobs:
id: publish_3
if: github.event.inputs.dry_run != 'true' && steps.publish_1.outcome == 'failure' && steps.publish_2.outcome == 'failure'
working-directory: packages/${{ matrix.broker_pkg }}
run: npm publish --access public --provenance --tag ${{ github.event.inputs.tag }} --ignore-scripts
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

- name: Fail if all publish attempts failed
if: >-
Expand Down Expand Up @@ -1059,7 +1083,90 @@ jobs:
- name: Publish to NPM
if: github.event.inputs.dry_run != 'true'
working-directory: packages/${{ matrix.package }}
run: npm publish --access public --provenance --tag ${{ github.event.inputs.tag }} --ignore-scripts
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
# cannot point npm at versions that do not exist.
publish-main-runtime-deps:
name: Publish main runtime dep ${{ matrix.package }}
needs: [build, build-broker, publish-broker-packages, publish-sdk-internal-deps]
runs-on: ubuntu-latest
if: github.event.inputs.package == 'main' || github.event.inputs.package == 'cli-prerelease'
strategy:
fail-fast: false
max-parallel: 6
matrix:
package:
- cloud
- config
- hooks
- sdk
- telemetry
- trajectory
- user-directory
- utils

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: .

# Keep the SDK tarball equivalent to the package=all path.
- name: Download broker binaries (SDK only)
if: matrix.package == 'sdk'
uses: actions/download-artifact@v4
with:
pattern: agent-relay-broker-*
path: packages/sdk/bin/
merge-multiple: true

- name: Make broker binaries executable (SDK only)
if: matrix.package == 'sdk'
run: |
chmod +x packages/sdk/bin/agent-relay-broker-* || true
rm -f packages/sdk/bin/agent-relay-broker

- 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/${{ matrix.package }}
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/${{ matrix.package }}
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

# Publish brand package only (when selected)
publish-brand-only:
Expand Down Expand Up @@ -1490,14 +1597,17 @@ jobs:
# Publish main package
publish-main:
name: Publish Main Package
needs: [build, verify-binaries, publish-packages]
needs: [build, verify-binaries, publish-packages, publish-main-runtime-deps]
runs-on: ubuntu-latest
outputs:
published: ${{ steps.publish_root.outputs.published }}
if: |
always() &&
(github.event.inputs.package == 'all' || github.event.inputs.package == 'main' || github.event.inputs.package == 'cli-prerelease') &&
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-packages.result == 'success' || needs.publish-packages.result == 'skipped') &&
(needs.publish-main-runtime-deps.result == 'success' || needs.publish-main-runtime-deps.result == 'skipped')

steps:
- name: Checkout code
Expand All @@ -1517,12 +1627,54 @@ jobs:

# NOTE: the root `agent-relay` CLI no longer bundles broker binaries in
# its own tarball. Brokers ship as `@agent-relay/broker-<platform>-<arch>`
# optional-deps of `@agent-relay/sdk` (which is itself bundled here via
# bundledDependencies), so users still get a broker on install.
# optional-deps of `@agent-relay/sdk`, which the root package installs as
# an exact-version runtime dependency.

- name: Update npm for OIDC support
run: npm install -g npm@latest

- name: Wait for root internal dependencies
if: github.event.inputs.dry_run != 'true'
shell: bash
run: |
set -euo pipefail
mapfile -t INTERNAL_DEPS < <(node --input-type=module -e "
import fs from 'node:fs';
const pkg = JSON.parse(fs.readFileSync('package.json', 'utf8'));
const deps = Object.entries(pkg.dependencies ?? {})
.filter(([name]) => name.startsWith('@agent-relay/'))
.map(([name, version]) => name + '@' + version);
console.log(deps.join('\n'));
")

if [ "${#INTERNAL_DEPS[@]}" -eq 0 ]; then
echo "No @agent-relay/* root dependencies to verify."
exit 0
fi

for _ in {1..12}; do
missing=()
for spec in "${INTERNAL_DEPS[@]}"; do
if npm view "$spec" version >/dev/null 2>&1; then
echo "✓ $spec is available"
else
missing+=("$spec")
fi
done

if [ "${#missing[@]}" -eq 0 ]; then
echo "All root @agent-relay/* dependencies are available on npm."
exit 0
fi

echo "Waiting for npm registry propagation: ${missing[*]}"
sleep 10
done

echo "Timed out waiting for root @agent-relay/* dependencies:"
printf ' - %s\n' "${missing[@]}"
exit 1

# bundledDependencies requires workspace packages to exist in
# node_modules/ at pack time so npm can include them in the tarball.
- name: Install workspace dependencies for bundling
Expand Down Expand Up @@ -1573,8 +1725,18 @@ jobs:
npm publish "$NPM_TARBALL" --dry-run --access public --tag "${{ github.event.inputs.tag }}"

- name: Publish to NPM
id: publish_root
if: github.event.inputs.dry_run != 'true'
run: npm publish "$NPM_TARBALL" --access public --provenance --tag "${{ github.event.inputs.tag }}"
run: |
set -euo pipefail
PKG_VERSION=$(node -p "require('./package.json').version")
if npm view "agent-relay@${PKG_VERSION}" version >/dev/null 2>&1; then
echo "agent-relay@${PKG_VERSION} already exists on npm; skipping publish"
echo "published=false" >> "$GITHUB_OUTPUT"
exit 0
Comment on lines +1733 to +1736
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Gate release job when root package publish is skipped

This new early-exit makes publish-main succeed whenever agent-relay@<version> already exists, but create-release still runs because it only checks needs.publish-main.result == 'success'. In a rerun or repair invocation that reuses an already released custom_version, this path reaches the later tag creation/push steps and fails on the existing tag, so the workflow is no longer idempotent for the exact scenario this change is trying to support.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in e578da0. publish-main now exposes a published output from the root publish step: already-existing agent-relay@<version> sets published=false, successful npm publish sets published=true, and create-release now requires needs.publish-main.outputs.published == 'true'. Repair reruns can publish missing deps and skip the existing root package without trying to recreate the tag/release.

fi
npm publish "$NPM_TARBALL" --access public --provenance --tag "${{ github.event.inputs.tag }}"
echo "published=true" >> "$GITHUB_OUTPUT"

# Create git tag and release
create-release:
Expand All @@ -1585,7 +1747,8 @@ jobs:
always() &&
github.event.inputs.package != 'cli-prerelease' &&
github.event.inputs.dry_run != 'true' &&
needs.publish-main.result == 'success'
needs.publish-main.result == 'success' &&
needs.publish-main.outputs.published == 'true'

steps:
- name: Setup Github App
Expand Down
Loading