Skip to content

Commit 2e46084

Browse files
kurodo3[bot]claude
authored andcommitted
refactor: merge publish.yml into release.yml; pin all action SHAs
The two-workflow chain (release.yml tags → publish.yml publishes on tag push) existed solely because GITHUB_TOKEN-authenticated pushes don't trigger other workflow runs. Now that they are a single workflow, the recursion guard is irrelevant — GITHUB_TOKEN with contents: write is enough to push the tag, so the GitHub App token and RELEASE_APP_* secrets are no longer needed. Merged structure (test → build → publish-testpypi → publish-pypi): - test: matrix 3.10/3.11/3.12, no fetch-depth needed - build: normalizes version once (job output), pushes tag, builds with hatch-vcs (fetch-depth: 0), uploads dist artifact - publish-testpypi: OIDC publish to TestPyPI - publish-pypi: OIDC publish to PyPI + GitHub Release (tag_name from build job output) All actions pinned to full commit SHAs: - actions/checkout 34e114876b0b11c390a56381ad16ebd13914f8d5 (v4) - astral-sh/setup-uv e58605a9b6da7c637471fab8847a5e5a6b8df081 (v5) - actions/upload-artifact ea165f8d65b6e75b540449e92b4886f43607fa02 (v4.6.2) - actions/download-artifact d3f86a106a0bac45b974a628896c90dbdf5c8093 (v4.3.0) - softprops/action-gh-release 3bb12739c298aeb8a4eeaf626c5b8d85266b0e65 (v2.6.2) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 532dc37 commit 2e46084

2 files changed

Lines changed: 108 additions & 120 deletions

File tree

.github/workflows/publish.yml

Lines changed: 0 additions & 104 deletions
This file was deleted.

.github/workflows/release.yml

Lines changed: 108 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,33 +8,125 @@ on:
88
required: true
99
type: string
1010

11+
# Minimal default; individual jobs declare only what they need.
12+
permissions:
13+
contents: read
14+
1115
jobs:
12-
release:
16+
test:
17+
name: Test (Python ${{ matrix.python-version }})
18+
runs-on: ubuntu-latest
19+
strategy:
20+
fail-fast: true
21+
matrix:
22+
python-version: ["3.10", "3.11", "3.12"]
23+
steps:
24+
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
25+
26+
- name: Install uv
27+
uses: astral-sh/setup-uv@e58605a9b6da7c637471fab8847a5e5a6b8df081 # v5
28+
29+
- name: Set up Python ${{ matrix.python-version }}
30+
run: uv python install ${{ matrix.python-version }}
31+
32+
- name: Install dependencies
33+
run: uv sync --dev --python ${{ matrix.python-version }}
34+
35+
- name: Run tests
36+
run: uv run --python ${{ matrix.python-version }} pytest tests/ -v
37+
38+
build:
39+
name: Build distribution
40+
needs: test
1341
runs-on: ubuntu-latest
1442
permissions:
15-
contents: write
43+
contents: write # required to push the release tag
44+
outputs:
45+
version: ${{ steps.normalize.outputs.version }}
1646
steps:
17-
- name: Generate GitHub App token
18-
id: app-token
19-
uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3
20-
with:
21-
app-id: ${{ secrets.RELEASE_APP_ID }}
22-
private-key: ${{ secrets.RELEASE_APP_PRIVATE_KEY }}
47+
# Strip a leading 'v' once here; all downstream steps use the output.
48+
- name: Normalize version
49+
id: normalize
50+
run: |
51+
VERSION="${{ inputs.version }}"
52+
VERSION="${VERSION#v}"
53+
echo "version=${VERSION}" >> "${GITHUB_OUTPUT}"
2354
2455
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
2556
with:
26-
token: ${{ steps.app-token.outputs.token }}
57+
fetch-depth: 0 # required: hatch-vcs derives the package version from git tags
2758

2859
- name: Configure git
2960
run: |
3061
git config user.name "github-actions[bot]"
3162
git config user.email "github-actions[bot]@users.noreply.github.com"
3263
33-
- name: Tag and push release
64+
- name: Tag release
3465
run: |
35-
# Strip a leading 'v' if the operator included one (e.g. "v0.3.0" → "0.3.0"),
36-
# then always prefix with 'v' so the tag is exactly "v0.3.0".
37-
VERSION="${{ inputs.version }}"
38-
VERSION="${VERSION#v}"
39-
git tag "v${VERSION}"
40-
git push origin "v${VERSION}"
66+
git tag "v${{ steps.normalize.outputs.version }}"
67+
git push origin "v${{ steps.normalize.outputs.version }}"
68+
69+
- name: Install uv
70+
uses: astral-sh/setup-uv@e58605a9b6da7c637471fab8847a5e5a6b8df081 # v5
71+
72+
- name: Build wheel and sdist
73+
run: uv build
74+
75+
- name: Upload dist artifact
76+
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
77+
with:
78+
name: dist
79+
path: dist/
80+
if-no-files-found: error
81+
82+
publish-testpypi:
83+
name: Publish → TestPyPI
84+
needs: build
85+
runs-on: ubuntu-latest
86+
environment:
87+
name: testpypi
88+
url: https://test.pypi.org/p/starfix
89+
permissions:
90+
id-token: write # required for OIDC trusted publishing
91+
steps:
92+
- name: Install uv
93+
uses: astral-sh/setup-uv@e58605a9b6da7c637471fab8847a5e5a6b8df081 # v5
94+
95+
- name: Download dist artifact
96+
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
97+
with:
98+
name: dist
99+
path: dist/
100+
101+
- name: Publish to TestPyPI
102+
run: uv publish --publish-url https://test.pypi.org/legacy/ dist/*
103+
104+
publish-pypi:
105+
name: Publish → PyPI
106+
needs: [build, publish-testpypi]
107+
runs-on: ubuntu-latest
108+
environment:
109+
name: pypi
110+
url: https://pypi.org/p/starfix
111+
permissions:
112+
id-token: write # required for OIDC trusted publishing
113+
contents: write # required for creating the GitHub Release
114+
steps:
115+
- name: Install uv
116+
uses: astral-sh/setup-uv@e58605a9b6da7c637471fab8847a5e5a6b8df081 # v5
117+
118+
- name: Download dist artifact
119+
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
120+
with:
121+
name: dist
122+
path: dist/
123+
124+
- name: Publish to PyPI
125+
run: uv publish dist/*
126+
127+
- name: Create GitHub Release
128+
uses: softprops/action-gh-release@3bb12739c298aeb8a4eeaf626c5b8d85266b0e65 # v2.6.2
129+
with:
130+
tag_name: "v${{ needs.build.outputs.version }}"
131+
generate_release_notes: true
132+
files: dist/*

0 commit comments

Comments
 (0)