Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 45 additions & 32 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,10 @@ env:
RUST_BACKTRACE: "1"

jobs:
# Dispatch-only: work out the next version. Nothing is written or pushed here — the
# version is stamped into each build's working tree, and only committed + tagged by
# `publish` after the builds succeed, so a failed build never bumps the version or
# leaves a dangling tag.
# Dispatch-only: work out the release version (strip +dev, then bump). Nothing is written or
# pushed here — the version is stamped into each build's working tree, and only the tag and the
# dev-bump branch are pushed by `publish` after the builds succeed, so a failed build never tags a
# release or pushes a bump branch.
compute:
if: github.event_name == 'workflow_dispatch'
runs-on: ubuntu-latest
Expand Down Expand Up @@ -179,9 +179,10 @@ jobs:
name: macos-arm64
path: dist/

# Runs only after both builds succeed. On dispatch it commits the version bump, tags,
# and pushes — so the version/tag only ever advance for a release that actually built.
# On a tag push there's nothing to commit; it just publishes at that tag.
# Runs only after both builds succeed. The release itself — tag + GitHub Release with the binaries
# — never touches main, so branch protection doesn't apply. The only change to main, advancing the
# `+dev` version marker, is pushed as a branch; the org blocks Actions from opening PRs, so a
# maintainer opens that PR (one click from the run summary) and merges it.
publish:
name: Publish Release
needs: [compute, build-linux, build-macos]
Expand All @@ -192,48 +193,60 @@ jobs:
(startsWith(github.ref, 'refs/tags/') || needs.compute.result == 'success')
runs-on: ubuntu-latest
timeout-minutes: 15
permissions:
contents: write # push the tag, create the release, push the dev-bump branch
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
fetch-depth: 0
token: ${{ secrets.GITHUB_TOKEN }}

# Dispatch only: now that the builds passed, commit the release version (matching the
# artifacts) and tag it, then reopen main on `<version>+dev` so development never sits on a
# bare released version. Both commits go up in one push; the tag points at the release commit.
- name: Commit release, tag, then reopen the dev version
if: needs.compute.outputs.version != ''
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"

stamp() {
perl -i -pe 'if (!$d && s/^version = ".*"/version = "'"$1"'"/) { $d = 1 }' Cargo.toml
perl -i -pe 'if ($h) { s/^version = .*/version = "'"$1"'"/; $h = 0 } $h = 1 if /^name = "agentcap"$/' Cargo.lock
}

stamp "${{ needs.compute.outputs.version }}"
git add Cargo.toml Cargo.lock
git commit -m "chore: release ${{ needs.compute.outputs.tag }}"
git tag "${{ needs.compute.outputs.tag }}"

stamp "${{ needs.compute.outputs.version }}+dev"
git add Cargo.toml Cargo.lock
git commit -m "chore: reopen dev (${{ needs.compute.outputs.version }}+dev)"
git push origin HEAD:main --tags

- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
path: artifacts
pattern: "{linux-*,macos-*}"
merge-multiple: true

- name: Create release
# Tag the released commit and publish the binaries. On dispatch we create + push the tag at the
# current main commit — tags aren't branch-protected, so this isn't blocked; on a manual tag
# push the tag already exists. The published binaries carry the computed version (stamped at
# build time); the tagged commit's Cargo.toml still shows the in-progress `+dev` marker.
- name: Tag and publish the release
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
TAG="${{ needs.compute.outputs.tag || github.ref_name }}"
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
git tag "$TAG"
git push origin "$TAG"
fi
gh release create "$TAG" artifacts/* \
--repo "${{ github.repository }}" \
--title "$TAG" \
--generate-notes

# Dispatch only: push a branch advancing main's version marker to `<version>+dev`. The org
# blocks Actions from opening PRs, so the workflow stops at the branch and surfaces a one-click
# "create PR" link in the run summary; a maintainer opens that PR and merges it.
- name: Push the dev-bump branch
if: needs.compute.outputs.version != ''
run: |
DEV="${{ needs.compute.outputs.version }}+dev"
BRANCH="chore/bump-dev-${{ needs.compute.outputs.version }}"
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git switch -c "$BRANCH"
perl -i -pe 'if (!$d && s/^version = ".*"/version = "'"$DEV"'"/) { $d = 1 }' Cargo.toml
perl -i -pe 'if ($h) { s/^version = .*/version = "'"$DEV"'"/; $h = 0 } $h = 1 if /^name = "agentcap"$/' Cargo.lock
git add Cargo.toml Cargo.lock
git commit -m "chore: bump version to $DEV"
git push --force origin "$BRANCH"
URL="${{ github.server_url }}/${{ github.repository }}/compare/main...${BRANCH}?expand=1"
{
echo "### Version bump ready"
echo ""
echo "Advance \`main\` to \`$DEV\`: open the PR from \`$BRANCH\`, then merge it."
echo ""
echo "[Create pull request →]($URL)"
} >> "$GITHUB_STEP_SUMMARY"
echo "Open the version-bump PR: $URL"