Skip to content

Commit 81407df

Browse files
committed
ci(github-workflows): fix release workflow, add sigstore signature, manual run
1 parent 11c2d0a commit 81407df

File tree

1 file changed

+243
-49
lines changed

1 file changed

+243
-49
lines changed

.github/workflows/create-release.yml

Lines changed: 243 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -8,102 +8,296 @@ name: 📦 Create Release GitHub and PyPI
88

99
on:
1010
workflow_dispatch:
11+
inputs: {version: {description: 'Release version (e.g., v1.3.0)', required: true}}
1112
push: {tags: ['*v[0-9]*']}
1213

14+
concurrency:
15+
group: ${{ github.workflow }}-${{ github.ref }}
16+
cancel-in-progress: true
17+
1318
jobs:
14-
build-release-assets:
15-
runs-on: ubuntu-latest
19+
build-python:
1620
permissions:
1721
contents: write
18-
strategy:
19-
fail-fast: true # Stop if any of the matrix builds fail
20-
matrix:
21-
os: [ubuntu-latest, windows-latest, macos-14, macos-12]
22-
arch: [amd64, arm64]
23-
python-version: ['3.9', '3.10', '3.11', '3.12']
24-
exclude:
25-
- {os: windows-latest, arch: arm64} # Windows doesn't support arm64 in this context
26-
- {os: macos-12, arch: arm64} # macos-12 runner is Intel Silicon
27-
- {os: macos-14, arch: amd64} # macos-14 runner is Apple M1 Silicon
28-
22+
runs-on: ubuntu-latest
2923
steps:
3024
- name: Checkout repository
3125
uses: actions/checkout@v4
3226

3327
- name: Set up Python
3428
uses: actions/setup-python@v5
3529
with:
36-
python-version: ${{ matrix.python-version }}
30+
python-version: '3.x'
3731
cache: pip
3832

39-
- name: Install dependencies
33+
- name: Set build environment
4034
run: |-
41-
python -m pip install --upgrade pip
42-
pip install build
35+
python -m venv venv
36+
source venv/bin/activate
37+
pip install --require-virtualenv --upgrade pip
38+
pip install --require-virtualenv build
4339
44-
- name: Build python wheels + package source code
45-
run: python -m build
40+
- name: Build a binary wheel and a source tarball
41+
run: |
42+
source venv/bin/activate
43+
python3 -m build
44+
ls -la dist/
4645
47-
- name: Upload builds
48-
uses: actions/upload-artifact@v3
46+
- name: Store the distribution packages
47+
uses: actions/upload-artifact@v4
4948
with:
50-
name: python-package-${{ matrix.python-version }}
49+
name: release-assets
5150
path: dist/*
5251

53-
create-release:
54-
needs: build-release-assets
52+
test-builds-linux:
53+
needs: [build-python]
54+
permissions:
55+
contents: read
56+
strategy:
57+
fail-fast: true
58+
matrix:
59+
python-version: ['3.9', '3.10', '3.11', '3.12']
5560
runs-on: ubuntu-latest
61+
steps:
62+
- name: Checkout repository
63+
uses: actions/checkout@v4
64+
with:
65+
fetch-depth: 1 # shallow
66+
67+
- name: Download all builds
68+
uses: actions/download-artifact@v4
69+
with:
70+
path: ./release-assets
71+
72+
- uses: getsentry/[email protected]
73+
id: venv
74+
with:
75+
python-version: ${{ matrix.python-version }}
76+
cache-dependency-path: dist/*.whl
77+
install-cmd: pip install --require-virtualenv $(find release-assets -name "*.whl")
78+
79+
- name: Install plugin from wheel
80+
run: |
81+
for whl in $(find release-assets -name "*.whl"); do
82+
python -m pip install --require-virtualenv "$whl" || echo "Failed to install $whl"
83+
done
84+
85+
- name: Add pyproject.toml with set plugin
86+
run: |
87+
echo "[tool.commitizen]" > pyproject.toml
88+
echo " name = 'czespressif'" >> pyproject.toml
89+
90+
- name: Test plugin functions
91+
run: |
92+
cz info | grep -q "Commitizen plugin for Espressif Systems" || exit 1
93+
cz example | grep -q "github.com/espressif" || exit 1
94+
95+
test-builds-macos:
96+
needs: [build-python]
5697
permissions:
57-
contents: write
98+
contents: read
99+
strategy:
100+
fail-fast: true
101+
matrix:
102+
python-version: ['3.9', '3.10', '3.11', '3.12']
103+
os: [macos-12, macos-14] # macOS 12 (Intel),macOS 14 (Apple Silicon)
104+
runs-on: ${{ matrix.os }}
58105
steps:
59106
- name: Checkout repository
60107
uses: actions/checkout@v4
108+
with:
109+
fetch-depth: 1 # shallow
61110

62-
- name: Set up Python
111+
- name: Download all builds
112+
uses: actions/download-artifact@v4
113+
with:
114+
path: ./release-assets
115+
116+
- uses: getsentry/[email protected]
117+
id: venv
118+
with:
119+
python-version: ${{ matrix.python-version }}
120+
cache-dependency-path: dist/*.whl
121+
install-cmd: pip install --require-virtualenv $(find release-assets -name "*.whl")
122+
123+
- name: Install plugin from wheel
124+
run: |
125+
for whl in $(find release-assets -name "*.whl"); do
126+
python -m pip install --require-virtualenv "$whl" || echo "Failed to install $whl"
127+
done
128+
129+
- name: Add pyproject.toml with set plugin
130+
run: |
131+
echo "[tool.commitizen]" > pyproject.toml
132+
echo " name = 'czespressif'" >> pyproject.toml
133+
134+
- name: Test plugin functions
135+
run: |
136+
cz info | grep -q "Commitizen plugin for Espressif Systems" || exit 1
137+
cz example | grep -q "github.com/espressif" || exit 1
138+
139+
test-builds-windows:
140+
needs: [build-python]
141+
permissions:
142+
contents: read
143+
strategy:
144+
fail-fast: true
145+
matrix:
146+
python-version: ['3.9', '3.10', '3.11', '3.12']
147+
runs-on: windows-latest
148+
steps:
149+
- name: Checkout repository
150+
uses: actions/checkout@v4
151+
152+
- name: Download all builds
153+
uses: actions/download-artifact@v4
154+
with:
155+
path: ./release-assets
156+
157+
- name: Set up Python to install this project
63158
uses: actions/setup-python@v5
64159
with:
65-
python-version: '3.9' # Minimum supported version - only for running `cz changelog ...`
160+
python-version: ${{ matrix.python-version }}
66161
cache: pip
67162

68-
- name: Install dependencies
69-
run: |-
70-
python -m pip install --upgrade pip
71-
python -m pip install .
163+
- name: Create virtual env
164+
shell: pwsh
165+
run: |
166+
python -m venv venv-pwsh
167+
.\venv-pwsh\Scripts\Activate.ps1
168+
python -m pip install --require-virtualenv --upgrade pip
72169
73-
- name: Get release version from "czespressif/__init__.py"
74-
run: |-
75-
version=$(grep '__version__' czespressif/__init__.py | sed -E "s/__version__ = '([^ ]*)'.*/\1/")
76-
echo "VERSION=$version" >> $GITHUB_ENV
170+
- name: Install plugin from wheel
171+
shell: pwsh
172+
run: |
173+
.\venv-pwsh\Scripts\Activate.ps1
174+
Get-ChildItem -Path "release-assets" -Recurse -Filter "*.whl" | ForEach-Object { try { python -m pip install --require-virtualenv $_.FullName } catch { Write-Host "Failed to install $($_.FullName)" } }
77175
78-
- name: Generate Release notes from Changelog
79-
run: cz changelog v${{ env.VERSION }} --template="RELEASE_NOTES.md.j2" --file-name="RELEASE_NOTES.md"
176+
- name: Add pyproject.toml with set plugin
177+
shell: pwsh
178+
run: |
179+
.\venv-pwsh\Scripts\Activate.ps1
180+
"[tool.commitizen]`r`n name = 'czespressif'" | Set-Content -Path "pyproject.toml"
80181
81-
- name: Show Release notes
82-
run: cat RELEASE_NOTES.md
182+
- name: Test plugin functions
183+
shell: pwsh
184+
run: |
185+
.\venv-pwsh\Scripts\Activate.ps1
186+
cz info | Select-String -Quiet "Commitizen plugin for Espressif Systems" || exit 1
187+
cz example | Select-String -Quiet "github.com/espressif" || exit 1
83188
84-
- name: Download artifacts (builds)
189+
create-github-release:
190+
needs: [test-builds-linux, test-builds-macos, test-builds-windows]
191+
permissions:
192+
contents: write
193+
id-token: write # IMPORTANT: mandatory for sigstore
194+
runs-on: ubuntu-latest
195+
steps:
196+
- name: Checkout repository (full history)
197+
uses: actions/checkout@v4
198+
with:
199+
fetch-depth: 0
200+
201+
- name: Download all builds
85202
uses: actions/download-artifact@v4
203+
204+
- name: Get project release version
205+
id: release_version
206+
run: |
207+
if [ -n "${{ github.event.inputs.version }}" ]; then
208+
VERSION="${{ github.event.inputs.version }}"
209+
else
210+
VERSION=$(git describe --tags --abbrev=0)
211+
fi
212+
echo "Release version: $VERSION"
213+
echo "VERSION=$VERSION" >> $GITHUB_OUTPUT
214+
215+
- name: Set up Python to install this project
216+
uses: actions/setup-python@v5
86217
with:
87-
pattern: python-package-*
88-
merge-multiple: true
218+
python-version: '3.9' # Minimum supported version by this project
219+
cache: pip
220+
221+
- name: Install project
222+
run: |-
223+
python -m venv venv
224+
source venv/bin/activate
225+
pip install --require-virtualenv --upgrade pip
226+
pip install --require-virtualenv .
227+
228+
- name: Create Release notes
229+
run: |
230+
source venv/bin/activate
231+
cz changelog ${{ steps.release_version.outputs.VERSION }} --file-name RELEASE_NOTES.md
232+
233+
- name: Sign the dists with Sigstore
234+
uses: sigstore/[email protected]
235+
with:
236+
inputs: >-
237+
./release-assets/*.tar.gz
238+
./release-assets/*.whl
239+
upload-signing-artifacts: true
240+
release-signing-artifacts: true
241+
242+
- name: List release assets
243+
run: ls -la release-assets
244+
245+
- name: Check all assets ready (or fail here)
246+
run: |
247+
set -e
248+
echo "Check version: ${{ steps.release_version.outputs.VERSION }}"
249+
echo "Check version fits version pattern:; [[ "${{ steps.release_version.outputs.VERSION }}" =~ ^v?[0-9]+\.[0-9]+\.[0-9]+(\.[a-z0-9]+)?$ ]]"
250+
echo "Check release notes file:"; cat RELEASE_NOTES.md
251+
echo "Check python builds:"; ls -la release-assets/*.{whl,tar.gz}
252+
echo "Check source code archive integrity:"; tar -tzf $(ls release-assets/*.tar.gz)
89253
90254
- name: Create GitHub release (and upload assets)
91255
id: create_release
92-
uses: softprops/action-gh-release@v1
256+
uses: softprops/action-gh-release@v2
93257
env:
94258
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
95259
with:
96260
body_path: RELEASE_NOTES.md
97-
name: Version v${{ env.VERSION }}
261+
name: ${{ steps.release_version.outputs.VERSION }}
262+
tag_name: ${{ steps.release_version.outputs.VERSION }} # expects a tag with the same name as version
98263
draft: false
99264
prerelease: false
265+
make_latest: true
100266
files: |
101-
dist/*.whl
102-
dist/*.tar.gz
267+
release-assets/**
268+
269+
create-pypi-release:
270+
needs: [test-builds-linux, test-builds-macos, test-builds-windows]
271+
permissions:
272+
contents: write
273+
id-token: write # For trusted publishing and sigstore
274+
runs-on: ubuntu-latest
275+
steps:
276+
- name: Checkout repository (need README.md used as long_description for PyPI)
277+
uses: actions/checkout@v4
278+
279+
- name: Download all builds and merge
280+
uses: actions/download-artifact@v4
281+
282+
- name: Check all assets ready (or fail here)
283+
run: |
284+
set -e
285+
echo "Check python builds:"; ls -la release-assets/*.{whl,tar.gz}
286+
echo "Check source code archive integrity:"; tar -tzf $(ls release-assets/*.tar.gz)
287+
288+
- name: Publish to TestPyPI
289+
uses: pypa/gh-action-pypi-publish@release/v1
290+
with:
291+
repository-url: https://test.pypi.org/legacy/
292+
packages-dir: release-assets/
293+
verify-metadata: true # 'twine check' before upload
294+
skip-existing: true
295+
# Trusted publisher TestPyPI: espressif/cz-plugin-espressif/create-release.yml
103296

104-
- name: Create PyPI release and (upload assets to PyPI)
297+
- name: Publish to PyPI
105298
uses: pypa/gh-action-pypi-publish@release/v1
106299
with:
107-
password: ${{ secrets.PYPI_PROJECT_TOKEN }}
300+
packages-dir: release-assets/
301+
verify-metadata: true # 'twine check' before upload
108302
skip-existing: true
109-
verify-metadata: true
303+
# Trusted publisher PyPI: espressif/cz-plugin-espressif/create-release.yml

0 commit comments

Comments
 (0)