From 170aecf1b66b69ef45a569fd0dd4a392a7614fad Mon Sep 17 00:00:00 2001 From: Nicolas Borges Date: Mon, 26 Oct 2026 17:28:38 -0400 Subject: [PATCH 1/2] refactor(ci): split v0 release workflow and lock CDK version to alpha --- .../workflows/release-main-and-preview.yml | 370 ++++++------------ .github/workflows/release-prepare.yml | 128 +++++- 2 files changed, 231 insertions(+), 267 deletions(-) diff --git a/.github/workflows/release-main-and-preview.yml b/.github/workflows/release-main-and-preview.yml index 527d5c2110..cad25b3c40 100644 --- a/.github/workflows/release-main-and-preview.yml +++ b/.github/workflows/release-main-and-preview.yml @@ -1,290 +1,150 @@ -name: Release v0 +# Publish v0.x releases to @aws/agentcore to npm under the v0-latest dist tag +name: release-publish on: workflow_dispatch: - inputs: - bump_type: - description: 'v0 version bump' - required: true - type: choice - options: - - patch - - minor - changelog: - description: 'Changelog entry (optional)' - required: false - type: string - dry_run: - description: 'Dry run — create PR but skip npm publish' - required: false - type: boolean - default: false - cdk_dist_tag: - description: '@aws/agentcore-cdk npm dist-tag to pin the vended CDK template to (default: latest)' - required: false - type: string - default: 'latest' - -permissions: - contents: write - pull-requests: write - -env: - AGENTCORE_TELEMETRY_DISABLED: '1' + push: + branches: [main, v0.x] jobs: - # ═══════════════════════════════════════════════════════════════════ - # Step 1 — Prepare v0 release PR - # ═══════════════════════════════════════════════════════════════════ - prepare-release: - name: Prepare Release - runs-on: aws-release-4-core + check-release: + runs-on: codebuild-agentcore-e2e-${{ github.run_id }}-${{ github.run_attempt }} + permissions: + pull-requests: read outputs: - version: ${{ steps.bump.outputs.version }} - branch: ${{ steps.create-pr.outputs.branch }} - + is_release: ${{ steps.check.outputs.is_release }} steps: - - name: Checkout v0 branch - uses: actions/checkout@v7 - with: - ref: ${{ github.ref_name }} - fetch-depth: 0 - - - uses: actions/setup-node@v7 - with: - node-version: 20.x - - - name: Verify v0 release branch and version + - name: Check for a merged v0 release PR + id: check env: - BRANCH_NAME: ${{ github.ref_name }} - BUMP_TYPE: ${{ github.event.inputs.bump_type }} + GH_TOKEN: ${{ github.token }} run: | - if [[ "$BUMP_TYPE" != "patch" && "$BUMP_TYPE" != "minor" ]]; then - echo "❌ v0 releases only support patch or minor bumps, not $BUMP_TYPE." + set -euo pipefail + if [[ "$GITHUB_REF_NAME" != main && "$GITHUB_REF_NAME" != v0.x ]]; then + echo "::error::v0 releases must run from main or v0.x, not $GITHUB_REF_NAME" exit 1 fi - if [[ "$BRANCH_NAME" != "main" && "$BRANCH_NAME" != "v0.x" ]]; then - echo "❌ v0 releases must run from main or v0.x, not $BRANCH_NAME." + IS_RELEASE=$(gh api --paginate --slurp "repos/$GITHUB_REPOSITORY/commits/$GITHUB_SHA/pulls" \ + | jq -r --arg repository "$GITHUB_REPOSITORY" --arg ref "$GITHUB_REF_NAME" --arg sha "$GITHUB_SHA" ' + any(.[][]; + .user.id == 282717993 and + .merged_at != null and + .merge_commit_sha == $sha and + .head.repo.full_name == $repository and + .base.ref == $ref and + (.head.ref | startswith("release/v")) + )') + if [[ "$GITHUB_EVENT_NAME" == workflow_dispatch && "$IS_RELEASE" != true ]]; then + echo "::error::Manual recovery must select the v0 branch while its tip is a merged automation-created release PR" exit 1 fi - VERSION=$(node -p "require('./package.json').version") - if [[ "$VERSION" != 0.* ]]; then - echo "❌ Expected a v0 package version, found $VERSION." - exit 1 - fi - - - name: Install uv - uses: astral-sh/setup-uv@v7 - - - name: Configure git - run: | - git config --global user.name "github-actions[bot]" - git config --global user.email "github-actions[bot]@users.noreply.github.com" - - - run: npm ci - - - name: Bump v0 version - id: bump - env: - BUMP_TYPE: ${{ github.event.inputs.bump_type }} - CHANGELOG_INPUT: ${{ github.event.inputs.changelog }} - run: | - BUMP_CMD="npx tsx scripts/bump-version.ts $BUMP_TYPE" - if [ -n "$CHANGELOG_INPUT" ]; then - BUMP_CMD="$BUMP_CMD --changelog \"$CHANGELOG_INPUT\"" - fi - eval $BUMP_CMD - - NEW_VERSION=$(node -p "require('./package.json').version") - echo "version=$NEW_VERSION" >> $GITHUB_OUTPUT - echo "📦 v0 version: $NEW_VERSION" - - - name: Sync vended CDK version - env: - CDK_DIST_TAG: ${{ github.event.inputs.cdk_dist_tag }} - run: | - npx tsx scripts/sync-vended-cdk.ts --tag "${CDK_DIST_TAG:-latest}" - npx prettier --write src/assets/cdk/package.json - - - name: Regenerate JSON schema - run: | - npm run build - node scripts/generate-schema.mjs - npx prettier --write schemas/ - - - name: Update snapshots - run: npm run test:update-snapshots - - - name: Generate GitHub App Token - id: app-token - uses: actions/create-github-app-token@v3 - with: - app-id: ${{ vars.APP_ID }} - private-key: ${{ secrets.APP_PRIVATE_KEY }} - - - name: Create release branch and PR - id: create-pr - env: - GH_TOKEN: ${{ steps.app-token.outputs.token }} - VERSION: ${{ steps.bump.outputs.version }} - run: | - BRANCH_NAME="release/v${VERSION}" - TITLE="Release v$VERSION" - COMMIT_MSG="chore: bump v0 to $VERSION" - echo "branch=$BRANCH_NAME" >> $GITHUB_OUTPUT - - git ls-remote --exit-code --heads origin "$BRANCH_NAME" && git push origin --delete "$BRANCH_NAME" || true - git show-ref --verify --quiet "refs/heads/$BRANCH_NAME" && git branch -D "$BRANCH_NAME" || true - - git checkout -b "$BRANCH_NAME" - git add -A - git commit -m "$COMMIT_MSG" - git push origin "$BRANCH_NAME" - - # Build PR body - BODY="## $TITLE - - | Package | Version | npm Tag | - |---------|---------|---------|" - BODY="$BODY - | @aws/agentcore | $VERSION | v0-latest | - - ### Checklist - - [ ] Review CHANGELOG.md - - [ ] All CI checks passing - - [ ] Merge this PR before approving the publish step" + echo "is_release=$IS_RELEASE" >> "$GITHUB_OUTPUT" - gh pr create \ - --base "${{ github.ref_name }}" \ - --head "$BRANCH_NAME" \ - --label release \ - --title "$TITLE" \ - --body "$BODY" - - # ═══════════════════════════════════════════════════════════════════ - # Step 2 — Manual approval gate - # ═══════════════════════════════════════════════════════════════════ - release-approval: - name: Release Approval - needs: [prepare-release] - runs-on: aws-release-4-core - environment: - name: npm-publish-approval - steps: - - name: Approval checkpoint - env: - VERSION: ${{ needs.prepare-release.outputs.version }} - run: | - echo "📦 v0 version: $VERSION (npm tag: v0-latest)" - echo "" - echo "⚠️ MANUAL APPROVAL REQUIRED" - echo "" - echo "Before approving:" - echo "1. Verify PR CI checks are passing" - echo "2. Merge the release PR to the selected v0 branch" - echo "3. Verify the PR is merged" - - # ═══════════════════════════════════════════════════════════════════ - # Step 3 — Verify PR merged - # ═══════════════════════════════════════════════════════════════════ - verify-merge: - name: Verify PR Merged - needs: [prepare-release, release-approval] - if: ${{ !inputs.dry_run }} - runs-on: aws-release-4-core + verify: + needs: check-release + if: needs.check-release.outputs.is_release == 'true' + runs-on: codebuild-agentcore-e2e-${{ github.run_id }}-${{ github.run_attempt }} + permissions: + contents: read + outputs: + version: ${{ steps.release.outputs.version }} + env: + AGENTCORE_TELEMETRY_DISABLED: '1' steps: - - name: Checkout - uses: actions/checkout@v7 + - uses: actions/checkout@v7 with: - ref: ${{ github.ref_name }} + ref: ${{ github.sha }} fetch-depth: 0 - - - name: Verify v0 version + persist-credentials: false + - uses: actions/setup-node@v7 + with: + node-version: 22.x + cache: npm + - uses: astral-sh/setup-uv@v7 + - name: Configure git for tests + run: | + git config --global user.email "ci@amazon.com" + git config --global user.name "CI" + - run: npm ci + - name: Validate v0 version and CDK pin + run: | + node - <<'NODE' + const semver = require("semver"); + const cliVersion = require("./package.json").version; + const cdkVersion = require("./src/assets/cdk/package.json").dependencies["@aws/agentcore-cdk"]; + if (!semver.valid(cliVersion) || semver.major(cliVersion) !== 0 || semver.prerelease(cliVersion)) { + throw new Error(`Expected a stable v0 CLI version, found ${cliVersion}`); + } + if (!semver.valid(cdkVersion) || semver.major(cdkVersion) !== 0) { + throw new Error(`Expected an exact v0 CDK pin, found ${cdkVersion}`); + } + NODE + - run: npm run lint + - run: npm run typecheck + - run: npm run build + - run: npm run test:unit + - name: Resolve v0 release + id: release env: - EXPECTED: ${{ needs.prepare-release.outputs.version }} + REF: ${{ github.sha }} run: | - git fetch origin ${{ github.ref_name }} - ACTUAL=$(git show origin/${{ github.ref_name }}:package.json | node -p "JSON.parse(require('fs').readFileSync('/dev/stdin','utf8')).version") - if [ "$ACTUAL" != "$EXPECTED" ]; then - echo "❌ Release PR not merged yet!" - echo "Expected v0 version: $EXPECTED, Got: $ACTUAL" - exit 1 + set -euo pipefail + VERSION=$(node -p "require('./package.json').version") + if git rev-parse -q --verify "refs/tags/v$VERSION" >/dev/null; then + TAG_SHA=$(git rev-list -n 1 "v$VERSION") + if [[ "$TAG_SHA" != "$REF" ]]; then + echo "::error::v$VERSION already points to $TAG_SHA, not $REF" + exit 1 + fi fi - echo "✅ v0 version verified: $ACTUAL" + echo "version=$VERSION" >> "$GITHUB_OUTPUT" + - name: Pack CLI + run: npm pack --ignore-scripts --silent + - uses: actions/upload-artifact@v7 + with: + name: release-tarball + path: aws-agentcore-*.tgz + if-no-files-found: error - # ═══════════════════════════════════════════════════════════════════ - # Step 4 — Publish v0 to npm (tag: v0-latest) - # ═══════════════════════════════════════════════════════════════════ - publish-main: - name: Publish v0 (@v0-latest) - needs: [prepare-release, verify-merge] - runs-on: aws-release-4-core + publish: + needs: verify + runs-on: ubuntu-latest environment: name: npm-publish url: https://www.npmjs.com/package/@aws/agentcore permissions: - id-token: write contents: write - + id-token: write steps: - - name: Checkout v0 branch - uses: actions/checkout@v7 - with: - ref: ${{ github.ref_name }} - fetch-depth: 0 - - uses: actions/setup-node@v7 with: node-version: 22.x - registry-url: 'https://registry.npmjs.org' - - - run: npm install -g npm@11.5.1 - - run: npm ci - - run: npm run build - + registry-url: https://registry.npmjs.org + - run: npm install -g npm@11 + - uses: actions/download-artifact@v8 + with: + name: release-tarball - name: Publish to npm - run: npm publish --access public --provenance --tag v0-latest - - - name: Tag and release env: - VERSION: ${{ needs.prepare-release.outputs.version }} + VERSION: ${{ needs.verify.outputs.version }} run: | - git config --global user.name "github-actions[bot]" - git config --global user.email "github-actions[bot]@users.noreply.github.com" - git tag -a "v$VERSION" -m "Release v$VERSION" - git push origin "v$VERSION" - - - name: Create GitHub Release - uses: softprops/action-gh-release@v3 - with: - tag_name: v${{ needs.prepare-release.outputs.version }} - name: AgentCore CLI v${{ needs.prepare-release.outputs.version }} - generate_release_notes: true - prerelease: false - make_latest: false - body: | - ## Installation - - ```bash - npm install -g @aws/agentcore@${{ needs.prepare-release.outputs.version }} - ``` - - # ═══════════════════════════════════════════════════════════════════ - # Summary - # ═══════════════════════════════════════════════════════════════════ - summary: - name: Release Summary - needs: [prepare-release, publish-main] - if: always() && !cancelled() - runs-on: aws-release-4-core - steps: - - name: Summary + set -euo pipefail + if npm view "@aws/agentcore@$VERSION" version >/dev/null 2>&1; then + echo "@aws/agentcore@$VERSION is already on npm, skipping publish" + else + npm publish "aws-agentcore-$VERSION.tgz" --provenance --access public --tag v0-latest + fi + - name: Create GitHub release env: - VERSION: ${{ needs.prepare-release.outputs.version }} - MAIN_STATUS: ${{ needs.publish-main.result }} + GH_TOKEN: ${{ github.token }} + GH_REPO: ${{ github.repository }} + VERSION: ${{ needs.verify.outputs.version }} + REF: ${{ github.sha }} run: | - echo "## Release Summary" - echo "" - echo "| Package | Version | npm Tag | Status |" - echo "|---------|---------|---------|--------|" - echo "| @aws/agentcore | $VERSION | v0-latest | $MAIN_STATUS |" + set -euo pipefail + if gh release view "v$VERSION" >/dev/null 2>&1; then + gh release upload "v$VERSION" --clobber "aws-agentcore-$VERSION.tgz" + else + gh release create "v$VERSION" --target "$REF" --title "v$VERSION" \ + --generate-notes --latest=false "aws-agentcore-$VERSION.tgz" + fi diff --git a/.github/workflows/release-prepare.yml b/.github/workflows/release-prepare.yml index e5b9b1057c..f8fe19d4e5 100644 --- a/.github/workflows/release-prepare.yml +++ b/.github/workflows/release-prepare.yml @@ -1,19 +1,123 @@ -# Placeholder. The real release-prepare workflow lives on the refactor branch. -# -# GitHub only lists a workflow in the Actions UI and the dispatch API if a file with its name exists on -# the default branch. Selecting "refactor" in the branch picker runs refactor's release-prepare.yml with -# refactor's inputs. Selecting "main" runs this file, which refuses so nothing happens to main. -# -# Delete this file when refactor lands on main and brings the real workflow with it. +# Opens a v0 maintenance release PR. Merging the PR triggers release-main-and-preview.yml. name: release-prepare on: workflow_dispatch: + inputs: + bump: + description: v0 version bump + required: true + type: choice + options: [patch, minor] + changelog: + description: Changelog entry (optional; otherwise generated from commits) + required: false + type: string jobs: - refuse: - runs-on: ubuntu-latest + prepare: + runs-on: codebuild-agentcore-e2e-${{ github.run_id }}-${{ github.run_attempt }} + permissions: + contents: read steps: - - run: | - echo "::error::release-prepare only exists on the refactor branch. Re-run with 'refactor' selected in the branch picker." - exit 1 + - uses: actions/checkout@v7 + with: + fetch-depth: 0 + persist-credentials: false + - uses: actions/setup-node@v7 + with: + node-version: 20.x + - uses: astral-sh/setup-uv@v7 + - name: Validate v0 release + env: + BRANCH: ${{ github.ref_name }} + BUMP: ${{ inputs.bump }} + run: | + set -euo pipefail + if [[ "$BRANCH" != main && "$BRANCH" != v0.x ]]; then + echo "::error::v0 releases must run from main or v0.x, not $BRANCH" + exit 1 + fi + if [[ "$BUMP" != patch && "$BUMP" != minor ]]; then + echo "::error::v0 releases only support patch or minor bumps" + exit 1 + fi + VERSION=$(node -p "require('./package.json').version") + if [[ ! "$VERSION" =~ ^0\.[0-9]+\.[0-9]+$ ]]; then + echo "::error::Expected a stable v0 package version, found $VERSION" + exit 1 + fi + - run: npm ci + - name: Pin v0 CDK + id: cdk + run: | + set -euo pipefail + if ! CDK_VERSION=$(npm view '@aws/agentcore-cdk@alpha' version); then + echo "::error::Publish a v0 CDK version under @aws/agentcore-cdk@alpha before preparing this release" + exit 1 + fi + if [[ ! "$CDK_VERSION" =~ ^0\.[0-9]+\.[0-9]+(-[0-9A-Za-z.-]+)?$ ]]; then + echo "::error::@aws/agentcore-cdk@alpha must resolve to a v0 version, found $CDK_VERSION" + exit 1 + fi + npx tsx scripts/sync-vended-cdk.ts --to "$CDK_VERSION" + npx prettier --write src/assets/cdk/package.json + echo "version=$CDK_VERSION" >> "$GITHUB_OUTPUT" + - name: Bump v0 version + id: version + env: + BUMP: ${{ inputs.bump }} + CHANGELOG: ${{ inputs.changelog }} + run: | + set -euo pipefail + if [[ -n "$CHANGELOG" ]]; then + npx tsx scripts/bump-version.ts "$BUMP" --changelog "$CHANGELOG" + else + npx tsx scripts/bump-version.ts "$BUMP" + fi + VERSION=$(node -p "require('./package.json').version") + if [[ ! "$VERSION" =~ ^0\.[0-9]+\.[0-9]+$ ]]; then + echo "::error::Expected a stable v0 release version, found $VERSION" + exit 1 + fi + if git rev-parse -q --verify "refs/tags/v$VERSION" >/dev/null; then + echo "::error::v$VERSION is already released" + exit 1 + fi + echo "version=$VERSION" >> "$GITHUB_OUTPUT" + - name: Regenerate JSON schema + run: | + npm run build + node scripts/generate-schema.mjs + npx prettier --write schemas/ + - name: Update snapshots + run: npm run test:update-snapshots + - uses: actions/create-github-app-token@v3 + id: app-token + with: + app-id: ${{ vars.APP_ID }} + private-key: ${{ secrets.APP_PRIVATE_KEY }} + - name: Open release PR + env: + GH_TOKEN: ${{ steps.app-token.outputs.token }} + VERSION: ${{ steps.version.outputs.version }} + CDK_VERSION: ${{ steps.cdk.outputs.version }} + run: | + set -euo pipefail + BRANCH="release/v$VERSION" + if git ls-remote --exit-code --heads origin "$BRANCH" >/dev/null; then + echo "::error::$BRANCH already exists; review that release branch before preparing another" + exit 1 + fi + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + git add -A + git commit -m "chore(release): v$VERSION" + git push "https://x-access-token:$GH_TOKEN@github.com/$GITHUB_REPOSITORY.git" "HEAD:refs/heads/$BRANCH" + gh pr create --base "$GITHUB_REF_NAME" --head "$BRANCH" --label release \ + --title "chore(release): v$VERSION" \ + --body "Merging publishes \`@aws/agentcore@$VERSION\` under npm \`v0-latest\` and creates the \`v$VERSION\` GitHub release. + + Vended CDK version: \`@aws/agentcore-cdk@$CDK_VERSION\` (resolved from \`alpha\`). + + Review the changelog, generated files, and CI results before merging." From bc292489df510785164d68d41351938ffeae3692 Mon Sep 17 00:00:00 2001 From: Nicolas Borges Date: Tue, 27 Oct 2026 08:04:42 -0400 Subject: [PATCH 2/2] fix(ci): retire legacy v0 release and scope release notes --- .../workflows/release-main-and-preview.yml | 12 +- .github/workflows/release.yml | 400 ------------------ 2 files changed, 11 insertions(+), 401 deletions(-) delete mode 100644 .github/workflows/release.yml diff --git a/.github/workflows/release-main-and-preview.yml b/.github/workflows/release-main-and-preview.yml index cad25b3c40..7cda651d41 100644 --- a/.github/workflows/release-main-and-preview.yml +++ b/.github/workflows/release-main-and-preview.yml @@ -48,6 +48,7 @@ jobs: contents: read outputs: version: ${{ steps.release.outputs.version }} + previous_tag: ${{ steps.release.outputs.previous_tag }} env: AGENTCORE_TELEMETRY_DISABLED: '1' steps: @@ -97,7 +98,14 @@ jobs: exit 1 fi fi + PREVIOUS=$(git tag -l 'v0.*' | grep -E '^v0\.[0-9]+\.[0-9]+$' \ + | xargs npx --no-install semver --range "<$VERSION" | tail -1) + if [[ -z "$PREVIOUS" ]]; then + echo "::error::No previous stable v0 tag found before v$VERSION" + exit 1 + fi echo "version=$VERSION" >> "$GITHUB_OUTPUT" + echo "previous_tag=v$PREVIOUS" >> "$GITHUB_OUTPUT" - name: Pack CLI run: npm pack --ignore-scripts --silent - uses: actions/upload-artifact@v7 @@ -139,6 +147,7 @@ jobs: GH_TOKEN: ${{ github.token }} GH_REPO: ${{ github.repository }} VERSION: ${{ needs.verify.outputs.version }} + PREVIOUS_TAG: ${{ needs.verify.outputs.previous_tag }} REF: ${{ github.sha }} run: | set -euo pipefail @@ -146,5 +155,6 @@ jobs: gh release upload "v$VERSION" --clobber "aws-agentcore-$VERSION.tgz" else gh release create "v$VERSION" --target "$REF" --title "v$VERSION" \ - --generate-notes --latest=false "aws-agentcore-$VERSION.tgz" + --generate-notes --notes-start-tag "$PREVIOUS_TAG" --latest=false \ + "aws-agentcore-$VERSION.tgz" fi diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml deleted file mode 100644 index f577d080f1..0000000000 --- a/.github/workflows/release.yml +++ /dev/null @@ -1,400 +0,0 @@ -name: Release - -on: - workflow_dispatch: - inputs: - bump_type: - description: 'Version bump type' - required: true - type: choice - options: - - patch - - minor - changelog: - description: 'Custom changelog entry (optional - leave empty to auto-generate)' - required: false - type: string - -permissions: - contents: write - pull-requests: write - -jobs: - prepare-release: - name: Prepare Release - runs-on: aws-release-4-core - outputs: - version: ${{ steps.bump.outputs.version }} - branch: ${{ steps.bump.outputs.branch }} - dist_tag: ${{ steps.release-meta.outputs.dist_tag }} - base_branch: ${{ steps.release-meta.outputs.base_branch }} - - steps: - - name: Determine release metadata - id: release-meta - env: - BRANCH_NAME: ${{ github.ref_name }} - BUMP_TYPE: ${{ github.event.inputs.bump_type }} - run: | - if [[ "$BUMP_TYPE" != "patch" && "$BUMP_TYPE" != "minor" ]]; then - echo "❌ ERROR: v0 releases only support patch or minor bumps, not $BUMP_TYPE." - exit 1 - fi - if [[ "$BRANCH_NAME" == "main" || "$BRANCH_NAME" == "v0.x" ]]; then - echo "dist_tag=v0-latest" >> $GITHUB_OUTPUT - echo "base_branch=$BRANCH_NAME" >> $GITHUB_OUTPUT - else - echo "❌ ERROR: v0 releases must run from main or v0.x, not $BRANCH_NAME." - exit 1 - fi - - - name: Checkout code - uses: actions/checkout@v7 - with: - fetch-depth: 0 - - - name: Setup Node.js - uses: actions/setup-node@v7 - with: - node-version: 20.x - - - name: Configure git - run: | - git config --global user.name "github-actions[bot]" - git config --global user.email "github-actions[bot]@users.noreply.github.com" - - - name: Install dependencies - run: npm ci - - - name: Get current version - id: current - run: | - VERSION=$(node -p "require('./package.json').version") - echo "version=$VERSION" >> $GITHUB_OUTPUT - echo "Current version: $VERSION" - if [[ "$VERSION" != 0.* ]]; then - echo "❌ ERROR: Expected a v0 package version, found $VERSION." - exit 1 - fi - - - name: Bump version - id: bump - env: - CHANGELOG_INPUT: ${{ github.event.inputs.changelog }} - BUMP_TYPE: ${{ github.event.inputs.bump_type }} - run: | - # If no custom changelog, provide guidance - if [ -z "$CHANGELOG_INPUT" ]; then - echo "ℹ️ No custom changelog provided. Will auto-generate from commits." - echo "💡 Tip: Provide a meaningful changelog message for better release notes" - fi - - # Build version bump command - BUMP_CMD="npx tsx scripts/bump-version.ts $BUMP_TYPE" - - # Add changelog if provided - if [ -n "$CHANGELOG_INPUT" ]; then - BUMP_CMD="$BUMP_CMD --changelog \"$CHANGELOG_INPUT\"" - fi - - # Run the bump command - eval $BUMP_CMD - - NEW_VERSION=$(node -p "require('./package.json').version") - echo "version=$NEW_VERSION" >> $GITHUB_OUTPUT - echo "branch=release/v$NEW_VERSION" >> $GITHUB_OUTPUT - echo "New version: $NEW_VERSION" - - - name: Regenerate JSON schema - run: | - npm run build - node scripts/generate-schema.mjs - npx prettier --write schemas/ - echo "✓ JSON schema regenerated and formatted" - - - name: Create release branch and PR - env: - NEW_VERSION: ${{ steps.bump.outputs.version }} - run: | - BRANCH_NAME="release/v$NEW_VERSION" - - # Delete remote branch if exists - if git ls-remote --exit-code --heads origin $BRANCH_NAME; then - echo "⚠️ Branch $BRANCH_NAME already exists. Deleting it first..." - git push origin --delete $BRANCH_NAME - fi - - # Delete local branch if exists - if git show-ref --verify --quiet refs/heads/$BRANCH_NAME; then - git branch -D $BRANCH_NAME - fi - - git checkout -b $BRANCH_NAME - git add -A - git commit -m "chore: bump version to $NEW_VERSION - - Co-authored-by: github-actions[bot] " - - git push origin $BRANCH_NAME - - # Verify version was committed correctly - COMMITTED_VERSION=$(git show HEAD:package.json | node -p "JSON.parse(require('fs').readFileSync('/dev/stdin', 'utf8')).version") - if [ "$COMMITTED_VERSION" != "$NEW_VERSION" ]; then - echo "❌ ERROR: Version not committed correctly!" - exit 1 - fi - - - name: Generate GitHub App Token - id: app-token - uses: actions/create-github-app-token@v3 - with: - app-id: ${{ vars.APP_ID }} - private-key: ${{ secrets.APP_PRIVATE_KEY }} - - - name: Create Pull Request - env: - GH_TOKEN: ${{ steps.app-token.outputs.token }} - NEW_VERSION: ${{ steps.bump.outputs.version }} - BASE_BRANCH: ${{ steps.release-meta.outputs.base_branch }} - DIST_TAG: ${{ steps.release-meta.outputs.dist_tag }} - GITHUB_ACTOR: ${{ github.actor }} - run: | - BRANCH_NAME="release/v$NEW_VERSION" - - RELEASE_TYPE="v0 maintenance (npm tag: $DIST_TAG)" - - gh pr create \ - --base "$BASE_BRANCH" \ - --head "$BRANCH_NAME" \ - --label release \ - --title "Release v$NEW_VERSION" \ - --body "## Release v$NEW_VERSION - - This PR was automatically created by the release workflow. - - **Release type:** $RELEASE_TYPE - **Base branch:** $BASE_BRANCH - - ### Pre-merge Checklist - - [ ] Review CHANGELOG.md - ensure it has meaningful release notes - - [ ] Verify version numbers are correct in all files - - [ ] All CI checks are passing - - ### Release Process - After merging this PR: - 1. Package will be built and tested - 2. **Manual approval required** before publishing to npm - 3. GitHub release and tag created after publication - - --- - *Triggered by @$GITHUB_ACTOR*" - - test-and-build: - name: Test and Build - needs: prepare-release - runs-on: aws-release-4-core - - steps: - - uses: actions/checkout@v7 - with: - ref: release/v${{ needs.prepare-release.outputs.version }} - - - name: Verify version before build - env: - EXPECTED_VERSION: ${{ needs.prepare-release.outputs.version }} - run: | - ACTUAL_VERSION=$(node -p "require('./package.json').version") - - echo "Expected version: $EXPECTED_VERSION" - echo "Actual version: $ACTUAL_VERSION" - - if [ "$ACTUAL_VERSION" != "$EXPECTED_VERSION" ]; then - echo "❌ ERROR: Version mismatch!" - exit 1 - fi - - echo "✓ Version verified: $ACTUAL_VERSION" - - - name: Setup Node.js - uses: actions/setup-node@v7 - with: - node-version: 20.x - - - name: Install dependencies - run: npm ci - - - name: Configure git for tests - run: | - git config --global user.name "github-actions[bot]" - git config --global user.email "github-actions[bot]@users.noreply.github.com" - - - name: Install uv for Python tests - run: curl -LsSf https://astral.sh/uv/install.sh | sh - - - name: Run linter - run: npm run lint - - - name: Run type check - run: npm run typecheck - - - name: Build package - run: npm run build - - - name: Run tests - run: npm run test:unit - - - name: Pack for verification - run: npm pack - - - name: Upload artifacts - uses: actions/upload-artifact@v7 - with: - name: dist - path: | - dist/ - *.tgz - - release-approval: - name: Release Approval - needs: test-and-build - runs-on: aws-release-4-core - environment: - name: npm-publish-approval - - steps: - - name: Approval checkpoint - run: | - echo "✅ Build and tests successful" - echo "📦 Package ready for npm publication" - echo "" - echo "⚠️ MANUAL APPROVAL REQUIRED" - echo "" - echo "Before approving:" - echo "1. Verify the PR has been merged to the selected base branch" - echo "2. Check that version number is correct" - echo "3. Ensure no duplicate version exists on npm" - echo "" - echo "🚨 Only approve if everything is correct!" - - publish-npm: - name: Publish to npm - needs: [prepare-release, release-approval] - runs-on: aws-release-4-core - environment: - name: npm-publish - url: https://www.npmjs.com/package/@aws/agentcore - permissions: - id-token: write # Required for OIDC trusted publishing - contents: write # Required to push git tags - - steps: - - name: Checkout base branch (AFTER PR merge) - uses: actions/checkout@v7 - with: - ref: ${{ needs.prepare-release.outputs.base_branch }} - fetch-depth: 0 - - - name: Verify we have the merged code - env: - BASE_BRANCH: ${{ needs.prepare-release.outputs.base_branch }} - run: | - echo "Branch: $BASE_BRANCH" - echo "Current version in package.json:" - cat package.json | grep '"version"' - echo "" - echo "Latest commit:" - git log -1 --oneline - - - name: Setup Node.js - uses: actions/setup-node@v7 - with: - node-version: 22.x - registry-url: 'https://registry.npmjs.org' - - - name: Ensure npm 11.5.1+ for trusted publishing - run: | - echo "Current npm version: $(npm --version)" - npm install -g npm@11.5.1 - echo "Updated npm version: $(npm --version)" - - - name: Download artifacts - uses: actions/download-artifact@v8 - with: - name: dist - path: . - - - name: Get version - id: version - run: | - VERSION=$(node -p "require('./package.json').version") - echo "version=$VERSION" >> $GITHUB_OUTPUT - - - name: Verify release PR was merged - env: - VERSION: ${{ steps.version.outputs.version }} - EXPECTED_VERSION: ${{ needs.prepare-release.outputs.version }} - BASE_BRANCH: ${{ needs.prepare-release.outputs.base_branch }} - run: | - echo "Version in $BASE_BRANCH: $VERSION" - echo "Expected version from PR: $EXPECTED_VERSION" - - if [ "$VERSION" != "$EXPECTED_VERSION" ]; then - echo "" - echo "❌ ERROR: Version mismatch!" - echo "" - echo "The release PR has NOT been merged yet." - echo "$BASE_BRANCH has: $VERSION" - echo "Release PR has: $EXPECTED_VERSION" - echo "" - echo "Please MERGE the release PR first, then approve this deployment." - echo "" - exit 1 - fi - - echo "Version matches - PR was merged correctly" - - - name: Install dependencies - run: npm ci - - - name: Build package - run: npm run build - - - name: Publish to npm (using OIDC trusted publishing) - env: - DIST_TAG: ${{ needs.prepare-release.outputs.dist_tag }} - run: | - echo "Publishing with OIDC trusted publishing..." - echo "No NPM_TOKEN needed - using GitHub OIDC" - echo "Dist tag: $DIST_TAG" - npm publish --access public --provenance --tag "$DIST_TAG" - - - name: Create and push tag - env: - VERSION: ${{ steps.version.outputs.version }} - run: | - git config --global user.name "github-actions[bot]" - git config --global user.email "github-actions[bot]@users.noreply.github.com" - git tag -a "v$VERSION" -m "Release v$VERSION" - git push origin "v$VERSION" - - - name: Create GitHub Release - uses: softprops/action-gh-release@v3 - env: - VERSION: ${{ steps.version.outputs.version }} - GITHUB_REPOSITORY: ${{ github.repository }} - with: - tag_name: v${{ steps.version.outputs.version }} - name: AgentCore CLI v${{ steps.version.outputs.version }} - files: '*.tgz' - generate_release_notes: true - prerelease: false - make_latest: false - body: | - ## Installation - - ```bash - npm install -g @aws/agentcore@${{ steps.version.outputs.version }} - ``` - - ## What's Changed - See the [full changelog](https://github.com/${{ github.repository }}/compare/v${{ steps.version.outputs.version }}...${{ needs.prepare-release.outputs.base_branch }}) for details.