Skip to content

Commit cea622c

Browse files
committed
docs: update contributing guidelines to clarify release automation and required secrets
1 parent e131e4a commit cea622c

3 files changed

Lines changed: 101 additions & 10 deletions

File tree

.github/workflows/CI.yml

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,6 @@ name: CI
22

33
on:
44
push:
5-
branches:
6-
- main
7-
- master
85
tags:
96
- "v*"
107
pull_request:
@@ -221,16 +218,45 @@ jobs:
221218
id-token: write
222219
contents: read
223220
steps:
221+
- name: Log release context
222+
run: |
223+
echo "event=${GITHUB_EVENT_NAME}"
224+
echo "ref=${GITHUB_REF}"
225+
echo "sha=${GITHUB_SHA}"
226+
224227
- name: Download wheel artifacts
225228
uses: actions/download-artifact@v4
226229
with:
227230
pattern: wheels-*
228231
merge-multiple: true
229232
path: dist
233+
234+
- name: Ensure PyPI token exists
235+
env:
236+
UV_PUBLISH_TOKEN: ${{ secrets.PYPI_API_TOKEN }}
237+
run: |
238+
if [ -z "${UV_PUBLISH_TOKEN}" ]; then
239+
echo "::error::Missing PYPI_API_TOKEN secret."
240+
exit 1
241+
fi
242+
243+
- name: Validate release artifacts
244+
run: |
245+
set -euo pipefail
246+
shopt -s nullglob
247+
files=(dist/*)
248+
if [ ${#files[@]} -eq 0 ]; then
249+
echo "::error::No artifacts found in dist/."
250+
exit 1
251+
fi
252+
printf '%s\n' "${files[@]}"
253+
230254
- uses: actions/setup-python@v5
231255
with:
232256
python-version: "3.12"
257+
233258
- uses: astral-sh/setup-uv@v5
259+
234260
- name: Publish artifacts
235261
run: uv publish dist/*
236262
env:

.github/workflows/release.yml

Lines changed: 63 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
name: Semantic Release
22

33
on:
4-
push:
4+
pull_request:
55
branches:
66
- main
7+
types:
8+
- closed
79
workflow_dispatch:
810

911
permissions:
@@ -15,30 +17,87 @@ concurrency:
1517

1618
jobs:
1719
release:
18-
if: github.actor != 'github-actions[bot]'
20+
if: >-
21+
${{
22+
github.event_name == 'workflow_dispatch' ||
23+
(
24+
github.event_name == 'pull_request' &&
25+
github.event.pull_request.merged == true &&
26+
github.event.pull_request.base.ref == 'main' &&
27+
github.event.pull_request.head.ref == 'dev'
28+
)
29+
}}
1930
runs-on: ubuntu-latest
2031
steps:
32+
- name: Log trigger context
33+
run: |
34+
echo "event=${GITHUB_EVENT_NAME}"
35+
echo "ref=${GITHUB_REF}"
36+
echo "actor=${GITHUB_ACTOR}"
37+
echo "pr_merged=${{ github.event.pull_request.merged }}"
38+
echo "pr_base=${{ github.event.pull_request.base.ref }}"
39+
echo "pr_head=${{ github.event.pull_request.head.ref }}"
40+
41+
- name: Ensure release push token exists
42+
env:
43+
RELEASE_PUSH_TOKEN: ${{ secrets.RELEASE_PUSH_TOKEN }}
44+
run: |
45+
if [ -z "${RELEASE_PUSH_TOKEN}" ]; then
46+
echo "::error::Missing RELEASE_PUSH_TOKEN secret."
47+
exit 1
48+
fi
49+
2150
- uses: actions/checkout@v4
2251
with:
52+
ref: main
2353
fetch-depth: 0
2454
submodules: recursive
55+
persist-credentials: false
2556

2657
- uses: actions/setup-python@v5
2758
with:
2859
python-version: "3.12"
2960

3061
- uses: astral-sh/setup-uv@v5
3162

63+
- name: Configure authenticated remote
64+
env:
65+
RELEASE_PUSH_TOKEN: ${{ secrets.RELEASE_PUSH_TOKEN }}
66+
run: git remote set-url origin "https://x-access-token:${RELEASE_PUSH_TOKEN}@github.com/${GITHUB_REPOSITORY}.git"
67+
3268
- name: Configure git identity
3369
run: |
3470
git config user.name "github-actions[bot]"
3571
git config user.email "github-actions[bot]@users.noreply.github.com"
3672
73+
- name: Capture release baseline
74+
id: baseline
75+
run: |
76+
echo "sha=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT"
77+
echo "tag=$(git describe --tags --abbrev=0 2>/dev/null || true)" >> "$GITHUB_OUTPUT"
78+
3779
- name: Run semantic release
3880
env:
39-
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
40-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
81+
GH_TOKEN: ${{ secrets.RELEASE_PUSH_TOKEN }}
82+
GITHUB_TOKEN: ${{ secrets.RELEASE_PUSH_TOKEN }}
4183
run: uv run --no-project --with python-semantic-release==9.21.1 semantic-release version
4284

4385
- name: Push release commit and tags
4486
run: git push --follow-tags origin HEAD:main
87+
88+
- name: Summarize release outcome
89+
run: |
90+
set -euo pipefail
91+
after_sha=$(git rev-parse HEAD)
92+
after_tag=$(git describe --tags --abbrev=0 2>/dev/null || true)
93+
94+
echo "before_sha=${{ steps.baseline.outputs.sha }}"
95+
echo "after_sha=${after_sha}"
96+
echo "before_tag=${{ steps.baseline.outputs.tag }}"
97+
echo "after_tag=${after_tag}"
98+
99+
if [ "${after_sha}" = "${{ steps.baseline.outputs.sha }}" ] && [ "${after_tag}" = "${{ steps.baseline.outputs.tag }}" ]; then
100+
echo "No new release generated from this merge."
101+
else
102+
echo "Release generated. Latest tag: ${after_tag:-none}"
103+
fi

CONTRIBUTING.md

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,12 @@ Include:
8989

9090
## Release Flow Overview
9191

92-
- Every merge to `main` is evaluated by semantic release.
93-
- If commits qualify (`feat`, `fix`, `perf`, or breaking), version and changelog are updated automatically.
94-
- New tags (`vX.Y.Z`) trigger multi-platform wheel builds and PyPI publish.
92+
- Release automation runs when a PR from `dev` into `main` is merged.
93+
- Semantic release evaluates Conventional Commits from merged changes.
94+
- If commits qualify (`feat`, `fix`, `perf`, or breaking), version and changelog are updated and a new tag (`vX.Y.Z`) is created.
95+
- If commits do not qualify (for example docs/chore only), release is a no-op and no publish is triggered.
96+
- New `vX.Y.Z` tags trigger the CI workflow that builds multi-platform wheels and publishes to PyPI.
97+
98+
Required repository secrets:
99+
- `RELEASE_PUSH_TOKEN`: personal access token used by semantic-release workflow to push release commit and tags.
100+
- `PYPI_API_TOKEN`: token used by publish job to upload wheels/sdist to PyPI.

0 commit comments

Comments
 (0)