ci: add release-prepare and release-publish workflows for npm releases - #2206
ci: add release-prepare and release-publish workflows for npm releases#2206tejaskash wants to merge 8 commits into
Conversation
- release.yml: workflow_dispatch (bump, channel, dry_run) publishes <next>-rc.N under the rc dist-tag after approval, or opens a release PR whose merge publishes under latest. rc numbers derive from tags, never commits. - package.json: publish as @aws/agentcore, version tracks the last stable release (0.28.1), repository field required for npm provenance. - update.test.ts: read the version from constants instead of a literal.
…ersion, drop redundant setup
…schema The rc dry run's binary printed its version and then exited 1: service.version was validated against ^\d+\.\d+\.\d+$, so any -rc.N build crashed at startup.
There was a problem hiding this comment.
AgentCore Harness Review
Verdict: Looks good
Reviewed the release workflow, the package.json rename to @aws/agentcore, and the update.test.ts refactor to use PACKAGE_VERSION. The design is clean: version resolution is centralized in one job, rc numbers are derived from tags (keeping package.json as the stable-only source of truth), the pull_request re-entry pattern properly gates stable publishes on human merge review, and packing happens before compile so the tarball never carries the platform binaries.
A few small things worth verifying before this workflow runs against main, but none block merging the PR:
- The scaffolding assumes
bun pm version <bump> --no-git-tag-versionprints the new tag with avprefix (${BASE#v}andrefs/tags/$BASEboth rely on that). Worth confirming on the first dry-run — if Bun ever drops the prefix,BASE="v..."becomesX.Y.Z, the tag-existence guard silently misses, and downstream tags/notes go out with a wrong prefix. PREVIOUS="v$(git tag -l 'v*' | xargs bunx semver@7 --range \"<$VERSION\" | tail -1)"degenerates toPREVIOUS="v"if there are no matching prior tags (i.e. a truly-first stable release).gh api generate-notesandgh release create --notes-start-tag vwould fail on that. Not reachable given0.28.1already exists, just something to be aware of.release-prusesgh pr create, which errors if a PR forrelease/vX.Y.Zis already open. The--forcepush updates the branch but won't refresh the PR title/body. Fine for the normal path; just means re-dispatching the same stable bump requires closing the old PR first.if: github.event_name == 'workflow_dispatch' || ...on theversionjob doesn't restrictworkflow_dispatchto any branch, so a stable dispatch from a non-refactorbranch will open a release PR against that branch but thepull_requestre-entry (branches: [refactor]) won't fire on merge. Presumably harmless during the refactor phase — worth tightening when the TODO to switch tomainis picked up.
Telemetry guidance doesn't apply here (CI-only change), and the test change is a straightforward improvement over hardcoded "1.0.0".
|
Claude Security Review: no high-confidence findings. (run) |
|
Claude Security Review: no high-confidence findings. (run) |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## refactor #2206 +/- ##
=========================================
Coverage 97.09% 97.09%
=========================================
Files 544 544
Lines 37794 37794
=========================================
Hits 36695 36695
Misses 1099 1099 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
…lish job - concurrency keyed on the resolved version at the publish job, so a closed unrelated PR can no longer cancel a pending stable publish - skip npm publish when the version is already on npm, so a rerun after a failed release step completes instead of failing on the republish - re-dispatching stable edits the existing release PR instead of failing - cap service.version length like every other telemetry attribute
|
Claude Security Review: no high-confidence findings. (run) |
There was a problem hiding this comment.
I kind of like how the python sdk does this with two workflows. In this case, it might look something like:
prepare-release.ymltakes in the versionBumpType and releaseChannel, and prepares a PR for the release on a branch withrelease/<channel>/<version>or some pattern so that we can extract it below.release.ymltriggers on closed PRs that follow release// from the GH bot. This could just run the build/check and release.
The main difference is we always get a PR to gate releases consistently, and the workflow triggers are much simpler.
| "name": "agentcore", | ||
| "version": "1.0.0", | ||
| "name": "@aws/agentcore", | ||
| "version": "0.28.1", |
There was a problem hiding this comment.
are we releasing under 1.0.0-rc or the previous version number?
There was a problem hiding this comment.
I think we want to do 1.0.0-rc.1
| type: choice | ||
| options: [major, minor, patch] | ||
| channel: | ||
| description: rc publishes after approval, stable opens a release PR |
There was a problem hiding this comment.
would it be simpler to always open a PR? That also allows us to see the releases in the commit history and gives a consistent way to approve releases.
There was a problem hiding this comment.
I agree about this. This pr would also update the cdk-contruct version on the project's agentcore.json using this pr like here
| jobs: | ||
| version: | ||
| if: github.event_name == 'workflow_dispatch' || (github.event.pull_request.merged && startsWith(github.head_ref, 'release/')) | ||
| runs-on: codebuild-agentcore-e2e-${{ github.run_id }}-${{ github.run_attempt }} |
There was a problem hiding this comment.
don't we need to do some allowlisting for this to work on the codebuild runners? I remember @aidandaly24 mentioning something recently.
…lease goes through a PR - release-prepare.yml: dispatch with bump and channel, bumps package.json with bun pm version (rc series continue with prerelease and graduate by stripping the suffix, since Bun's major would jump an rc to the next major), refreshes the vended @aws/agentcore-cdk pin, opens release/v<version> via the App - release-publish.yml: on merged release PRs, runs check/build/unit-test then publishes with provenance from a GitHub-hosted runner and creates the release. workflow_dispatch with dry_run for verification - scripts/sync-vended-cdk.ts: Bun port of the main-branch pin sync - no environments, no concurrency groups, no tag-derived rc numbering
|
Claude Security Review: no high-confidence findings. (run) |
|
Claude Security Review: no high-confidence findings. (run) |
…e creation rerun-safe Also follow the package rename through: the PR tarball job and the README looked for agentcore-*.tgz, Bun names a scoped tarball aws-agentcore-*.tgz.
|
Claude Security Review: no high-confidence findings. (run) |
| release-publish.yml (npm publish and GitHub release when a release PR merges) | ||
| |-- check.yml | ||
| |-- build.yml | ||
| `-- unit-test.yml |
There was a problem hiding this comment.
Can we take the opportunity to put all of these in one. That will be much more efficient and will save time.
There was a problem hiding this comment.
Harrison and TJ seemed to think that the release workflow
From the SDKs made a lot of sense. So I restructured it to be like those, it was originally one file.
Let's discuss
There was a problem hiding this comment.
I think alex's comment is in reference to the check/build/unit-test workflows which are always run together, so I think the suggestion is to make it a single workflow containing check, build, and unit-test as jobs.
My understanding is that the runtime behavior would be the same, but we no longer need to manually wire in each job as a separate call. Instead, we call a single workflow that triggers all three, so it'd simplify some of the changes here.
| types: [closed] | ||
| # TODO: switch to main once the refactor lands there. | ||
| branches: [refactor] | ||
| workflow_dispatch: |
There was a problem hiding this comment.
why do we need workflow dispatch here?
| release-publish.yml (npm publish and GitHub release when a release PR merges) | ||
| |-- check.yml | ||
| |-- build.yml | ||
| `-- unit-test.yml |
There was a problem hiding this comment.
I think alex's comment is in reference to the check/build/unit-test workflows which are always run together, so I think the suggestion is to make it a single workflow containing check, build, and unit-test as jobs.
My understanding is that the runtime behavior would be the same, but we no longer need to manually wire in each job as a separate call. Instead, we call a single workflow that triggers all three, so it'd simplify some of the changes here.
Summary
Two workflows give the refactor branch a PR-gated npm release process for
@aws/agentcore, in the shape of the Python SDK's release-prepare and release-publish pair.release-prepare.yml,workflow_dispatchwithbump(major, minor, patch) andchannel(rc, stable). Bumps package.json withbun pm version, refreshes the vended@aws/agentcore-cdkpin in the template, force-pushesrelease/v<version>and opens the PR as the automation App. The PR is the only release gate.0.28.1→1.0.0-rc.0→1.0.0-rc.1→1.0.0→1.1.0-rc.0.bumpis ignored while an rc series is open. Graduation strips the suffix explicitly because Bun'spm version majoron1.0.0-rc.3yields2.0.0.release-publish.yml,pull_request: closedinto refactor for mergedrelease/v*PRs. Runs check, build and unit-test on the merge commit, then onubuntu-latestbuilds, packs, cross-compiles six binaries,npm publish --provenanceunderrcfor prereleases orlatestotherwise, and creates the GitHub release with generated notes, tarball and binaries. Publish is skipped if the version is already on npm, so a rerun after a failed release step completes.workflow_dispatchwithdry_runexists for verification.scripts/sync-vended-cdk.ts, Bun port of feat(release): auto-bump the vended CDK pin during release prep #2118's pin sync. Dependency-free because it runs beforebun install.@aws/agentcore, set to the last published version0.28.1, with therepositoryfield provenance requires.src/telemetry/shapes.tsxonly acceptedX.Y.Z, so a binary versioned1.0.0-rc.0printed its version and exited 1 at startup. Now accepts a prerelease suffix, length-capped like the other attributes, with atest.eachfor accepted and rejected shapes.No GitHub environments and no concurrency groups. Publish runs on a GitHub-hosted runner because npm refuses provenance from self-hosted ones.
Verification
workflow_dispatchonly lists workflow files that exist on main, and these two do not yet, so neither could be dispatched from this branch. Verified instead:actionlintwith shellcheck clean on both workflows.scripts/sync-vended-cdk.tsrun with node_modules absent: bumpsalpha.45→alpha.51, is a no-op on the second run, exits 1 on an unknown dist-tag.aws-agentcore-1.0.0-rc.0.tgzwith the stamped version and six binaries). The release PR path also ran end to end then: https://github.com/aws/agentcore-cli/actions/runs/33810398072 opened chore(release): v1.0.0 #2203, and https://github.com/aws/agentcore-cli/actions/runs/33816972577 re-dispatched against an existing PR without failing.1.0.0-rc.0runs--versionand exits 0.Review fixes after the rebuild
vX.Y.ZandvX.Y.Z-rc.N). Without the filter, the first rc's notes would have started at main'sv1.0.0-preview.29, which sorts just below1.0.0-rc.0. Verified against the real tag list:1.0.0-rc.0and1.0.0start atv0.28.1,1.0.0-rc.1atv1.0.0-rc.0,1.1.0-rc.0atv1.0.0.gh release createis rerun-safe: if the release already exists the step re-uploads assets with--clobberinstead of failing on the tag.pr-automation.yml's PR tarball step and the README looked foragentcore-*.tgz, Bun names a scoped tarballaws-agentcore-*.tgz.Before the first real release
NPM_TOKENas a repo secret (granular token with publish rights on@aws/agentcore). The Trusted Publisher stays bound torelease-main-and-preview.ymlon main.release-prepare.ymlbecomes dispatchable once refactor lands on main, or once the file exists there.1.0.0tolatestwill supersede main's0.28.xline and sort above itspreviewtag.Follow-ups, not in this PR
src/handlers/update/index.tsxmaps any prerelease to dist-tagpreviewand compares againstlatest, so rc users would not be offered a newer rc byagentcore update.@aws/agentcore-cdksurfaces as red CI on that PR.