Skip to content

Commit 55190f5

Browse files
committed
Add a "release" button to GHA
Ref #16
1 parent f3210ea commit 55190f5

File tree

1 file changed

+97
-18
lines changed

1 file changed

+97
-18
lines changed

.github/workflows/ci-cd.yml

Lines changed: 97 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8,27 +8,55 @@ on:
88
pull_request:
99
branches:
1010
- 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
1136
# Run once per week (Monday at 06:00 UTC)
1237
schedule:
1338
- cron: 0 6 * * 1
1439

1540
jobs:
1641
pre-setup:
1742
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'
2143
runs-on: ubuntu-latest
2244
defaults:
2345
run:
2446
shell: python
2547
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+
}}
2754
is_untagged_devel: >-
2855
${{ 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 }}
3057
cache_key_files: >-
3158
${{ steps.calc_cache_key_files.outputs.files_hash_key }}
59+
git_tag: ${{ steps.git_tag.outputs.tag }}
3260
sdist_artifact_name: ${{ steps.artifact_name.outputs.sdist }}
3361
wheel_artifact_name: ${{ steps.artifact_name.outputs.wheel }}
3462
steps:
@@ -49,19 +77,21 @@ jobs:
4977
print('::set-output name=is_untagged_devel::true')
5078
- name: Mark the build as tagged
5179
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'
5581
run: >-
56-
print('::set-output name=is_tagged::true')
82+
print('::set-output name=release_requested::true')
5783
- name: Check out src from Git
84+
if: >-
85+
steps.tagged_check.outputs.release_requested != 'true'
5886
uses: actions/checkout@v2
5987
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 }}
6290
- name: >-
6391
Calculate Python interpreter version hash value
6492
for use in the cache key
93+
if: >-
94+
steps.tagged_check.outputs.release_requested != 'true'
6595
id: calc_cache_key_py
6696
run: |
6797
from hashlib import sha512
@@ -71,6 +101,8 @@ jobs:
71101
- name: >-
72102
Calculate dependency files' combined hash value
73103
for use in the cache key
104+
if: >-
105+
steps.tagged_check.outputs.release_requested != 'true'
74106
id: calc_cache_key_files
75107
run: |
76108
from hashlib import sha512
@@ -82,6 +114,8 @@ jobs:
82114
)).encode()).hexdigest()
83115
print(f'::set-output name=files_hash_key::{hashes_combo}')
84116
- name: Set up pip cache
117+
if: >-
118+
steps.tagged_check.outputs.release_requested != 'true'
85119
uses: actions/cache@v2.1.5
86120
with:
87121
path: >-
@@ -100,27 +134,38 @@ jobs:
100134
${{ runner.os }}-
101135
- name: Drop Git tags from HEAD for non-tag-create events
102136
if: >-
103-
steps.tagged_check.outputs.is_tagged != 'true'
137+
steps.tagged_check.outputs.release_requested != 'true'
104138
run: >-
105139
git tag --points-at HEAD
106140
|
107141
xargs git tag --delete
108142
shell: bash
109143
- name: Set up versioning prerequisites
144+
if: >-
145+
steps.tagged_check.outputs.release_requested != 'true'
110146
run: >-
111147
python -m
112148
pip install
113149
--user
114150
setuptools-scm
115151
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'
117154
id: scm_version
118155
run: |
119156
import setuptools_scm
120157
ver = setuptools_scm.get_version(
121158
${{ steps.not_tagged_check.outputs.is_untagged_devel == 'true' && 'local_scheme="no-local-version"' || '' }}
122159
)
123160
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+
}}')
124169
- name: Set the expected dist artifact names
125170
id: artifact_name
126171
run: |
@@ -184,6 +229,8 @@ jobs:
184229
185230
- name: Grab the source from Git
186231
uses: actions/checkout@v2
232+
with:
233+
ref: ${{ github.event.inputs.release-committish }}
187234
- name: >-
188235
Update the project version to ${{
189236
needs.pre-setup.outputs.dist_version
@@ -257,6 +304,14 @@ jobs:
257304
- os: Windows
258305
python-version: pypy-3.6
259306

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+
260315
env:
261316
ARTIFACT_NAME: >-
262317
${{
@@ -285,6 +340,8 @@ jobs:
285340
286341
- name: Grab the source from Git
287342
uses: actions/checkout@v2
343+
with:
344+
ref: ${{ github.event.inputs.release-committish }}
288345
- name: Download all the dists
289346
uses: actions/download-artifact@v2
290347
with:
@@ -325,26 +382,48 @@ jobs:
325382
- tests
326383
if: >-
327384
fromJSON(needs.pre-setup.outputs.is_untagged_devel) ||
328-
fromJSON(needs.pre-setup.outputs.is_tagged)
385+
fromJSON(needs.pre-setup.outputs.release_requested)
329386
runs-on: ubuntu-latest
330387

331388
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 }}
332406
- name: Download all the dists
333407
uses: actions/download-artifact@v2
334408
with:
335409
name: python-package-distributions
336410
path: dist/
337-
- name: Publish 🐍📦 to TestPyPI
411+
- name: Publish 🐍📦 ${{ needs.pre-setup.outputs.git_tag }}to TestPyPI
338412
if: >-
339413
fromJSON(needs.pre-setup.outputs.is_untagged_devel) ||
340-
fromJSON(needs.pre-setup.outputs.is_tagged)
414+
fromJSON(needs.pre-setup.outputs.release_requested)
341415
uses: pypa/gh-action-pypi-publish@release/v1
342416
with:
343417
password: ${{ secrets.TESTPYPI_API_TOKEN }}
344418
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)
347421
uses: pypa/gh-action-pypi-publish@release/v1
348422
with:
349423
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 }}'
350429
...

0 commit comments

Comments
 (0)