Skip to content

ci: add release-prepare and release-publish workflows for npm releases - #2206

Merged
tejaskash merged 11 commits into
refactorfrom
feat/refactor-release-workflow
Sep 4, 2026
Merged

ci: add release-prepare and release-publish workflows for npm releases#2206
tejaskash merged 11 commits into
refactorfrom
feat/refactor-release-workflow

Conversation

@tejaskash

@tejaskash tejaskash commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

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_dispatch with bump (major, minor, patch) and channel (rc, stable). Bumps package.json with bun pm version, refreshes the vended @aws/agentcore-cdk pin in the template, force-pushes release/v<version> and opens the PR as the automation App. The PR is the only release gate.
    • Version arithmetic: 0.28.11.0.0-rc.11.0.0-rc.21.0.01.1.0-rc.1. bump is ignored while an rc series is open. Series boundaries set the version explicitly: Bun's prerelease counter starts at 0 and its pm version major on 1.0.0-rc.3 yields 2.0.0.
  • release-publish.yml, pull_request: closed into refactor for merged release/v* PRs. Runs check, build and unit-test on the merge commit, then on ubuntu-latest builds, packs, cross-compiles six binaries, npm publish --provenance under rc for prereleases or latest otherwise, 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.
  • 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 before bun install.
  • package.json renamed to @aws/agentcore, set to the last published version 0.28.1, with the repository field provenance requires.
  • Telemetry fix found by the first dry run: src/telemetry/shapes.tsx only accepted X.Y.Z, so a binary versioned 1.0.0-rc.1 printed its version and exited 1 at startup. Now accepts a prerelease suffix, length-capped like the other attributes, with a test.each for 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_dispatch only lists workflow files that exist on main, and these two do not yet, so neither could be dispatched from this branch. Verified instead:

Review fixes after the rebuild

  • Release notes only consider this workflow's own tags (vX.Y.Z and vX.Y.Z-rc.N). Without the filter, the first rc's notes would have started at main's v1.0.0-preview.29, which sorts just below 1.0.0-rc.1. Verified against the real tag list: 1.0.0-rc.1 and 1.0.0 start at v0.28.1, 1.0.0-rc.1 at v1.0.0-rc.0, 1.1.0-rc.0 at v1.0.0.
  • gh release create is rerun-safe: if the release already exists the step re-uploads assets with --clobber instead of failing on the tag.
  • The package rename is followed through: pr-automation.yml's PR tarball step and the README looked for agentcore-*.tgz, Bun names a scoped tarball aws-agentcore-*.tgz.

Per @AlexanderRichey's thread

check.yml, build.yml and unit-test.yml are merged into one reusable verify.yml with one job per platform: install Bun and deps once, then static checks (Linux only, they are platform-independent), bundle, package, compile, smoke test and unit tests. Three jobs and three installs instead of seven. ci.yml and release-publish.yml each call it once. Check names become verify / Linux, verify / Windows, verify / macOS. No ruleset requires status checks by name. The workflow_dispatch on release-publish is gone too, since it existed only for dry-run verification and cannot be used until the file is on main.

Further review findings addressed

  • First rc is rc.1, per Alex.
  • Bun is pinned to 1.4.0 through packageManager in package.json, which setup-bun reads in every workflow. The release scripts depend on bun pm version, bun pm view and bun pm pack --quiet output shapes.
  • verify's static checks all report even when one fails (!cancelled()), matching the old check.yml. Build and tests run only when they pass.
  • agentcore update now tracks the dist-tag named by its own prerelease identifier (rc, preview) and compares against that tag, instead of mapping every prerelease to preview and comparing against latest. Without this, an rc user running update after 1.0.0 reached latest would have installed main's preview build. Covered by a test.each.
  • README documents recovery when publish fails after the release PR merges: rerun release-publish, never re-dispatch release-prepare.
  • verify's bun pm pack skips prepublishOnly, which would have rebuilt right after bun run build.

Before the first real release

  1. Add NPM_TOKEN as a repo secret (granular token with publish rights on @aws/agentcore). The Trusted Publisher stays bound to release-main-and-preview.yml on main.
  2. release-prepare.yml becomes dispatchable once refactor lands on main, or once the file exists there. release-publish.yml has no dispatch and is unaffected.
  3. latest contention with main needs a decision before the first stable: release-main-and-preview.yml on main also publishes --tag latest, so after refactor publishes 1.0.0, the next 0.28.x from main would move latest back down. Either main stops publishing latest once 1.0.0 is out, or its releases move to a different dist-tag.
  4. Runner allowlisting for a dedicated release runner, if we want one, with @aidandaly24.

Follow-ups, not in this PR

  • src/handlers/update/index.tsx maps any prerelease to dist-tag preview and compares against latest, so rc users would not be offered a newer rc by agentcore update.
  • A telemetry attribute validation failure takes the whole CLI down. Telemetry should degrade, not crash.
  • The vended CDK pin bump lands in the release PR, so any template incompatibility with a newer @aws/agentcore-cdk surfaces as red CI on that PR.

- 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.
@github-actions github-actions Bot added the size/m PR size: M label Sep 3, 2026
@agentcore-devx-automation agentcore-devx-automation Bot added the agentcore-harness-reviewing AgentCore Harness review in progress label Sep 3, 2026
…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.
@agentcore-devx-automation agentcore-devx-automation Bot added the claude-security-reviewing Claude Code /security-review in progress label Sep 3, 2026
@github-actions github-actions Bot added size/m PR size: M and removed size/m PR size: M labels Sep 3, 2026

@agentcore-devx-automation agentcore-devx-automation Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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-version prints the new tag with a v prefix (${BASE#v} and refs/tags/$BASE both rely on that). Worth confirming on the first dry-run — if Bun ever drops the prefix, BASE="v..." becomes X.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 to PREVIOUS="v" if there are no matching prior tags (i.e. a truly-first stable release). gh api generate-notes and gh release create --notes-start-tag v would fail on that. Not reachable given 0.28.1 already exists, just something to be aware of.
  • release-pr uses gh pr create, which errors if a PR for release/vX.Y.Z is already open. The --force push 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 the version job doesn't restrict workflow_dispatch to any branch, so a stable dispatch from a non-refactor branch will open a release PR against that branch but the pull_request re-entry (branches: [refactor]) won't fire on merge. Presumably harmless during the refactor phase — worth tightening when the TODO to switch to main is picked up.

Telemetry guidance doesn't apply here (CI-only change), and the test change is a straightforward improvement over hardcoded "1.0.0".

@agentcore-devx-automation agentcore-devx-automation Bot removed the agentcore-harness-reviewing AgentCore Harness review in progress label Sep 3, 2026
@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automation agentcore-devx-automation Bot added claude-security-reviewing Claude Code /security-review in progress and removed claude-security-reviewing Claude Code /security-review in progress labels Sep 3, 2026
@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automation agentcore-devx-automation Bot removed the claude-security-reviewing Claude Code /security-review in progress label Sep 3, 2026
@codecov-commenter

codecov-commenter commented Sep 3, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 97.09%. Comparing base (ef32ae3) to head (9000d63).
⚠️ Report is 22 commits behind head on refactor.

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.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

…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
@github-actions github-actions Bot added size/m PR size: M and removed size/m PR size: M labels Sep 3, 2026
@agentcore-devx-automation agentcore-devx-automation Bot added the claude-security-reviewing Claude Code /security-review in progress label Sep 3, 2026
@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automation agentcore-devx-automation Bot removed the claude-security-reviewing Claude Code /security-review in progress label Sep 3, 2026
@github-actions github-actions Bot added size/m PR size: M and removed size/m PR size: M labels Sep 3, 2026

@Hweinstock Hweinstock left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I kind of like how the python sdk does this with two workflows. In this case, it might look something like:

  • prepare-release.yml takes in the versionBumpType and releaseChannel, and prepares a PR for the release on a branch with release/<channel>/<version> or some pattern so that we can extract it below.
  • release.yml triggers 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.

Comment thread package.json
"name": "agentcore",
"version": "1.0.0",
"name": "@aws/agentcore",
"version": "0.28.1",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

are we releasing under 1.0.0-rc or the previous version number?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think we want to do 1.0.0-rc.1

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

1.0.0-rc.1. We will do release channel -> rc and bump type -> major that should give us 1.0.0-rc.1

Comment thread .github/workflows/release.yml Outdated
type: choice
options: [major, minor, patch]
channel:
description: rc publishes after approval, stable opens a release PR

@Hweinstock Hweinstock Sep 3, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I agree about this. This pr would also update the cdk-contruct version on the project's agentcore.json using this pr like here

Comment thread .github/workflows/release.yml Outdated
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 }}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

don't we need to do some allowlisting for this to work on the codebuild runners? I remember @aidandaly24 mentioning something recently.

Comment thread .github/workflows/release-publish.yml Outdated
types: [closed]
# TODO: switch to main once the refactor lands there.
branches: [refactor]
workflow_dispatch:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

why do we need workflow dispatch here?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This is only for the dryrun verification path

Comment thread .github/workflows/README.md Outdated
release-publish.yml (npm publish and GitHub release when a release PR merges)
|-- check.yml
|-- build.yml
`-- unit-test.yml

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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.

ci.yml and release-publish.yml each call verify.yml once instead of wiring three
workflows. Job bodies are unchanged. release-publish drops its workflow_dispatch,
which only existed for dry-run verification.
@github-actions github-actions Bot added size/l PR size: L and removed size/m PR size: M size/l PR size: L labels Sep 4, 2026
@agentcore-devx-automation agentcore-devx-automation Bot added the claude-security-reviewing Claude Code /security-review in progress label Sep 4, 2026
@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automation agentcore-devx-automation Bot removed the claude-security-reviewing Claude Code /security-review in progress label Sep 4, 2026
Comment thread .github/workflows/verify.yml Outdated
- run: bun run secrets:check
if: always()

build:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I meant to bring all three of these into one job to avoid installing bun and deps three times. We can just install bum, install deps, typecheck, build, and run tests all in one.

@github-actions github-actions Bot added size/m PR size: M and removed size/l PR size: L labels Sep 4, 2026
@agentcore-devx-automation agentcore-devx-automation Bot added the claude-security-reviewing Claude Code /security-review in progress label Sep 4, 2026
@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automation agentcore-devx-automation Bot removed the claude-security-reviewing Claude Code /security-review in progress label Sep 4, 2026
…ry static check

- release-prepare sets series boundaries explicitly so 0.28.1 -> 1.0.0-rc.1 -> 1.0.0-rc.2 -> 1.0.0
- package.json packageManager pins Bun 1.4.0, setup-bun reads it in every workflow
- verify keeps reporting all static checks after one fails, pack skips prepublishOnly
- update command tracks the dist-tag of its own prerelease identifier (rc, preview) instead of
  mapping every prerelease to preview and comparing against latest
- README documents the recovery path when publish fails after the release PR merges
@github-actions github-actions Bot added size/m PR size: M and removed size/m PR size: M labels Sep 4, 2026
@agentcore-devx-automation agentcore-devx-automation Bot added the claude-security-reviewing Claude Code /security-review in progress label Sep 4, 2026
@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automation agentcore-devx-automation Bot removed the claude-security-reviewing Claude Code /security-review in progress label Sep 4, 2026

@jariy17 jariy17 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Looks good.

@tejaskash
tejaskash merged commit 8ee4126 into refactor Sep 4, 2026
22 checks passed
@tejaskash
tejaskash deleted the feat/refactor-release-workflow branch September 4, 2026 17:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/m PR size: M

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants