From d592efc023a8a17119fd38d0b7034ed3543f205b Mon Sep 17 00:00:00 2001 From: Roomote Date: Fri, 15 May 2026 22:47:50 +0000 Subject: [PATCH 1/2] chore: switch releases to a single PR flow --- .github/workflows/changeset-release.yml | 132 --------------------- .github/workflows/release-validation.yml | 87 ++++++++++++++ .roo/commands/release.md | 143 ++++++++++++++++------- 3 files changed, 191 insertions(+), 171 deletions(-) delete mode 100644 .github/workflows/changeset-release.yml create mode 100644 .github/workflows/release-validation.yml diff --git a/.github/workflows/changeset-release.yml b/.github/workflows/changeset-release.yml deleted file mode 100644 index 7c274b0639..0000000000 --- a/.github/workflows/changeset-release.yml +++ /dev/null @@ -1,132 +0,0 @@ -name: Changeset Release -run-name: Changeset Release ${{ github.actor != 'R00-B0T' && '- Create PR' || '- Update Changelog' }} - -on: - workflow_dispatch: - pull_request: - types: [closed, opened, labeled] - -env: - REPO_PATH: ${{ github.repository }} - GIT_REF: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || 'main' }} - -jobs: - # Job 1: Create version bump PR when changesets are merged to main - changeset-pr-version-bump: - if: > - ( github.event_name == 'pull_request' && - github.event.pull_request.merged == true && - github.event.pull_request.base.ref == 'main' && - github.actor != 'R00-B0T' ) || - github.event_name == 'workflow_dispatch' - runs-on: ubuntu-latest - permissions: - contents: write - pull-requests: write - steps: - - name: Git Checkout - uses: actions/checkout@v4 - with: - fetch-depth: 0 - ref: ${{ env.GIT_REF }} - - name: Setup Node.js and pnpm - uses: ./.github/actions/setup-node-pnpm - - # Check if there are any new changesets to process - - name: Check for changesets - id: check-changesets - run: | - NEW_CHANGESETS=$(find .changeset -name "*.md" ! -name "README.md" | wc -l | tr -d ' ') - echo "Changesets diff with previous version: $NEW_CHANGESETS" - echo "new_changesets=$NEW_CHANGESETS" >> $GITHUB_OUTPUT - - # Create version bump PR using changesets/action if there are new changesets - - name: Changeset Pull Request - if: steps.check-changesets.outputs.new_changesets != '0' - id: changesets - uses: changesets/action@v1 - with: - commit: "changeset version bump" - title: "Changeset version bump" - version: pnpm changeset:version # This performs the changeset version bump - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - # Job 2: Process version bump PR created by R00-B0T - changeset-pr-edit-approve: - name: Auto approve and merge Bump version PRs - runs-on: ubuntu-latest - permissions: - contents: write - pull-requests: write - if: > - github.event_name == 'pull_request' && - github.event.pull_request.base.ref == 'main' && - github.actor == 'R00-B0T' && - contains(github.event.pull_request.title, 'Changeset version bump') - steps: - - name: Determine checkout ref - id: checkout-ref - run: | - echo "Event action: ${{ github.event.action }}" - echo "Actor: ${{ github.actor }}" - echo "Head ref: ${{ github.head_ref }}" - echo "PR SHA: ${{ github.event.pull_request.head.sha }}" - - if [[ "${{ github.event.action }}" == "opened" && "${{ github.actor }}" == "R00-B0T" ]]; then - echo "Using branch ref: ${{ github.head_ref }}" - echo "git_ref=${{ github.head_ref }}" >> $GITHUB_OUTPUT - else - echo "Using SHA ref: ${{ github.event.pull_request.head.sha }}" - echo "git_ref=${{ github.event.pull_request.head.sha }}" >> $GITHUB_OUTPUT - fi - - - name: Checkout Repo - uses: actions/checkout@v4 - with: - token: ${{ secrets.GITHUB_TOKEN }} - fetch-depth: 0 - ref: ${{ steps.checkout-ref.outputs.git_ref }} - - # Commit and push changelog updates - - name: Push Changelog updates - if: ${{ !contains(github.event.pull_request.labels.*.name, 'changelog-ready') }} - run: | - git config user.name "R00-B0T" - git config user.email github-actions@github.com - echo "Running git add and commit..." - git add CHANGELOG.md - git commit -m "Updating CHANGELOG.md format" - git status - echo "--------------------------------------------------------------------------------" - echo "Pushing to remote..." - echo "--------------------------------------------------------------------------------" - git push - - # Add label to indicate changelog has been formatted - - name: Add changelog-ready label - if: ${{ !contains(github.event.pull_request.labels.*.name, 'changelog-ready') }} - uses: actions/github-script@v7 - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - script: | - await github.rest.issues.addLabels({ - owner: context.repo.owner, - repo: context.repo.repo, - issue_number: context.issue.number, - labels: ['changelog-ready'] - }); - - # Auto-approve PR only after it has been labeled - - name: Auto approve PR - if: contains(github.event.pull_request.labels.*.name, 'changelog-ready') - uses: hmarr/auto-approve-action@v4 - with: - review-message: "I'm approving since it's a bump version PR" - - # Auto-merge PR - - name: Automerge on PR - if: false # Needs enablePullRequestAutoMerge in repo settings to work contains(github.event.pull_request.labels.*.name, 'changelog-ready') - run: gh pr merge --auto --merge ${{ github.event.pull_request.number }} - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/release-validation.yml b/.github/workflows/release-validation.yml new file mode 100644 index 0000000000..83a3c07bec --- /dev/null +++ b/.github/workflows/release-validation.yml @@ -0,0 +1,87 @@ +name: Release Validation + +on: + workflow_dispatch: + pull_request: + types: [opened, reopened, synchronize, ready_for_review] + paths: + - "CHANGELOG.md" + - "README.md" + - "src/package.json" + - "src/CHANGELOG.md" + - "src/core/webview/ClineProvider.ts" + - "webview-ui/src/components/chat/Announcement.tsx" + - "releases/**" + - ".github/workflows/release-validation.yml" + +jobs: + validate-release: + runs-on: ubuntu-latest + permissions: + contents: read + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup Node.js and pnpm + uses: ./.github/actions/setup-node-pnpm + with: + install-args: "--frozen-lockfile" + + - name: Validate package identity + run: | + package_name=$(node -p "require('./src/package.json').name") + publisher=$(node -p "require('./src/package.json').publisher") + + test "$package_name" = "zoo-code" + test "$publisher" = "ZooCodeOrganization" + + - name: Validate release metadata + run: | + package_version=$(node -p "require('./src/package.json').version") + + node -e 'const version = process.argv[1]; if (!/^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?$/.test(version)) { throw new Error("Invalid SemVer version: " + version) }' "$package_version" + grep -q "## \\[$package_version\\]\\|## $package_version" CHANGELOG.md + + - name: Build workspace packages + run: | + pnpm --filter @roo-code/build build + pnpm --filter @roo-code/vscode-webview build + + - name: Bundle extension and verify README sync + env: + POSTHOG_API_KEY: ${{ secrets.POSTHOG_API_KEY }} + run: | + pnpm --filter ./src bundle --production + cmp README.md src/README.md + + - name: Package extension + env: + POSTHOG_API_KEY: ${{ secrets.POSTHOG_API_KEY }} + run: | + package_version=$(node -p "require('./src/package.json').version") + pnpm --filter ./src vsix + + vsix_path="bin/zoo-code-${package_version}.vsix" + test -f "$vsix_path" + + unzip -l "$vsix_path" > /tmp/zoo-code-vsix-contents.txt + grep -q "extension/package.json" /tmp/zoo-code-vsix-contents.txt + grep -q "extension/package.nls.json" /tmp/zoo-code-vsix-contents.txt + grep -q "extension/dist/extension.js" /tmp/zoo-code-vsix-contents.txt + grep -q "extension/webview-ui/audio/celebration.wav" /tmp/zoo-code-vsix-contents.txt + grep -q "extension/webview-ui/build/assets/index.js" /tmp/zoo-code-vsix-contents.txt + grep -q "extension/assets/codicons/codicon.ttf" /tmp/zoo-code-vsix-contents.txt + grep -q "extension/assets/vscode-material-icons/icons/3d.svg" /tmp/zoo-code-vsix-contents.txt + + - name: Validate packaged manifest identity + run: | + package_version=$(node -p "require('./src/package.json').version") + vsix_path="bin/zoo-code-${package_version}.vsix" + + artifact_name=$(unzip -p "$vsix_path" extension/package.json | jq -r '.name') + artifact_publisher=$(unzip -p "$vsix_path" extension/package.json | jq -r '.publisher') + + test "$artifact_name" = "zoo-code" + test "$artifact_publisher" = "ZooCodeOrganization" diff --git a/.roo/commands/release.md b/.roo/commands/release.md index 2e09783a58..38bd70b4b1 100644 --- a/.roo/commands/release.md +++ b/.roo/commands/release.md @@ -1,45 +1,110 @@ --- -description: "Create a new release of the Roo Code extension" +description: "Prepare a new release of the Zoo Code extension" argument-hint: patch | minor | major mode: code --- -1. Identify the SHA corresponding to the most recent release using GitHub CLI: `gh release view --json tagName,targetCommitish,publishedAt` -2. Analyze changes since the last release using: `gh pr list --state merged --base main --json number,title,author,url,mergedAt,closingIssuesReferences --limit 1000 -q '[.[] | select(.mergedAt > "TIMESTAMP") | {number, title, author: .author.login, url, mergedAt, issues: .closingIssuesReferences}] | sort_by(.number)'` -3. For each PR with linked issues, fetch the issue details to get the issue reporter: `gh issue view ISSUE_NUMBER --json number,author -q '{number, reporter: .author.login}'` -4. Summarize the changes. If the user did not specify, ask them whether this should be a major, minor, or patch release. -5. Create a changeset in .changeset/v[version].md instead of directly modifying package.json. The format is: +1. Identify the most recent stable extension release: -``` ---- -"roo-cline": patch|minor|major ---- -[list of changes] -``` - -- Always include contributor attribution and the PR number: use "(PR # by @username)". -- For PRs that close issues, include both the issue number and the PR number and authors: "- Fix: Description (#123 by @reporter, PR #456 by @contributor)" -- For PRs without linked issues, include the PR number and author: "- Add support for feature (PR #456 by @contributor)" -- Provide brief descriptions of each item to explain the change -- Order the list from most important to least important -- Example formats: - - With issue: "- Fix: Resolve memory leak in extension (#456 by @issueReporter, PR #789 by @prAuthor)" - - Without issue: "- Add support for Gemini 2.5 Pro caching (PR #789 by @contributor)" -- CRITICAL: Include EVERY SINGLE PR in the changeset - don't assume you know which ones are important. Count the total PRs to verify completeness and cross-reference the list to ensure nothing is missed. - -6. If the generate_image tool is available, create a release image at `releases/[version]-release.png` - - The image should feature a realistic-looking kangaroo doing something human-like that relates to the main highlight of the release - - Pass `releases/template.png` as the reference image for aspect ratio and kangaroo style - - Add the generated image to .changeset/v[version].md before the list of changes with format: `![X.Y.Z Release - Description](/releases/X.Y.Z-release.png)` -7. If a major or minor release: - - Ask the user what the three most important areas to highlight are in the release - - Update the English version relevant announcement files and documentation (webview-ui/src/components/chat/Announcement.tsx, README.md, and the `latestAnnouncementId` in src/core/webview/ClineProvider.ts) - - Ask the user to confirm that the English version looks good to them before proceeding - - Use the new_task tool to create a subtask in `translate` mode with detailed instructions of which content needs to be translated into all supported languages (The READMEs as well as the translation strings) -8. Create a new branch for the release preparation: `git checkout -b release/v[version]` -9. Commit and push the changeset file and any documentation updates to the repository: `git add . && git commit -m "chore: add changeset for v[version]" && git push origin release/v[version]` -10. Create a pull request for the release: `gh pr create --title "Release v[version]" --body "Release preparation for v[version]. This PR includes the changeset and any necessary documentation updates." --base main --head release/v[version]` -11. The GitHub Actions workflow will automatically: - - Create a version bump PR when changesets are merged to main - - Update the CHANGELOG.md with proper formatting - - Publish the release when the version bump PR is merged + ```bash + gh release view --json tagName,targetCommitish,publishedAt + ``` + +2. Analyze changes since that release: + + ```bash + gh pr list --state merged --base main --json number,title,author,url,mergedAt,closingIssuesReferences --limit 1000 -q '[.[] | select(.mergedAt > "TIMESTAMP") | {number, title, author: .author.login, url, mergedAt, issues: .closingIssuesReferences}] | sort_by(.number)' + ``` + +3. For each PR with linked issues, fetch the issue reporter: + + ```bash + gh issue view ISSUE_NUMBER --json number,author -q '{number, reporter: .author.login}' + ``` + +4. Summarize the changes. If the user did not specify a release type, ask whether this should be a major, minor, or patch release. + +5. Review and update the Marketplace-facing root `README.md`. + + - Treat root `README.md` as the source of truth for Marketplace content. + - Update the "What's New" section for the release when appropriate. + - Do not manually edit `src/README.md`; the extension bundle step copies root `README.md` into `src/README.md`. + - Check for stale upstream Roo Code wording that should now say Zoo Code. + +6. Draft the release notes in a temporary changeset file at `.changeset/v[version].md`. Use this as the input to `pnpm changeset:version`; it will be consumed on the release branch before the PR is opened. + + ```md + --- + "zoo-code": patch|minor|major + --- + + [list of changes] + ``` + + - Always include contributor attribution and the PR number: use `(PR # by @username)`. + - For PRs that close issues, include both issue and PR authors: `- Fix: Description (#123 by @reporter, PR #456 by @contributor)`. + - For PRs without linked issues, include the PR number and author: `- Add support for feature (PR #456 by @contributor)`. + - Provide brief descriptions of each item to explain the change. + - Order the list from most important to least important. + - Include every PR in the release window. Count the PRs and cross-reference the list before continuing. + +7. If an image generation tool is available, create a release image at `releases/[version]-release.png`. + + - The image should relate to the main release highlight and fit the existing release-image style. + - Add the generated image to `.changeset/v[version].md` before the list of changes: + + ```md + ![X.Y.Z Release - Description](/releases/X.Y.Z-release.png) + ``` + +8. For a major or minor release: + + - Ask the user what three areas should be highlighted. + - Update relevant announcement files and documentation, including `webview-ui/src/components/chat/Announcement.tsx`, `README.md`, and the `latestAnnouncementId` in `src/core/webview/ClineProvider.ts`. + - Ask the user to confirm the English announcement before proceeding. + - Arrange translation updates for all supported locales affected by README, announcement, or package localization changes. + +9. Create the release branch: + + ```bash + git checkout -b release/v[version] + ``` + +10. Generate the final release state on that branch: + + ```bash + pnpm changeset:version + ``` + + - This should update `src/package.json`, `CHANGELOG.md`, and `src/CHANGELOG.md`, then consume the temporary `.changeset` file. + - Review the generated version and changelog before opening the PR. + +11. Open a single release PR with the fully generated release state. + + ```bash + git add CHANGELOG.md src/CHANGELOG.md src/package.json README.md + # If generated or updated: + git add releases/[version]-release.png webview-ui/src/components/chat/Announcement.tsx src/core/webview/ClineProvider.ts + git commit -m "chore: prepare v[version] release" + git push origin release/v[version] + gh pr create --title "Release v[version]" --body "Release preparation for v[version]. This PR includes the final version bump, changelog updates, Marketplace README updates, and any release assets or announcement changes." --base main --head release/v[version] + ``` + + - There is no separate version-bump PR in this flow. + - The release PR should already contain the final version number and generated changelog updates. + - Let the release validation workflow and normal PR checks run before merge. + +12. After the release PR is merged, create the release tag on the resulting `main` commit: + + ```bash + git switch main + git pull origin main + git tag v[version] + git push origin v[version] + ``` + +13. The stable publish workflow runs from the `v[version]` tag. + + - Do not create the tag before the release PR is merged. + - The publish workflow validates that the tag version matches `src/package.json`. + - Marketplace and Open VSX publishing use the configured CI secrets. From f4ed4d011ef2ba0bf610f8539b2d807c0fa4abbb Mon Sep 17 00:00:00 2001 From: Roomote Date: Fri, 15 May 2026 22:59:14 +0000 Subject: [PATCH 2/2] chore: address release flow PR feedback --- .github/workflows/release-validation.yml | 2 ++ .roo/commands/release.md | 7 ++++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/.github/workflows/release-validation.yml b/.github/workflows/release-validation.yml index 83a3c07bec..c49a870855 100644 --- a/.github/workflows/release-validation.yml +++ b/.github/workflows/release-validation.yml @@ -7,8 +7,10 @@ on: paths: - "CHANGELOG.md" - "README.md" + - "locales/*/README.md" - "src/package.json" - "src/CHANGELOG.md" + - "src/package.nls*.json" - "src/core/webview/ClineProvider.ts" - "webview-ui/src/components/chat/Announcement.tsx" - "releases/**" diff --git a/.roo/commands/release.md b/.roo/commands/release.md index 38bd70b4b1..19c35c5082 100644 --- a/.roo/commands/release.md +++ b/.roo/commands/release.md @@ -31,7 +31,7 @@ mode: code - Do not manually edit `src/README.md`; the extension bundle step copies root `README.md` into `src/README.md`. - Check for stale upstream Roo Code wording that should now say Zoo Code. -6. Draft the release notes in a temporary changeset file at `.changeset/v[version].md`. Use this as the input to `pnpm changeset:version`; it will be consumed on the release branch before the PR is opened. +6. Create the release notes as a changeset file at `.changeset/v[version].md`, then run `pnpm changeset:version` on the release branch before opening the PR. ```md --- @@ -76,13 +76,13 @@ mode: code pnpm changeset:version ``` - - This should update `src/package.json`, `CHANGELOG.md`, and `src/CHANGELOG.md`, then consume the temporary `.changeset` file. + - This should update `src/package.json`, `CHANGELOG.md`, and `src/CHANGELOG.md`, then consume the `.changeset` file. - Review the generated version and changelog before opening the PR. 11. Open a single release PR with the fully generated release state. ```bash - git add CHANGELOG.md src/CHANGELOG.md src/package.json README.md + git add CHANGELOG.md src/CHANGELOG.md src/package.json README.md locales/*/README.md src/package.nls*.json # If generated or updated: git add releases/[version]-release.png webview-ui/src/components/chat/Announcement.tsx src/core/webview/ClineProvider.ts git commit -m "chore: prepare v[version] release" @@ -92,6 +92,7 @@ mode: code - There is no separate version-bump PR in this flow. - The release PR should already contain the final version number and generated changelog updates. + - If the release includes translated README or package-localization updates, include those files in the same PR. - Let the release validation workflow and normal PR checks run before merge. 12. After the release PR is merged, create the release tag on the resulting `main` commit: