Skip to content

Commit 9273444

Browse files
committed
Add a release workflow
1 parent 7b531ee commit 9273444

File tree

2 files changed

+90
-106
lines changed

2 files changed

+90
-106
lines changed

.github/workflows/ci.yml

Lines changed: 0 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -70,109 +70,3 @@ jobs:
7070
uses: codecov/codecov-action@v4
7171
with:
7272
flags: unittests
73-
74-
check:
75-
if: always()
76-
needs: [test, lint]
77-
runs-on: ubuntu-latest
78-
steps:
79-
- name: Decide whether the needed jobs succeeded or failed
80-
uses: re-actors/alls-green@release/v1
81-
with:
82-
jobs: ${{ toJSON(needs) }}
83-
84-
build:
85-
runs-on: ubuntu-latest
86-
name: build
87-
# only run on push to main and on release, or with tag
88-
if: "success() && (startsWith(github.ref, 'refs/tags/') || github.ref == 'refs/heads/main' || contains(github.event.pull_request.labels.*.name, 'Full Build'))"
89-
steps:
90-
- uses: actions/checkout@v4
91-
92-
- name: Set up Python
93-
uses: actions/setup-python@v5
94-
with:
95-
python-version: "3"
96-
97-
- name: Install build dependencies (pypa/build)
98-
run: |
99-
pip install -U pip
100-
pip install build
101-
102-
- name: Build distribution
103-
run: python -m build
104-
105-
- run: ls -altrh dist/
106-
shell: bash
107-
108-
- uses: actions/upload-artifact@v3
109-
with:
110-
name: pypi_files
111-
path: dist
112-
113-
inspect-pypi-assets:
114-
needs: [build]
115-
runs-on: ubuntu-latest
116-
117-
steps:
118-
- uses: actions/checkout@v4
119-
120-
- name: get dist artifacts
121-
uses: actions/download-artifact@v3
122-
with:
123-
name: pypi_files
124-
path: dist
125-
126-
- name: list dist files
127-
run: |
128-
ls -lh dist/
129-
echo "`ls dist | wc -l` files"
130-
- name: extract and list sdist file
131-
run: |
132-
mkdir sdist-files
133-
tar -xvf dist/*.tar.gz -C sdist-files
134-
tree -a sdist-files
135-
- name: extract and list wheel file
136-
run: |
137-
ls dist/*.whl | head -n 1
138-
python -m zipfile --list `ls dist/*.whl | head -n 1`
139-
140-
release:
141-
needs: [build, check]
142-
if: "success() && startsWith(github.ref, 'refs/tags/')"
143-
runs-on: ubuntu-latest
144-
145-
steps:
146-
- uses: actions/checkout@v4
147-
148-
- name: Set up Python
149-
uses: actions/setup-python@v5
150-
with:
151-
python-version: "3"
152-
153-
- name: Install build dependencies (twine)
154-
run: |
155-
pip install -U pip
156-
pip install twine
157-
158-
- name: get dist artifacts
159-
uses: actions/download-artifact@v3
160-
with:
161-
name: pypi_files
162-
path: dist
163-
164-
- name: Upload to PyPI
165-
env:
166-
TWINE_NON_INTERACTIVE: "true"
167-
TWINE_USERNAME: "__token__"
168-
TWINE_PASSWORD: "${{ secrets.pypi_token }}"
169-
run: |
170-
twine check dist/*
171-
twine upload dist/*
172-
173-
- name: upload to github release
174-
uses: softprops/action-gh-release@v1
175-
with:
176-
files: |
177-
dist/*
178-
generate_release_notes: true
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
name: Create release
2+
3+
on:
4+
push:
5+
tags:
6+
- "*"
7+
workflow_dispatch:
8+
9+
permissions:
10+
contents: read
11+
12+
jobs:
13+
publish-pypi:
14+
runs-on: ubuntu-latest
15+
name: PyPI Release
16+
environment: release
17+
permissions:
18+
id-token: write # for PyPI trusted publishing
19+
steps:
20+
- uses: actions/checkout@v4
21+
- name: Set up Python
22+
uses: actions/setup-python@v5
23+
with:
24+
python-version: "3"
25+
cache: pip
26+
cache-dependency-path: pyproject.toml
27+
28+
- name: Install build dependencies (pypa/build, twine)
29+
run: |
30+
pip install -U pip
31+
pip install build twine
32+
33+
- name: Build distribution
34+
run: python -m build
35+
36+
- name: Mint PyPI API token
37+
id: mint-token
38+
uses: actions/github-script@v7
39+
with:
40+
# language=JavaScript
41+
script: |
42+
// retrieve the ambient OIDC token
43+
const oidc_request_token = process.env.ACTIONS_ID_TOKEN_REQUEST_TOKEN;
44+
const oidc_request_url = process.env.ACTIONS_ID_TOKEN_REQUEST_URL;
45+
const oidc_resp = await fetch(`${oidc_request_url}&audience=pypi`, {
46+
headers: {Authorization: `bearer ${oidc_request_token}`},
47+
});
48+
const oidc_token = (await oidc_resp.json()).value;
49+
50+
// exchange the OIDC token for an API token
51+
const mint_resp = await fetch('https://pypi.org/_/oidc/github/mint-token', {
52+
method: 'post',
53+
body: `{"token": "${oidc_token}"}` ,
54+
headers: {'Content-Type': 'application/json'},
55+
});
56+
const api_token = (await mint_resp.json()).token;
57+
58+
// mask the newly minted API token, so that we don't accidentally leak it
59+
core.setSecret(api_token)
60+
core.setOutput('api-token', api_token)
61+
62+
- name: Upload to PyPI
63+
env:
64+
TWINE_NON_INTERACTIVE: "true"
65+
TWINE_USERNAME: "__token__"
66+
TWINE_PASSWORD: "${{ steps.mint-token.outputs.api-token }}"
67+
run: |
68+
twine check dist/*
69+
twine upload dist/*
70+
71+
github-release:
72+
runs-on: ubuntu-latest
73+
name: GitHub release
74+
environment: release
75+
permissions:
76+
contents: write # for softprops/action-gh-release to create GitHub release
77+
steps:
78+
- uses: actions/checkout@v4
79+
- name: Get release version
80+
id: get_version
81+
uses: actions/github-script@v7
82+
with:
83+
script: core.setOutput('version', context.ref.replace("refs/tags/", ""))
84+
85+
- name: Create GitHub release
86+
uses: softprops/action-gh-release@v1
87+
if: startsWith(github.ref, 'refs/tags/')
88+
with:
89+
name: "Release ${{ steps.get_version.outputs.version }}"
90+
generate_release_notes: true

0 commit comments

Comments
 (0)