Cut Release #1
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # AgentOps Toolkit — Cut Release | |
| # | |
| # Workflows: | |
| # 1. ci.yml — Lint + test on every push/PR | |
| # 2. _build.yml — Reusable build (test + package), called by staging and release | |
| # 3. staging.yml — Staging: release/* branch → TestPyPI → verify | |
| # 4. release.yml — Production: v* tag → TestPyPI → verify → PyPI → GitHub Release | |
| # 5. cut-release.yml — Manual dispatch: create release branch + PR from develop | |
| # | |
| # One-click release branch creation. Triggered manually from the Actions tab. | |
| # Creates a release branch from develop, updates CHANGELOG.md, and opens a PR to main. | |
| # The branch push then triggers staging.yml automatically. | |
| # | |
| # Usage: | |
| # Actions tab → "Cut Release" → "Run workflow" → enter version (e.g. 0.2.0) | |
| name: Cut Release | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| version: | |
| description: "Release version (e.g. 0.2.0) — no 'v' prefix" | |
| required: true | |
| type: string | |
| permissions: | |
| contents: write | |
| pull-requests: write | |
| jobs: | |
| cut-release: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Validate version format | |
| run: | | |
| VERSION="${{ inputs.version }}" | |
| if [[ ! "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then | |
| echo "::error::Version must be in semver format (e.g. 0.2.0), got: $VERSION" | |
| exit 1 | |
| fi | |
| echo "version=$VERSION" >> "$GITHUB_ENV" | |
| - name: Checkout develop | |
| uses: actions/checkout@v4 | |
| with: | |
| ref: develop | |
| fetch-depth: 0 | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Check release branch does not exist | |
| run: | | |
| if git ls-remote --exit-code origin "refs/heads/release/v${{ env.version }}" >/dev/null 2>&1; then | |
| echo "::error::Branch release/v${{ env.version }} already exists. Delete it first or use a different version." | |
| exit 1 | |
| fi | |
| - name: Check CHANGELOG has Unreleased section | |
| run: | | |
| if ! grep -q '## \[Unreleased\]' CHANGELOG.md; then | |
| echo "::error::CHANGELOG.md is missing the [Unreleased] section." | |
| exit 1 | |
| fi | |
| - name: Create release branch | |
| run: | | |
| git checkout -b "release/v${{ env.version }}" | |
| - name: Update CHANGELOG | |
| run: | | |
| DATE=$(date +%Y-%m-%d) | |
| # Replace [Unreleased] with versioned section, add fresh Unreleased above | |
| sed -i "s/## \[Unreleased\]/## [Unreleased]\n\n## [${{ env.version }}] - $DATE/" CHANGELOG.md | |
| - name: Configure git | |
| run: | | |
| git config user.name "github-actions[bot]" | |
| git config user.email "41898282+github-actions[bot]@users.noreply.github.com" | |
| - name: Commit and push | |
| run: | | |
| git add CHANGELOG.md | |
| git commit -m "chore: prepare release ${{ env.version }}" | |
| git push origin "release/v${{ env.version }}" | |
| - name: Create PR to main | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| gh pr create \ | |
| --base main \ | |
| --head "release/v${{ env.version }}" \ | |
| --title "Release v${{ env.version }}" \ | |
| --body "## Release v${{ env.version }} | |
| Automated release branch created from \`develop\`. | |
| ### What happened | |
| - Branch \`release/v${{ env.version }}\` created from \`develop\` | |
| - \`CHANGELOG.md\` updated: \`[Unreleased]\` → \`[${{ env.version }}]\` | |
| - Staging pipeline triggered automatically (build → TestPyPI → verify) | |
| ### Next steps | |
| 1. Wait for the **Staging** pipeline to pass | |
| 2. Review and approve this PR | |
| 3. Merge to \`main\` | |
| 4. Tag and push: \`git tag v${{ env.version }} && git push origin v${{ env.version }}\` | |
| 5. Approve the PyPI publish in the **Release** workflow | |
| 6. Sync develop: \`git checkout develop && git merge main && git push origin develop\` | |
| ### Checklist | |
| - [ ] Staging pipeline passes (build + TestPyPI + verify) | |
| - [ ] CHANGELOG entries reviewed | |
| - [ ] PR approved and merged to main | |
| - [ ] Tag \`v${{ env.version }}\` pushed | |
| - [ ] PyPI publish approved | |
| - [ ] develop synced from main" | |
| - name: Summary | |
| run: | | |
| echo "## ✅ Release branch created" >> "$GITHUB_STEP_SUMMARY" | |
| echo "" >> "$GITHUB_STEP_SUMMARY" | |
| echo "- Branch: \`release/v${{ env.version }}\`" >> "$GITHUB_STEP_SUMMARY" | |
| echo "- CHANGELOG updated with version **${{ env.version }}**" >> "$GITHUB_STEP_SUMMARY" | |
| echo "- PR opened: \`release/v${{ env.version }}\` → \`main\`" >> "$GITHUB_STEP_SUMMARY" | |
| echo "- Staging pipeline triggered automatically" >> "$GITHUB_STEP_SUMMARY" | |
| echo "" >> "$GITHUB_STEP_SUMMARY" | |
| echo "### Next: wait for staging, then tag \`v${{ env.version }}\` to publish" >> "$GITHUB_STEP_SUMMARY" |