Repository navigation
147 lines (132 loc) · 4.75 KB
/
Copy pathrelease.yml
File metadata and controls
147 lines (132 loc) · 4.75 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
name: Release
# Publishing a GitHub Release whose tag is `v0.1.0` publishes 0.1.0 to PyPI
# and attaches the built distributions to that Release. Create the Release
# (and its tag) in the GitHub UI; the tag must match the version in
# pyproject.toml - the build job refuses to continue otherwise, before
# anything is uploaded anywhere.
#
# Manual runs publish to TestPyPI instead, so a release can be rehearsed
# end to end without burning a version number on PyPI (a filename can never
# be reused there, even after a delete).
on:
release:
types: [published]
workflow_dispatch:
permissions:
contents: read
jobs:
build:
name: build + verify
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: actions/setup-python@v7
with:
python-version: "3.12"
# On a release event github.ref is the release's tag, so ref_name is
# the tag name, exactly as it was under the old on-tag-push trigger.
- name: Verify tag matches the declared version
if: github.event_name == 'release'
env:
TAG: ${{ github.ref_name }}
run: |
python - <<'PY'
import os
import pathlib
import tomllib
tag = os.environ["TAG"].removeprefix("v")
declared = tomllib.loads(pathlib.Path("pyproject.toml").read_text())["project"]["version"]
init = pathlib.Path("src/pyzephyrconnect/__init__.py").read_text()
dunder = next(
line.split('"')[1] for line in init.splitlines() if line.startswith("__version__")
)
problems = []
if tag != declared:
problems.append(f"tag {tag!r} != pyproject.toml version {declared!r}")
if dunder != declared:
problems.append(f"__init__.py version {dunder!r} != pyproject.toml version {declared!r}")
if problems:
raise SystemExit("version mismatch:\n " + "\n ".join(problems))
print(f"ok: releasing {declared}")
PY
- name: Build sdist and wheel
run: |
python -m pip install --upgrade pip build twine
python -m build
- name: Check distribution metadata
run: twine check --strict dist/*
- name: Assert cert bundle is in the wheel
run: |
python - <<'PY'
import glob
import zipfile
wheel, = glob.glob("dist/*.whl")
names = zipfile.ZipFile(wheel).namelist()
cert = "pyzephyrconnect/certs/twca.pem"
assert names.count(cert) == 1, f"{cert} appears {names.count(cert)}x in {wheel}: {names}"
print(f"ok: {cert} present exactly once in {wheel}")
PY
- name: Run the test suite against the built wheel
run: |
python -m venv /tmp/relcheck
/tmp/relcheck/bin/pip install --quiet dist/*.whl pytest pytest-asyncio
/tmp/relcheck/bin/python -m pytest -q
- uses: actions/upload-artifact@v7
with:
name: dist
path: dist/
publish-testpypi:
name: publish to TestPyPI
if: github.event_name == 'workflow_dispatch'
needs: build
runs-on: ubuntu-latest
environment:
name: testpypi
url: https://test.pypi.org/p/pyzephyrconnect
permissions:
id-token: write # trusted publishing (OIDC); no API token stored anywhere
steps:
- uses: actions/download-artifact@v8
with:
name: dist
path: dist/
- uses: pypa/gh-action-pypi-publish@release/v1
with:
repository-url: https://test.pypi.org/legacy/
publish-pypi:
name: publish to PyPI
if: github.event_name == 'release'
needs: build
runs-on: ubuntu-latest
environment:
name: pypi
url: https://pypi.org/p/pyzephyrconnect
permissions:
id-token: write # trusted publishing (OIDC); no API token stored anywhere
steps:
- uses: actions/download-artifact@v8
with:
name: dist
path: dist/
- uses: pypa/gh-action-pypi-publish@release/v1
attach-artifacts:
name: attach artifacts to the GitHub Release
if: github.event_name == 'release'
needs: publish-pypi
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/download-artifact@v8
with:
name: dist
path: dist/
# The Release already exists - publishing it is what triggered this
# workflow - so upload the published distributions to it rather than
# creating one. --clobber makes a re-run of this job idempotent.
- name: Upload the published artifacts to the release
env:
GH_TOKEN: ${{ github.token }}
GH_REPO: ${{ github.repository }}
TAG: ${{ github.ref_name }}
run: gh release upload "$TAG" dist/* --clobber