Skip to content

Commit 1e46654

Browse files
committed
feat(ci): automated release workflow (#1072)
1 parent 6fed323 commit 1e46654

File tree

10 files changed

+505
-7
lines changed

10 files changed

+505
-7
lines changed

.github/CODEOWNERS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners
2+
/.github @DisnakeDev/maintainers
3+
/scripts/ci @DisnakeDev/maintainers
Lines changed: 227 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,227 @@
1+
# SPDX-License-Identifier: MIT
2+
3+
name: Build (+ Release)
4+
5+
# test build for commit/tag, but only upload release for tags
6+
on:
7+
push:
8+
branches:
9+
- "master"
10+
- 'v[0-9]+.[0-9]+.x' # matches to backport branches, e.g. v3.6.x
11+
tags:
12+
- "v[0-9]+.[0-9]+.[0-9]+"
13+
14+
permissions:
15+
contents: read
16+
17+
jobs:
18+
# Builds sdist and wheel, runs `twine check`, and optionally uploads artifacts.
19+
build:
20+
name: Build package
21+
runs-on: ubuntu-latest
22+
23+
steps:
24+
- uses: actions/checkout@v3
25+
26+
- name: Set up environment
27+
id: setup
28+
uses: ./.github/actions/setup-env
29+
with:
30+
python-version: 3.8
31+
32+
- name: Install dependencies
33+
run: pdm install -dG build
34+
35+
- name: Build package
36+
run: |
37+
pdm run python -m build
38+
ls -la dist/
39+
40+
- name: Twine check
41+
run: pdm run twine check --strict dist/*
42+
43+
- name: Show metadata
44+
run: |
45+
mkdir out/
46+
tar -xf dist/*.tar.gz -C out/
47+
48+
echo -e "<details><summary>Metadata</summary>\n" >> $GITHUB_STEP_SUMMARY
49+
cat out/*/PKG-INFO | sed 's/^/ /' | tee -a $GITHUB_STEP_SUMMARY
50+
echo -e "\n</details>\n" >> $GITHUB_STEP_SUMMARY
51+
52+
- name: Upload artifact
53+
# only upload artifacts when necessary
54+
if: startsWith(github.ref, 'refs/tags/')
55+
uses: actions/upload-artifact@v3
56+
with:
57+
name: dist
58+
path: dist/
59+
if-no-files-found: error
60+
61+
62+
### Anything below this only runs for tags ###
63+
64+
# Ensures that git tag and built version match.
65+
validate-tag:
66+
name: Validate tag
67+
runs-on: ubuntu-latest
68+
if: startsWith(github.ref, 'refs/tags/')
69+
needs:
70+
- build
71+
env:
72+
GIT_TAG: ${{ github.ref_name }}
73+
outputs:
74+
bump_dev: ${{ steps.check-dev.outputs.bump_dev }}
75+
76+
steps:
77+
- name: Download build artifact
78+
uses: actions/download-artifact@v3
79+
with:
80+
name: dist
81+
path: dist/
82+
83+
- name: Compare sdist version to git tag
84+
run: |
85+
mkdir out/
86+
tar -xf dist/*.tar.gz -C out/
87+
88+
SDIST_VERSION="$(grep "^Version:" out/*/PKG-INFO | cut -d' ' -f2-)"
89+
echo "git tag: $GIT_TAG"
90+
echo "sdist version: $SDIST_VERSION"
91+
92+
if [ "$GIT_TAG" != "v$SDIST_VERSION" ]; then
93+
echo "error: git tag does not match sdist version" >&2
94+
exit 1
95+
fi
96+
97+
- name: Determine if dev version PR is needed
98+
id: check-dev
99+
run: |
100+
BUMP_DEV=
101+
# if this is a new major/minor version, create a PR later
102+
if [[ "$GIT_TAG" =~ ^v[0-9]+\.[0-9]+\.0$ ]]; then
103+
BUMP_DEV=1
104+
fi
105+
echo "bump_dev=$BUMP_DEV" | tee -a $GITHUB_OUTPUT
106+
107+
108+
# Creates a draft release on GitHub, and uploads the artifacts there.
109+
release-github:
110+
name: Create GitHub draft release
111+
runs-on: ubuntu-latest
112+
if: startsWith(github.ref, 'refs/tags/')
113+
needs:
114+
- build
115+
- validate-tag
116+
permissions:
117+
contents: write # required for creating releases
118+
119+
steps:
120+
- name: Download build artifact
121+
uses: actions/download-artifact@v3
122+
with:
123+
name: dist
124+
path: dist/
125+
126+
- name: Calculate versions
127+
id: versions
128+
env:
129+
GIT_TAG: ${{ github.ref_name }}
130+
run: |
131+
# v1.2.3 -> v1-2-3 (for changelog)
132+
echo "docs_version=${GIT_TAG//./-}" >> $GITHUB_OUTPUT
133+
134+
- name: Create Release
135+
uses: softprops/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844 # v0.1.15
136+
with:
137+
files: dist/*
138+
draft: true
139+
body: |
140+
TBD.
141+
142+
**Changelog**: https://docs.disnake.dev/en/stable/whats_new.html#${{ steps.versions.outputs.docs_version }}
143+
**Git history**: https://github.com/${{ github.repository }}/compare/vTODO...${{ github.ref_name }}
144+
145+
146+
# Creates a PyPI release (using an environment which requires separate confirmation).
147+
release-pypi:
148+
name: Publish package to pypi.org
149+
environment:
150+
name: release-pypi
151+
url: https://pypi.org/project/disnake/
152+
runs-on: ubuntu-latest
153+
if: startsWith(github.ref, 'refs/tags/')
154+
needs:
155+
- build
156+
- validate-tag
157+
permissions:
158+
id-token: write # this permission is mandatory for trusted publishing
159+
160+
steps:
161+
- name: Download build artifact
162+
uses: actions/download-artifact@v3
163+
with:
164+
name: dist
165+
path: dist/
166+
167+
- name: Upload to pypi
168+
uses: pypa/gh-action-pypi-publish@f5622bde02b04381239da3573277701ceca8f6a0 # v1.8.7
169+
with:
170+
print-hash: true
171+
172+
173+
# Creates a PR to bump to an alpha version for development, if applicable.
174+
create-dev-version-pr:
175+
name: Create dev version bump PR
176+
runs-on: ubuntu-latest
177+
if: startsWith(github.ref, 'refs/tags/') && needs.validate-tag.outputs.bump_dev
178+
needs:
179+
- validate-tag
180+
- release-github
181+
- release-pypi
182+
183+
steps:
184+
# https://docs.github.com/en/apps/creating-github-apps/authenticating-with-a-github-app/making-authenticated-api-requests-with-a-github-app-in-a-github-actions-workflow
185+
- name: Generate app token
186+
id: generate_token
187+
uses: tibdex/github-app-token@b62528385c34dbc9f38e5f4225ac829252d1ea92 # v1.8.0
188+
with:
189+
app_id: ${{ secrets.BOT_APP_ID }}
190+
private_key: ${{ secrets.BOT_PRIVATE_KEY }}
191+
192+
- uses: actions/checkout@v3
193+
with:
194+
token: ${{ steps.generate_token.outputs.token }}
195+
persist-credentials: false
196+
ref: master # the PR action wants a proper base branch
197+
198+
- name: Set git name/email
199+
env:
200+
GIT_USER: ${{ vars.GIT_APP_USER_NAME }}
201+
GIT_EMAIL: ${{ vars.GIT_APP_USER_EMAIL }}
202+
run: |
203+
git config user.name "$GIT_USER"
204+
git config user.email "$GIT_EMAIL"
205+
206+
- name: Update version to dev
207+
id: update-version
208+
run: |
209+
NEW_VERSION="$(python scripts/ci/versiontool.py --set dev)"
210+
git commit -a -m "chore: update version to v$NEW_VERSION"
211+
echo "new_version=$NEW_VERSION" >> $GITHUB_OUTPUT
212+
213+
- name: Create pull request
214+
uses: peter-evans/create-pull-request@153407881ec5c347639a548ade7d8ad1d6740e38 # v5.0.2
215+
with:
216+
token: ${{ steps.generate_token.outputs.token }}
217+
branch: auto/dev-v${{ steps.update-version.outputs.new_version }}
218+
delete-branch: true
219+
base: master
220+
title: "chore: update version to v${{ steps.update-version.outputs.new_version }}"
221+
body: |
222+
Automated dev version PR.
223+
224+
<sub>https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}</sub>
225+
labels: |
226+
skip news
227+
t: meta

.github/workflows/changelog.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ jobs:
3333
python-version: '3.9'
3434

3535
- name: Install dependencies
36-
run: pdm install -dG tools
36+
run: pdm install -dG changelog
3737

3838
- name: Check for presence of a Change Log fragment (only pull requests)
3939
# NOTE: The pull request' base branch needs to be fetched so towncrier
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
# SPDX-License-Identifier: MIT
2+
3+
name: Create Release PR
4+
5+
on:
6+
workflow_dispatch:
7+
inputs:
8+
version:
9+
description: "The new version number, e.g. `1.2.3`."
10+
type: string
11+
required: true
12+
13+
permissions: {}
14+
15+
jobs:
16+
create-release-pr:
17+
name: Create Release PR
18+
runs-on: ubuntu-latest
19+
20+
env:
21+
VERSION_INPUT: ${{ inputs.version }}
22+
23+
steps:
24+
# https://docs.github.com/en/apps/creating-github-apps/authenticating-with-a-github-app/making-authenticated-api-requests-with-a-github-app-in-a-github-actions-workflow
25+
- name: Generate app token
26+
id: generate_token
27+
uses: tibdex/github-app-token@b62528385c34dbc9f38e5f4225ac829252d1ea92 # v1.8.0
28+
with:
29+
app_id: ${{ secrets.BOT_APP_ID }}
30+
private_key: ${{ secrets.BOT_PRIVATE_KEY }}
31+
32+
- uses: actions/checkout@v3
33+
with:
34+
token: ${{ steps.generate_token.outputs.token }}
35+
persist-credentials: false
36+
37+
- name: Set git name/email
38+
env:
39+
GIT_USER: ${{ vars.GIT_APP_USER_NAME }}
40+
GIT_EMAIL: ${{ vars.GIT_APP_USER_EMAIL }}
41+
run: |
42+
git config user.name "$GIT_USER"
43+
git config user.email "$GIT_EMAIL"
44+
45+
- name: Set up environment
46+
uses: ./.github/actions/setup-env
47+
with:
48+
python-version: 3.8
49+
50+
- name: Install dependencies
51+
run: pdm install -dG changelog
52+
53+
- name: Update version
54+
run: |
55+
python scripts/ci/versiontool.py --set "$VERSION_INPUT"
56+
git commit -a -m "chore: update version to $VERSION_INPUT"
57+
58+
- name: Build changelog
59+
run: |
60+
pdm run towncrier build --yes --version "$VERSION_INPUT"
61+
git commit -a -m "docs: build changelog"
62+
63+
- name: Create pull request
64+
uses: peter-evans/create-pull-request@153407881ec5c347639a548ade7d8ad1d6740e38 # v5.0.2
65+
with:
66+
token: ${{ steps.generate_token.outputs.token }}
67+
branch: auto/release-v${{ inputs.version }}
68+
delete-branch: true
69+
title: "release: v${{ inputs.version }}"
70+
body: |
71+
Automated release PR, triggered by @${{ github.actor }} for ${{ github.sha }}.
72+
73+
### Tasks
74+
- [ ] Add changelogs from backports, if applicable.
75+
- [ ] Once merged, create + push a tag.
76+
77+
<sub>https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}</sub>
78+
labels: |
79+
t: release
80+
assignees: |
81+
${{ github.actor }}

.github/workflows/lint-test.yml

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ on:
66
push:
77
branches:
88
- 'master'
9-
- 'v[0-9]+.[0-9]+.x' # matches to backport branches, e.g. 3.6
9+
- 'v[0-9]+.[0-9]+.x' # matches to backport branches, e.g. v3.6.x
1010
- 'run-ci/*'
1111
tags:
1212
pull_request:
@@ -122,10 +122,11 @@ jobs:
122122
run: nox -s check-manifest
123123

124124
# This only runs if the previous steps were successful, no point in running it otherwise
125-
- name: Build package
125+
- name: Try building package
126126
run: |
127-
python -m pip install -U build
128-
python -m build
127+
pdm install -dG build
128+
pdm run python -m build
129+
ls -la dist/
129130
130131
# run the libcst parsers and check for changes
131132
- name: libcst codemod

.pre-commit-config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ repos:
3535
args: [--negate]
3636
types: [text]
3737
exclude_types: [json, pofile]
38-
exclude: 'changelog/|py.typed|disnake/bin/COPYING|.github/PULL_REQUEST_TEMPLATE.md|LICENSE|MANIFEST.in'
38+
exclude: 'changelog/|py.typed|disnake/bin/COPYING|.github/PULL_REQUEST_TEMPLATE.md|.github/CODEOWNERS|LICENSE|MANIFEST.in'
3939

4040
- repo: https://github.com/pycqa/isort
4141
rev: 5.12.0

0 commit comments

Comments
 (0)