Skip to content

Commit 0e97834

Browse files
olivermeyerclaude
andcommitted
feat: add merge-release GitHub workflow and make target
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 455b80f commit 0e97834

3 files changed

Lines changed: 100 additions & 18 deletions

File tree

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
name: "Merge Release"
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
branch:
7+
description: 'Release branch to merge (e.g. "release/v1.1.0"). Auto-detected if omitted.'
8+
required: false
9+
type: string
10+
11+
permissions:
12+
contents: read
13+
14+
jobs:
15+
merge-release:
16+
runs-on: ubuntu-latest
17+
steps:
18+
- name: Generate GitHub App token
19+
id: app-token
20+
uses: actions/create-github-app-token@f8d387b68d61c58ab83c6c016672934102569859 # v3.0.0
21+
with:
22+
app-id: ${{ secrets.RELEASE_BOT_APP_ID }}
23+
private-key: ${{ secrets.RELEASE_BOT_PRIVATE_KEY }}
24+
25+
- name: Configure git identity
26+
run: |
27+
git config --global user.name "aignostics-release-bot[bot]"
28+
git config --global user.email "aignostics-release-bot[bot]@users.noreply.github.com"
29+
30+
- name: Checkout main
31+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
32+
with:
33+
token: ${{ steps.app-token.outputs.token }}
34+
ref: main
35+
fetch-depth: 0
36+
37+
- name: Resolve release branch
38+
id: branch
39+
run: |
40+
INPUT="${{ inputs.branch }}"
41+
if [ -n "$INPUT" ]; then
42+
BRANCH="$INPUT"
43+
else
44+
MATCHES=$(git ls-remote --heads origin 'release/v*' | awk '{print $2}' | sed 's|refs/heads/||')
45+
if [ -z "$MATCHES" ]; then
46+
echo "❌ No release/v* branches found."
47+
exit 1
48+
fi
49+
COUNT=$(echo "$MATCHES" | wc -l | tr -d ' ')
50+
if [ "$COUNT" -gt 1 ]; then
51+
echo "❌ Multiple release/v* branches found. Specify one explicitly:"
52+
echo "$MATCHES"
53+
exit 1
54+
fi
55+
BRANCH="$MATCHES"
56+
fi
57+
echo "branch=${BRANCH}" >> "$GITHUB_OUTPUT"
58+
echo "✅ Using release branch: ${BRANCH}"
59+
60+
- name: Fetch remote
61+
run: git fetch origin
62+
63+
- name: Merge release branch into main
64+
run: |
65+
BRANCH="${{ steps.branch.outputs.branch }}"
66+
git merge --no-ff "origin/${BRANCH}" -m "chore: merge ${BRANCH} into main"
67+
68+
- name: Push main
69+
run: git push origin main
70+
71+
- name: Delete remote release branch
72+
run: git push origin --delete "${{ steps.branch.outputs.branch }}"
73+
74+
- name: Print job summary
75+
run: |
76+
BRANCH="${{ steps.branch.outputs.branch }}"
77+
cat >> "$GITHUB_STEP_SUMMARY" << EOF
78+
## ✅ Release merged
79+
80+
| | |
81+
|---|---|
82+
| **Branch** | \`${BRANCH}\` |
83+
| **Merged into** | \`main\` |
84+
85+
The release branch has been merged into \`main\` and deleted.
86+
EOF

Makefile

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ $(error Python version validation failed. See error message above.)
2121
endif
2222

2323
# Define all PHONY targets
24-
.PHONY: act all audit bump clean codegen dist dist_native docs docker_build gui_watch install lint lint_fix merge-release pre_commit_run_all prepare-release profile publish-release setup test test_coverage_reset test_default test_e2e test_e2e_matrix test_integration test_integration_matrix test_long_running test_scheduled test_stress test_sequential test_unit test_unit_matrix test_very_long_running update_from_template
24+
.PHONY: act all audit clean codegen dist dist_native docs docker_build gui_watch install lint lint_fix merge-release pre_commit_run_all prepare-release profile publish-release setup test test_coverage_reset test_default test_e2e test_e2e_matrix test_integration test_integration_matrix test_long_running test_scheduled test_stress test_sequential test_unit test_unit_matrix test_very_long_running update_from_template
2525

2626

2727
# Main target i.e. default sessions defined in noxfile.py
@@ -47,7 +47,7 @@ else \
4747
fi
4848

4949
## Individual Nox sessions
50-
act audit bump dist docs lint lint_fix setup test update_from_template:
50+
act audit dist docs lint lint_fix setup test update_from_template:
5151
$(nox-cmd)
5252

5353
# Standalone targets
@@ -125,6 +125,17 @@ publish-release:
125125
fi
126126
@echo "Workflow triggered. Monitor at: https://github.com/aignostics/python-sdk/actions"
127127

128+
## Trigger the merge-release GitHub workflow to merge release/vX.Y.Z into main and delete the branch
129+
## Usage: make merge-release [release/vX.Y.Z]
130+
merge-release:
131+
$(eval BRANCH := $(filter-out $@,$(MAKECMDGOALS)))
132+
@if [ -n "$(BRANCH)" ]; then \
133+
gh workflow run merge-release.yml --field branch=$(BRANCH); \
134+
else \
135+
gh workflow run merge-release.yml; \
136+
fi
137+
@echo "Workflow triggered. Monitor at: https://github.com/aignostics/python-sdk/actions"
138+
128139
## Clean build artifacts and caches
129140
clean:
130141
rm -rf .mypy_cache
@@ -214,9 +225,9 @@ help:
214225
@echo " act - Run GitHub actions locally via act"
215226
@echo " all - Run all default nox sessions, i.e. lint, test, docs, audit"
216227
@echo " audit - Run security and license compliance audit"
217-
@echo " bump patch|minor|major|x.y.z - Bump version (local, legacy)"
218228
@echo " prepare-release patch|minor|major|x.y.z - Create release/vX.Y.Z branch via GitHub workflow"
219229
@echo " publish-release [release/vX.Y.Z] - Generate changelog, tag, and push via GitHub workflow"
230+
@echo " merge-release [release/vX.Y.Z] - Merge release branch into main and delete it via GitHub workflow"
220231
@echo " clean - Clean build artifacts and caches"
221232
@echo " codegen - Download openapi.json from Aignostics platform, generate API code"
222233
@echo " dist - Build wheel and sdist into dist/"

noxfile.py

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1023,21 +1023,6 @@ def act(session: nox.Session) -> None:
10231023
)
10241024

10251025

1026-
@nox.session(default=False)
1027-
def bump(session: nox.Session) -> None:
1028-
"""Bump version and push changes to git."""
1029-
version_part = session.posargs[0] if session.posargs else "patch"
1030-
1031-
# Check if the version_part is a specific version (e.g., 1.2.3)
1032-
if re.match(r"^\d+\.\d+\.\d+$", version_part):
1033-
session.run("bump-my-version", "bump", "--new-version", version_part, external=True)
1034-
else:
1035-
session.run("bump-my-version", "bump", version_part, external=True)
1036-
1037-
# Push changes to git including tag created
1038-
session.run("git", "push", "--follow-tags", "--no-verify", external=True)
1039-
1040-
10411026
@nox.session()
10421027
def dist(session: nox.Session) -> None:
10431028
"""Build wheel and put in dist/."""

0 commit comments

Comments
 (0)