@@ -2,77 +2,129 @@ name: release
22
33on :
44 push :
5- branches : [deploy ]
5+ branches : [release-test-pypi, release-test-github, release-test-full ]
66 tags : [v*]
77 workflow_dispatch :
88
9+
910jobs :
10- build-and-deploy :
11+ build :
1112 runs-on : ubuntu-latest
12- environment : release
13-
14- permissions :
15- id-token : write # Used to authenticate to PyPI via OIDC
16-
17- contents : write # Used to authenticate github release publish
13+ outputs :
14+ release-artifact-id : ${{ steps.upload-release.outputs.artifact-id }}
15+ wheel-artifact-id : ${{ steps.upload-wheel.outputs.artifact-id }}
16+ artifact-runner : ${{ github.job }}
1817
1918 steps :
2019 - name : Checkout code
21- uses : actions/checkout@v4
20+ uses : actions/checkout@v5
2221
2322 - name : Reject any VCS dependencies
24- shell : python
25- run : |
26- import re, tomllib
27- manifest = tomllib.load(open('pyproject.toml', 'rb'))
28- deps = manifest['build-system']['requires']
29- deps.extend(manifest['project']['dependencies'])
30- if rejects := list(filter(re.compile(r'@[^+]+').search, deps)):
31- rejects = " \n".join(sorted(rejects))
32- raise Exception(f'VCS dependencies were detected in [build-system]:\n {rejects}')
23+ continue-on-error : ${{ github.ref_type == 'branch' && github.ref_name != 'release-test-full' }}
24+ uses : pkgcore/gh-actions/reject-python-vcs-deps@main
3325
3426 - name : Set up Python 3.13
3527 uses : actions/setup-python@v5
3628 with :
3729 python-version : " 3.13"
30+ cache : ' pip'
31+ cache-dependency-path : pyproject.toml
3832
3933 - name : Install dependencies
4034 run : |
4135 python -m pip install --upgrade pip
42- pip install build ".[test,doc]"
43-
44- - name : Test with pytest
45- env :
46- PY_COLORS : 1 # forcibly enable pytest colors
47- run : pytest
36+ pip install build ".[doc]"
4837
49- - name : Build sdist
38+ - name : Build the release
5039 run : |
51- git clean -fxd
52- make man
53- make sdist
54-
55- - name : Build wheel
56- run : make wheel
40+ make release
5741
5842 - name : Output dist file info
5943 run : |
6044 sha512sum dist/*
45+ echo ::group::Release contents
6146 tar -ztf dist/*.tar.gz | sort
47+ echo ::endgroup::
48+ echo ::group::All generated content in dist
49+ find .
50+ echo ::endgroup::
51+
52+ - name : Upload wheel
53+ id : upload-wheel
54+ uses : actions/upload-artifact@v5
55+ with :
56+ name : wheel-release
57+ path : dist/*.whl
58+ if-no-files-found : error
6259
63- - uses : actions/upload-artifact@v4
60+ - name : Upload release source
61+ id : upload-release
62+ uses : actions/upload-artifact@v5
6463 with :
65- name : results
66- path : dist/*
64+ name : release-source
65+ path : dist/*.tar.gz
66+ if-no-files-found : error
67+
68+ test :
69+ needs : [build]
70+ uses : ./.github/workflows/test.yml
71+ with :
72+ release-artifact-id : ${{ needs.build.outputs.release-artifact-id }}
73+ disable-format-check : true
6774
68- - name : publish
69- uses : pypa/gh-action-pypi-publish@release/v1
70- if : startsWith(github.ref, 'refs/tags/')
75+ publish :
76+ if : github.ref_type == 'tag'
77+ needs : [build, test]
78+ environment : release
79+ permissions :
80+ id-token : write # Used to authenticate to PyPI via OIDC
81+ contents : write # release uploads
82+ runs-on : ubuntu-latest
7183
72- - name : Create GitHub release
73- uses : softprops/action-gh-release@v1
74- if : startsWith(github.ref, 'refs/tags/')
84+ steps :
85+ - &common_download_artifacts
86+ name : Download artifacts
87+ uses : actions/download-artifact@v5
88+ with :
89+ merge-multiple : true # store both in the root, not in named directories
90+ artifact-ids : ${{ needs.build.outputs.release-artifact-id }},${{ needs.build.outputs.wheel-artifact-id }}
91+
92+ - name : Publish github source
93+ uses : softprops/action-gh-release@v2
7594 with :
76- files : dist/*.tar.gz
95+ files : ' *.tar.*'
96+ fail_on_unmatched_files : true
97+
98+ - name : Publish to PyPi server
99+ uses : pypa/gh-action-pypi-publish@release/v1.13
100+ with :
101+ packages-dir : .
102+
103+ test-publish :
104+ # use the full form to ensure insane tags and errors in 'on' filter still don't kick.
105+ if : github.ref_type == 'branch'
106+ needs : [build, test]
107+ environment : test-release
108+ permissions :
109+ id-token : write # Used to authenticate to PyPI via OIDC
110+ contents : write # release uploads-
111+ runs-on : ubuntu-latest
112+
113+ steps :
114+ - *common_download_artifacts
115+ - name : Publish github source
116+ uses : softprops/action-gh-release@v2
117+ if : github.ref_name == 'release-test-github' || github.ref_name == 'release-test-full'
118+ with :
119+ files : ' *.tar.*'
77120 fail_on_unmatched_files : true
78121 draft : true
122+
123+ - name : Publish to Test PyPi server
124+ if : github.ref_name == 'release-test-pypi' || github.ref_name == 'release-test-full'
125+ uses : pypa/gh-action-pypi-publish@release/v1.13
126+ with :
127+ packages-dir : .
128+ repository-url : https://test.pypi.org/legacy/
129+ # attestations are bound in a way re-releasing isn't possible. Disable for tests.
130+ attestations : false
0 commit comments