-
Notifications
You must be signed in to change notification settings - Fork 5
Add automated release workflow #72
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| name: Publish Release | ||
| on: | ||
| pull_request: | ||
| types: [closed] | ||
|
|
||
| # When a release PR is merged, create the corresponding GitHub release | ||
| # with the release notes from the PR body. | ||
| jobs: | ||
| publish: | ||
| if: | | ||
| github.event.pull_request.merged == true && | ||
| contains(github.event.pull_request.labels.*.name, 'release') && | ||
| startsWith(github.event.pull_request.head.ref, 'release/') | ||
| runs-on: ubuntu-24.04 | ||
| permissions: | ||
| contents: write | ||
| steps: | ||
| - name: Extract version from branch name | ||
| id: version | ||
| env: | ||
| HEAD_REF: ${{ github.event.pull_request.head.ref }} | ||
| run: | | ||
| version="${HEAD_REF#release/}" | ||
| echo "version=$version" >> "$GITHUB_OUTPUT" | ||
| echo "Publishing release: $version" | ||
|
|
||
| - name: Create GitHub Release | ||
| env: | ||
| GH_TOKEN: ${{ github.token }} | ||
| VERSION: ${{ steps.version.outputs.version }} | ||
| PR_NUMBER: ${{ github.event.pull_request.number }} | ||
| REPO: ${{ github.repository }} | ||
| run: | | ||
| pr_body=$(gh pr view "$PR_NUMBER" --repo "$REPO" --json body --jq .body) | ||
|
|
||
| gh release create "$VERSION" \ | ||
| --repo "$REPO" \ | ||
| --title "Release $VERSION" \ | ||
| --notes "$pr_body" |
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,89 @@ | ||
| --- | ||
| description: | | ||
| Automated release agent for this repository. Runs weekly to create a | ||
| release PR with release notes from git history since the last release. | ||
| The PR requires human review and approval before merge. When merged, | ||
| a separate workflow creates the GitHub release with the tag. | ||
|
|
||
| on: | ||
| schedule: weekly on monday | ||
| workflow_dispatch: | ||
|
|
||
| permissions: | ||
| contents: read | ||
| issues: read | ||
| pull-requests: read | ||
|
|
||
| model: claude-sonnet-4-5-20250929 | ||
| engine: | ||
| id: claude | ||
| tools: | ||
| bash: ["*"] | ||
| github: | ||
| toolsets: [default] | ||
|
|
||
| safe-outputs: | ||
| github-app: | ||
| client-id: ${{ vars.GH_AW_APP_CLIENT_ID }} | ||
| private-key: ${{ secrets.GH_AW_APP_PRIVATE_KEY }} | ||
| create-pull-request: | ||
| max: 1 | ||
| branch-prefix: release/ | ||
|
Comment on lines
+29
to
+31
|
||
| allowed-files: | ||
| - RELEASE-NOTES.md | ||
| noop: | ||
| missing-data: | ||
| --- | ||
|
|
||
| # Release Agent | ||
|
|
||
| This workflow runs weekly to create a release PR. | ||
|
|
||
| ## Your task | ||
|
|
||
| 1. **Check for existing release PRs**: Before doing anything else, run | ||
| `gh pr list --label release --state open --json number --jq length` | ||
| to check if a release PR is already open. If the count is non-zero, | ||
| use `noop` to report that a release PR is already open. | ||
|
|
||
| 2. **Fetch full history**: The checkout is shallow by default. Run | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Huh, really? Kind of weird, can we just configure that in GH-AW deterministically? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Checked; there's no frontmatter option for fetch depth. The compiler hardcodes |
||
| `git fetch --unshallow --tags` so that all tags and commit history | ||
| are available. | ||
|
|
||
| 3. **Determine the next version**: Run `scripts/next-version.sh` to get | ||
| the next version string (e.g., `v0.3.0`). | ||
|
|
||
| 4. **Generate release notes**: Use GitHub's release notes generation API | ||
| as a starting point: | ||
| ```bash | ||
| gh api repos/$GITHUB_REPOSITORY/releases/generate-notes \ | ||
| -f tag_name="<next-version>" \ | ||
| -f previous_tag_name="<last-tag>" \ | ||
| --jq .body | ||
| ``` | ||
| Then refine the output: group changes by category (Features, Bug Fixes, | ||
| Documentation, Dependencies, Other), add a brief summary at the top, | ||
| and highlight any breaking changes. | ||
|
|
||
| 5. **Write RELEASE-NOTES.md**: Write the final release notes to | ||
| `RELEASE-NOTES.md` at the repository root. This file is overwritten | ||
| each release. | ||
|
|
||
| 6. **Create the release PR**: Use the `create-pull-request` safe-output | ||
| with: | ||
| - **Title**: `Release <version>` (e.g., "Release v0.3.0") | ||
| - **Branch**: `<version>` (e.g., "v0.3.0") — the `release/` prefix | ||
| is added automatically by the branch-prefix setting | ||
| - **Body**: The release notes from RELEASE-NOTES.md | ||
| - **Labels**: `release` | ||
|
|
||
| 7. **Handle edge cases**: | ||
| - If there are no changes since the last release, use `noop` | ||
| - If you cannot determine the version or history, use `missing-data` | ||
|
|
||
| ## Constraints | ||
|
|
||
| - Never push directly to the default branch | ||
| - Only modify RELEASE-NOTES.md — do not touch other files | ||
| - Always include "Generated-by: AI" in the PR body | ||
| - Require human review for all releases | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| #!/bin/bash | ||
| # Determine the next release version by reading git tags. | ||
| # This project uses v0.x.0 minor releases. | ||
| set -euo pipefail | ||
|
|
||
| latest=$(git tag --list 'v*' --sort=-v:refname | head -1) | ||
|
|
||
| if [ -z "$latest" ]; then | ||
| echo "v0.1.0" | ||
| exit 0 | ||
| fi | ||
|
|
||
| # Strip leading 'v', split on '.', bump minor, reset patch | ||
| IFS='.' read -r major minor _patch <<< "${latest#v}" | ||
| echo "v${major}.$((minor + 1)).0" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(Do we need this stuff btw? doesn't the MCP server allow reads)