8
8
pull_request :
9
9
branches :
10
10
- main
11
+ workflow_dispatch :
12
+ inputs :
13
+ release-version :
14
+ # github.event_name == 'workflow_dispatch'
15
+ # && github.event.inputs.release-version
16
+ description : >-
17
+ Target PEP440-compliant version to release.
18
+ Please, don't prepend `v`.
19
+ required : true
20
+ release-commitish :
21
+ # github.event_name == 'workflow_dispatch'
22
+ # && github.event.inputs.release-committish
23
+ default : ' '
24
+ description : >-
25
+ The commit to be released to PyPI and tagged
26
+ in Git as `release-version`. Normally, you
27
+ should keep this empty.
28
+ YOLO :
29
+ default : false
30
+ description : >-
31
+ Flag whether test results should block the
32
+ release (true/false). Only use this under
33
+ extraordinary circumstances to ignore the
34
+ test failures and cut the release regardless.
35
+ required : true
11
36
# Run once per week (Monday at 06:00 UTC)
12
37
schedule :
13
38
- cron : 0 6 * * 1
14
39
15
40
jobs :
16
41
pre-setup :
17
42
name : Pre-set global build settings
18
- if : >- # https://twitter.com/webKnjaZ/status/1308803017001652225
19
- github.event_name != 'create' ||
20
- github.event.ref_type == 'tag'
21
43
runs-on : ubuntu-latest
22
44
defaults :
23
45
run :
24
46
shell : python
25
47
outputs :
26
- dist_version : ${{ steps.scm_version.outputs.dist_version }}
48
+ dist_version : >-
49
+ ${{
50
+ steps.tagged_check.outputs.release_requested == 'true'
51
+ && github.event.inputs.release-version
52
+ || steps.scm_version.outputs.dist_version
53
+ }}
27
54
is_untagged_devel : >-
28
55
${{ steps.not_tagged_check.outputs.is_untagged_devel || false }}
29
- is_tagged : ${{ steps.tagged_check.outputs.is_tagged || false }}
56
+ release_requested : ${{ steps.tagged_check.outputs.release_requested || false }}
30
57
cache_key_files : >-
31
58
${{ steps.calc_cache_key_files.outputs.files_hash_key }}
59
+ git_tag : ${{ steps.git_tag.outputs.tag }}
32
60
sdist_artifact_name : ${{ steps.artifact_name.outputs.sdist }}
33
61
wheel_artifact_name : ${{ steps.artifact_name.outputs.wheel }}
34
62
steps :
@@ -49,19 +77,21 @@ jobs:
49
77
print('::set-output name=is_untagged_devel::true')
50
78
- name : Mark the build as tagged
51
79
id : tagged_check
52
- if : >- # "create" workflows run separately from "push" & "pull_request"
53
- github.event_name == 'create' &&
54
- github.event.ref_type == 'tag'
80
+ if : github.event_name == 'workflow_dispatch'
55
81
run : >-
56
- print('::set-output name=is_tagged ::true')
82
+ print('::set-output name=release_requested ::true')
57
83
- name : Check out src from Git
84
+ if : >-
85
+ steps.tagged_check.outputs.release_requested != 'true'
58
86
uses : actions/checkout@v2
59
87
with :
60
- fetch-depth : >-
61
- ${{ steps.tagged_check.outputs.is_tagged == 'true' && 1 || 0 }}
88
+ fetch-depth : 0
89
+ ref : ${{ github.event.inputs.release-committish }}
62
90
- name : >-
63
91
Calculate Python interpreter version hash value
64
92
for use in the cache key
93
+ if: >-
94
+ steps.tagged_check.outputs.release_requested != 'true'
65
95
id: calc_cache_key_py
66
96
run: |
67
97
from hashlib import sha512
71
101
- name : >-
72
102
Calculate dependency files' combined hash value
73
103
for use in the cache key
104
+ if: >-
105
+ steps.tagged_check.outputs.release_requested != 'true'
74
106
id: calc_cache_key_files
75
107
run: |
76
108
from hashlib import sha512
82
114
)).encode()).hexdigest()
83
115
print(f'::set-output name=files_hash_key::{hashes_combo}')
84
116
- name : Set up pip cache
117
+ if : >-
118
+ steps.tagged_check.outputs.release_requested != 'true'
85
119
uses : actions/cache@v2.1.5
86
120
with :
87
121
path : >-
@@ -100,27 +134,38 @@ jobs:
100
134
${{ runner.os }}-
101
135
- name : Drop Git tags from HEAD for non-tag-create events
102
136
if : >-
103
- steps.tagged_check.outputs.is_tagged != 'true'
137
+ steps.tagged_check.outputs.release_requested != 'true'
104
138
run : >-
105
139
git tag --points-at HEAD
106
140
|
107
141
xargs git tag --delete
108
142
shell : bash
109
143
- name : Set up versioning prerequisites
144
+ if : >-
145
+ steps.tagged_check.outputs.release_requested != 'true'
110
146
run : >-
111
147
python -m
112
148
pip install
113
149
--user
114
150
setuptools-scm
115
151
shell : bash
116
- - name : Set the current dist version
152
+ - name : Set the current dist version from Git
153
+ if : steps.tagged_check.outputs.release_requested != 'true'
117
154
id : scm_version
118
155
run : |
119
156
import setuptools_scm
120
157
ver = setuptools_scm.get_version(
121
158
${{ steps.not_tagged_check.outputs.is_untagged_devel == 'true' && 'local_scheme="no-local-version"' || '' }}
122
159
)
123
160
print('::set-output name=dist_version::{ver}'.format(ver=ver))
161
+ - name : Set the target Git tag
162
+ id : git_tag
163
+ run : >-
164
+ print('::set-output name=tag::v${{
165
+ steps.tagged_check.outputs.release_requested == 'true'
166
+ && github.event.inputs.release-version
167
+ || steps.scm_version.outputs.dist_version
168
+ }}')
124
169
- name : Set the expected dist artifact names
125
170
id : artifact_name
126
171
run : |
@@ -184,6 +229,8 @@ jobs:
184
229
185
230
- name : Grab the source from Git
186
231
uses : actions/checkout@v2
232
+ with :
233
+ ref : ${{ github.event.inputs.release-committish }}
187
234
- name : >-
188
235
Update the project version to ${{
189
236
needs.pre-setup.outputs.dist_version
@@ -257,6 +304,14 @@ jobs:
257
304
- os : Windows
258
305
python-version : pypy-3.6
259
306
307
+ continue-on-error : >-
308
+ ${{
309
+ (
310
+ needs.pre-setup.outputs.release_requested == 'true' &&
311
+ !toJSON(github.event.inputs.YOLO)
312
+ ) && true || false
313
+ }}
314
+
260
315
env :
261
316
ARTIFACT_NAME : >-
262
317
${{
@@ -285,6 +340,8 @@ jobs:
285
340
286
341
- name : Grab the source from Git
287
342
uses : actions/checkout@v2
343
+ with :
344
+ ref : ${{ github.event.inputs.release-committish }}
288
345
- name : Download all the dists
289
346
uses : actions/download-artifact@v2
290
347
with :
@@ -325,26 +382,48 @@ jobs:
325
382
- tests
326
383
if : >-
327
384
fromJSON(needs.pre-setup.outputs.is_untagged_devel) ||
328
- fromJSON(needs.pre-setup.outputs.is_tagged )
385
+ fromJSON(needs.pre-setup.outputs.release_requested )
329
386
runs-on : ubuntu-latest
330
387
331
388
steps :
389
+ - name : Check out src from Git
390
+ uses : actions/checkout@v2
391
+ with :
392
+ fetch-depth : 0
393
+ - name : Setup git user as [bot]
394
+ run : >
395
+ git config --local user.email
396
+ 'github-actions[bot]@users.noreply.github.com'
397
+
398
+ git config --local user.name 'github-actions[bot]'
399
+
400
+ - name : >-
401
+ Tag the release in the local Git repo
402
+ as ${{ needs.pre-setup.outputs.git_tag }}
403
+ run: >-
404
+ git tag '${{ needs.pre-setup.outputs.git_tag }}'
405
+ ${{ github.event.inputs.release-committish }}
332
406
- name : Download all the dists
333
407
uses : actions/download-artifact@v2
334
408
with :
335
409
name : python-package-distributions
336
410
path : dist/
337
- - name : Publish 🐍📦 to TestPyPI
411
+ - name : Publish 🐍📦 ${{ needs.pre-setup.outputs.git_tag }} to TestPyPI
338
412
if : >-
339
413
fromJSON(needs.pre-setup.outputs.is_untagged_devel) ||
340
- fromJSON(needs.pre-setup.outputs.is_tagged )
414
+ fromJSON(needs.pre-setup.outputs.release_requested )
341
415
uses : pypa/gh-action-pypi-publish@release/v1
342
416
with :
343
417
password : ${{ secrets.TESTPYPI_API_TOKEN }}
344
418
repository_url : https://test.pypi.org/legacy/
345
- - name : Publish 🐍📦 to PyPI
346
- if : fromJSON(needs.pre-setup.outputs.is_tagged )
419
+ - name : Publish 🐍📦 ${{ needs.pre-setup.outputs.git_tag }} to PyPI
420
+ if : fromJSON(needs.pre-setup.outputs.release_requested )
347
421
uses : pypa/gh-action-pypi-publish@release/v1
348
422
with :
349
423
password : ${{ secrets.PYPI_API_TOKEN }}
424
+ - name : >-
425
+ Push ${{ needs.pre-setup.outputs.git_tag }} tag corresponding
426
+ to the just published release back to GitHub
427
+ run: >-
428
+ git push --atomic origin '${{ needs.pre-setup.outputs.git_tag }}'
350
429
...
0 commit comments