@@ -8,28 +8,28 @@ concurrency:
8
8
on :
9
9
push :
10
10
tags :
11
- - ' [0-9]* .[0-9]* .[0-9]*' # Push events to every tag that looks like a semver
12
- - ' [0-9]* .[0-9]* .[0-9]*rc[0-9]* ' # Push events to every tag that looks like a release candidate
11
+ - ' [0-9]+ .[0-9]+ .[0-9]+ *' # Push events for official release tags
12
+ - ' test-release/ [0-9]+ .[0-9]+ .[0-9]+* ' # Push events for test release tags
13
13
14
14
jobs :
15
- build :
15
+ build-dist-artifacts :
16
16
# This job uses vanilla Python tools rather than Poetry, so we don't have to use third party GitHub actions
17
17
# e.g. pip, build, twine
18
18
# If we even want to, we could switch to using something like actions/setup-poetry (but do a search for current
19
19
# best implementations)
20
- name : Build distribution 📦
20
+ name : Build distribution artifacts 📦
21
21
runs-on : ubuntu-latest
22
22
23
23
steps :
24
- - name : Checkout repo
24
+ - name : Checkout repository
25
25
uses : actions/checkout@v4
26
26
27
27
- name : Install Python 🐍
28
28
uses : actions/setup-python@v5
29
29
with :
30
30
python-version : ' 3.11'
31
31
32
- - name : Install dependencies
32
+ - name : Install project dependencies
33
33
run : python -m pip install build twine
34
34
35
35
- name : Build wheel and source distribution
@@ -40,21 +40,24 @@ jobs:
40
40
run : twine check dist/*
41
41
42
42
# Save ("upload") the distribution artifacts for use by downstream Actions jobs
43
- - name : Upload sdist artifacts 📦
43
+ - name : Upload distribution artifacts 📦
44
44
uses : actions/upload-artifact@v4 # This allows us to persist the dist directory after the job has completed
45
45
with :
46
46
name : python-package-distributions
47
47
path : dist/
48
48
if-no-files-found : error
49
49
50
- publish-to-pypi :
51
- name : Upload release to PyPI
52
- if : startsWith(github.ref, 'refs/tags/') # Belt and suspenders, only ever publish based on a tag
53
- needs : build
50
+ # Job that pushes dist artifacts to public PyPI for official release tags
51
+ official-pypi-publish :
52
+ name : Upload official release to PyPI
53
+ # Prevent running on any PEP 440 suffixed tags or on test-release tags
54
+ if : startsWith(github.ref, 'refs/tags/test-release') == false
55
+ needs :
56
+ - build-dist-artifacts
54
57
runs-on : ubuntu-latest
55
58
environment :
56
- name : pypi-publish
57
- url : https://pypi.org/p/space_packet_parser
59
+ name : official- pypi-publish-environment
60
+ url : https://pypi.org/p/space_packet_parser # Public PyPI
58
61
permissions :
59
62
id-token : write # IMPORTANT: this permission is mandatory for trusted publishing
60
63
@@ -66,24 +69,52 @@ jobs:
66
69
name : python-package-distributions
67
70
path : dist/
68
71
69
- - name : Publish distribution 📦 to PyPI
72
+ - name : Publish distribution artifacts 📦 to PyPI
70
73
71
74
75
+ # Job that pushes dist artifacts to TestPyPI for test release tags
76
+ # This will fail if the version (according to package metadata) has already been pushed
77
+ test-pypi-publish :
78
+ name : Upload testing release to TestPyPI
79
+ # Only run on test-release tags
80
+ if : startsWith(github.ref, 'refs/tags/test-release')
81
+ needs :
82
+ - build-dist-artifacts
83
+ runs-on : ubuntu-latest
84
+ environment :
85
+ name : test-pypi-publish-environment
86
+ url : https://test.pypi.org/p/space_packet_parser # TestPyPI
87
+ permissions :
88
+ id-token : write # IMPORTANT: this permission is mandatory for trusted publishing
89
+
90
+ steps :
91
+ # This downloads the build artifacts from the build job
92
+ - name : Download all the dists 📦
93
+ uses : actions/download-artifact@v4
94
+ with :
95
+ name : python-package-distributions
96
+ path : dist/
97
+
98
+ - name : Publish distribution artifacts 📦 to TestPyPI
99
+
100
+ with :
101
+ repository-url : https://test.pypi.org/legacy/
102
+
103
+ # Job that publishes an official Release to GitHub after pushing to PyPI
104
+ # This only runs if we have pushed to public PyPI (not TestPyPI)
72
105
create-github-release :
73
- name : >-
74
- Sign the Python 🐍 distribution 📦 with Sigstore
75
- and upload them to GitHub Release
106
+ name : Upload dist artifacts to GitHub Release
76
107
needs :
77
- - publish-to- pypi
108
+ - official- pypi-publish
78
109
runs-on : ubuntu-latest
79
110
environment :
80
- name : pypi-publish
111
+ name : create-github-release-environment
81
112
permissions :
82
- contents : write # IMPORTANT: mandatory for making GitHub Releases
83
113
id-token : write # IMPORTANT: mandatory for sigstore
114
+ contents : write # IMPORTANT: mandatory for making GitHub Releases
84
115
85
116
steps :
86
- - name : Download all the dists 📦
117
+ - name : Download the artifacts 📦
87
118
uses : actions/download-artifact@v4
88
119
with :
89
120
name : python-package-distributions
@@ -96,14 +127,15 @@ jobs:
96
127
./dist/*.tar.gz
97
128
./dist/*.whl
98
129
99
- - name : Determine if it's a pre-release
100
- # Dynamically sets the --prerelease option passed to the release create CLI based on matching the *rc*
101
- # substring in the git tag. If rc not present, does not pass --prerelease to the CLI.
130
+ - name : Determine if the release is a prerelease
131
+ # Checks the regex form of the tag.
132
+ # Marks final releases only for tags matching the regex (no version suffixes)
133
+ # All other releases are marked as prereleases
102
134
run : |
103
- if [[ "${{ github.ref_name }}" == *rc* ]]; then
104
- echo "PRE_RELEASE_OPTION=--prerelease " >> $GITHUB_ENV
135
+ if [[ "${{ github.ref_name }}" =~ '^[0-9]*\.[0-9]*\.[0-9]*$' ]]; then
136
+ echo "PRE_RELEASE_OPTION='' " >> $GITHUB_ENV # Not a prerelease
105
137
else
106
- echo "PRE_RELEASE_OPTION=''" >> $GITHUB_ENV
138
+ echo "PRE_RELEASE_OPTION='--prerelease '" >> $GITHUB_ENV # Is a prerelease
107
139
fi
108
140
109
141
- name : Get latest non-prerelease release
@@ -125,9 +157,11 @@ jobs:
125
157
# Uses the GitHub CLI to generate the Release and auto-generate the release notes. Also generates
126
158
# the Release title based on the annotation on the git tag.
127
159
run : >-
160
+ RELEASE_NAME=$(basename "${{ github.ref_name }}")
128
161
gh release create
129
162
'${{ github.ref_name }}'
130
163
--repo '${{ github.repository }}'
164
+ --title "$RELEASE_NAME"
131
165
${{ env.PRE_RELEASE_OPTION }}
132
166
--generate-notes
133
167
--notes-start-tag '${{ env.LATEST_RELEASE_TAG }}'
0 commit comments