Skip to content

Commit 455b80f

Browse files
committed
feat: add publish-release GitHub workflow and make target
1 parent d601e16 commit 455b80f

2 files changed

Lines changed: 150 additions & 1 deletion

File tree

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
name: "Publish Release"
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
branch:
7+
description: 'Release branch name (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+
publish-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
31+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
32+
with:
33+
token: ${{ steps.app-token.outputs.token }}
34+
fetch-depth: 0
35+
36+
- name: Resolve release branch
37+
id: branch
38+
run: |
39+
INPUT="${{ inputs.branch }}"
40+
if [ -n "$INPUT" ]; then
41+
BRANCH="$INPUT"
42+
else
43+
MATCHES=$(git ls-remote --heads origin 'release/v*' | awk '{print $2}' | sed 's|refs/heads/||')
44+
if [ -z "$MATCHES" ]; then
45+
echo "❌ No release/v* branches found. Run 'make prepare-release' first."
46+
exit 1
47+
fi
48+
COUNT=$(echo "$MATCHES" | wc -l | tr -d ' ')
49+
if [ "$COUNT" -gt 1 ]; then
50+
echo "❌ Multiple release/v* branches found. Specify one explicitly:"
51+
echo "$MATCHES"
52+
exit 1
53+
fi
54+
BRANCH="$MATCHES"
55+
fi
56+
echo "branch=${BRANCH}" >> "$GITHUB_OUTPUT"
57+
echo "✅ Using release branch: ${BRANCH}"
58+
59+
- name: Checkout release branch
60+
run: git checkout "${{ steps.branch.outputs.branch }}"
61+
62+
- name: Install uv
63+
uses: astral-sh/setup-uv@cec208311dfd045dd5311c1add060b2062131d57 # v8.0.0
64+
with:
65+
version-file: "pyproject.toml"
66+
enable-cache: true
67+
cache-dependency-glob: uv.lock
68+
69+
- name: Install dependencies
70+
run: uv sync --frozen
71+
72+
- name: Read version info
73+
id: version
74+
run: |
75+
NEW_VERSION=$(cat VERSION)
76+
TAG_NAME="v${NEW_VERSION}"
77+
PREV_TAG=$(git describe --abbrev=0 HEAD^ 2>/dev/null || echo "")
78+
if [ -n "$PREV_TAG" ]; then
79+
PREV_VERSION="${PREV_TAG#v}"
80+
else
81+
PREV_VERSION="(initial)"
82+
fi
83+
echo "new_version=${NEW_VERSION}" >> "$GITHUB_OUTPUT"
84+
echo "tag_name=${TAG_NAME}" >> "$GITHUB_OUTPUT"
85+
echo "prev_tag=${PREV_TAG}" >> "$GITHUB_OUTPUT"
86+
echo "prev_version=${PREV_VERSION}" >> "$GITHUB_OUTPUT"
87+
88+
- name: Generate changelog
89+
run: |
90+
PREV_TAG="${{ steps.version.outputs.prev_tag }}"
91+
TAG_NAME="${{ steps.version.outputs.tag_name }}"
92+
if [ -n "$PREV_TAG" ]; then
93+
uv run git-cliff --tag "$TAG_NAME" "${PREV_TAG}..HEAD"
94+
else
95+
uv run git-cliff --tag "$TAG_NAME"
96+
fi
97+
98+
- name: Commit changelog
99+
run: |
100+
TAG_NAME="${{ steps.version.outputs.tag_name }}"
101+
git add CHANGELOG.md
102+
if git diff --staged --quiet; then
103+
echo "No changelog changes to commit."
104+
else
105+
git commit --no-verify -m "chore: update changelog for ${TAG_NAME}"
106+
fi
107+
108+
- name: Create annotated tag
109+
run: |
110+
git tag -a "${{ steps.version.outputs.tag_name }}" \
111+
-m "Bump version: ${{ steps.version.outputs.prev_version }} → ${{ steps.version.outputs.new_version }}"
112+
113+
- name: Push branch and tag
114+
run: git push origin "${{ steps.branch.outputs.branch }}" --follow-tags
115+
116+
- name: Print job summary
117+
run: |
118+
BRANCH="${{ steps.branch.outputs.branch }}"
119+
TAG_NAME="${{ steps.version.outputs.tag_name }}"
120+
cat >> "$GITHUB_STEP_SUMMARY" << EOF
121+
## ✅ Release published
122+
123+
| | |
124+
|---|---|
125+
| **Branch** | \`${BRANCH}\` |
126+
| **Tag** | \`${TAG_NAME}\` |
127+
| **Version** | ${{ steps.version.outputs.prev_version }} → ${{ steps.version.outputs.new_version }} |
128+
129+
### Next steps
130+
131+
1. Monitor the CI/CD pipeline triggered by the tag:
132+
[View CI runs](https://github.com/aignostics/python-sdk/actions)
133+
2. Once CI passes and the package is published, merge the release branch:
134+
\`\`\`bash
135+
make merge-release
136+
\`\`\`
137+
EOF

Makefile

Lines changed: 13 additions & 1 deletion
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 pre_commit_run_all prepare-release profile 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 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
2525

2626

2727
# Main target i.e. default sessions defined in noxfile.py
@@ -114,6 +114,17 @@ prepare-release:
114114
gh workflow run prepare-release.yml --field version_part=$(VERSION_PART)
115115
@echo "Workflow triggered. Monitor at: https://github.com/aignostics/python-sdk/actions"
116116

117+
## Trigger the publish-release GitHub workflow to generate changelog, tag, and push
118+
## Usage: make publish-release [release/vX.Y.Z]
119+
publish-release:
120+
$(eval BRANCH := $(filter-out $@,$(MAKECMDGOALS)))
121+
@if [ -n "$(BRANCH)" ]; then \
122+
gh workflow run publish-release.yml --field branch=$(BRANCH); \
123+
else \
124+
gh workflow run publish-release.yml; \
125+
fi
126+
@echo "Workflow triggered. Monitor at: https://github.com/aignostics/python-sdk/actions"
127+
117128
## Clean build artifacts and caches
118129
clean:
119130
rm -rf .mypy_cache
@@ -205,6 +216,7 @@ help:
205216
@echo " audit - Run security and license compliance audit"
206217
@echo " bump patch|minor|major|x.y.z - Bump version (local, legacy)"
207218
@echo " prepare-release patch|minor|major|x.y.z - Create release/vX.Y.Z branch via GitHub workflow"
219+
@echo " publish-release [release/vX.Y.Z] - Generate changelog, tag, and push via GitHub workflow"
208220
@echo " clean - Clean build artifacts and caches"
209221
@echo " codegen - Download openapi.json from Aignostics platform, generate API code"
210222
@echo " dist - Build wheel and sdist into dist/"

0 commit comments

Comments
 (0)