Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(ci): automated release workflow #1072

Merged
merged 48 commits into from
Oct 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
9ff128a
lint: ignore formatting for `version_info`
shiftinv Jun 24, 2023
630e93c
feat: add update_version.py
shiftinv Jul 5, 2023
be48ddf
feat: add release preparation workflow
shiftinv Jul 5, 2023
287c40b
feat: use app token
shiftinv Jul 5, 2023
fd8d33e
fix: use sha in description
shiftinv Jul 5, 2023
d5dcf1e
build: move towncrier to new `changelog` dev-deps group
shiftinv Jul 5, 2023
9d07b50
chore: pin create-pull-request commit
shiftinv Jul 5, 2023
428ca95
feat: add task list to PR text
shiftinv Jul 6, 2023
dc32cb2
fix: remove all workflow permissions
shiftinv Jul 6, 2023
afa863c
feat: print version if no script argument specified
shiftinv Jul 6, 2023
47b2adb
ci: add build (+ release) workflow
shiftinv Jul 6, 2023
1887082
feat: add (test) pypi upload
shiftinv Jul 6, 2023
300a8c4
chore: add version comments to tagged actions
shiftinv Jul 6, 2023
f91e8b0
feat: show sdist metadata
shiftinv Jul 6, 2023
aba15e0
fix: fix tag filter
shiftinv Jul 6, 2023
3a223e0
ci: use environment for pypi release
shiftinv Jul 6, 2023
898b443
chore: rename release workflow file
shiftinv Jul 6, 2023
e93c3e2
feat: validate git tag and sdist version
shiftinv Jul 8, 2023
ab3a752
fix: fix version regex in script
shiftinv Jul 8, 2023
9ed610d
chore: fix env var name
shiftinv Jul 8, 2023
40a5014
feat: add github release job
shiftinv Jul 8, 2023
7dc21e4
refactor: use argparse
shiftinv Jul 8, 2023
5a3d70f
fix: add contents permission for creating github releases
shiftinv Jul 8, 2023
4fc4305
feat: automatically create dev version bump PR
shiftinv Jul 8, 2023
4dc77a7
fix: unset persist-credentials
shiftinv Jul 8, 2023
36cd1f7
chore: disable pypi upload temporarily
shiftinv Jul 8, 2023
7546ee5
feat: add run url to PR desc
shiftinv Jul 9, 2023
a64ce60
chore: re-enable pypi upload
shiftinv Jul 9, 2023
f89d512
chore: improve workflow name
shiftinv Jul 9, 2023
b01969a
feat: set environment url
shiftinv Jul 9, 2023
3777859
feat: use repository variables for git user/email
shiftinv Jul 9, 2023
d5717bb
fix: boolean fun
shiftinv Jul 9, 2023
b6b3113
docs: create RELEASING.md
shiftinv Jul 9, 2023
cb12558
fix: no longer use testpypi
shiftinv Jul 9, 2023
ea7b785
feat: add CODEOWNERS for ci files
shiftinv Jul 9, 2023
363823d
chore: what
shiftinv Jul 9, 2023
4527a01
fix: use `tee -a` for package metadata step
shiftinv Jul 9, 2023
5c269f0
chore: more comments
shiftinv Jul 9, 2023
8e40eb4
docs: i know how to count
shiftinv Jul 9, 2023
58984e5
fix: oops
shiftinv Jul 9, 2023
5e4b180
fix: make check-manifest ignore RELEASING.md
shiftinv Jul 9, 2023
1927cc6
fix: don't run build on pull_request
shiftinv Jul 9, 2023
0e7a1d8
fix: remove unused PR label condition
shiftinv Jul 10, 2023
ae27a67
Merge remote-tracking branch 'upstream/master' into ci/release-workflow
shiftinv Oct 20, 2023
76fd25a
docs: simplify release process
shiftinv Oct 20, 2023
d56c570
chore: rename `RELEASING.md` to `RELEASE.md`
shiftinv Oct 20, 2023
7aeb024
chore: resolve lint issue
shiftinv Oct 20, 2023
5f6eddb
Merge remote-tracking branch 'upstream/master' into ci/release-workflow
shiftinv Oct 29, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners
/.github @DisnakeDev/maintainers
/scripts/ci @DisnakeDev/maintainers
227 changes: 227 additions & 0 deletions .github/workflows/build-release.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,227 @@
# SPDX-License-Identifier: MIT

name: Build (+ Release)

# test build for commit/tag, but only upload release for tags
on:
push:
branches:
- "master"
- 'v[0-9]+.[0-9]+.x' # matches to backport branches, e.g. v3.6.x
tags:
- "v[0-9]+.[0-9]+.[0-9]+"

permissions:
contents: read

jobs:
# Builds sdist and wheel, runs `twine check`, and optionally uploads artifacts.
build:
name: Build package
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3

- name: Set up environment
id: setup
uses: ./.github/actions/setup-env
with:
python-version: 3.8

- name: Install dependencies
run: pdm install -dG build

- name: Build package
run: |
pdm run python -m build
ls -la dist/

- name: Twine check
run: pdm run twine check --strict dist/*

- name: Show metadata
run: |
mkdir out/
tar -xf dist/*.tar.gz -C out/

echo -e "<details><summary>Metadata</summary>\n" >> $GITHUB_STEP_SUMMARY
cat out/*/PKG-INFO | sed 's/^/ /' | tee -a $GITHUB_STEP_SUMMARY
echo -e "\n</details>\n" >> $GITHUB_STEP_SUMMARY

- name: Upload artifact
# only upload artifacts when necessary
if: startsWith(github.ref, 'refs/tags/')
uses: actions/upload-artifact@v3
with:
name: dist
path: dist/
if-no-files-found: error


### Anything below this only runs for tags ###

# Ensures that git tag and built version match.
validate-tag:
name: Validate tag
runs-on: ubuntu-latest
if: startsWith(github.ref, 'refs/tags/')
needs:
- build
env:
GIT_TAG: ${{ github.ref_name }}
outputs:
bump_dev: ${{ steps.check-dev.outputs.bump_dev }}

steps:
- name: Download build artifact
uses: actions/download-artifact@v3
with:
name: dist
path: dist/

- name: Compare sdist version to git tag
run: |
mkdir out/
tar -xf dist/*.tar.gz -C out/

SDIST_VERSION="$(grep "^Version:" out/*/PKG-INFO | cut -d' ' -f2-)"
echo "git tag: $GIT_TAG"
echo "sdist version: $SDIST_VERSION"

if [ "$GIT_TAG" != "v$SDIST_VERSION" ]; then
echo "error: git tag does not match sdist version" >&2
exit 1
fi

- name: Determine if dev version PR is needed
id: check-dev
run: |
BUMP_DEV=
# if this is a new major/minor version, create a PR later
if [[ "$GIT_TAG" =~ ^v[0-9]+\.[0-9]+\.0$ ]]; then
BUMP_DEV=1
fi
echo "bump_dev=$BUMP_DEV" | tee -a $GITHUB_OUTPUT


# Creates a draft release on GitHub, and uploads the artifacts there.
release-github:
name: Create GitHub draft release
runs-on: ubuntu-latest
if: startsWith(github.ref, 'refs/tags/')
needs:
- build
- validate-tag
permissions:
contents: write # required for creating releases

steps:
- name: Download build artifact
uses: actions/download-artifact@v3
with:
name: dist
path: dist/

- name: Calculate versions
id: versions
env:
GIT_TAG: ${{ github.ref_name }}
run: |
# v1.2.3 -> v1-2-3 (for changelog)
echo "docs_version=${GIT_TAG//./-}" >> $GITHUB_OUTPUT

- name: Create Release
uses: softprops/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844 # v0.1.15
with:
files: dist/*
draft: true
body: |
TBD.

**Changelog**: https://docs.disnake.dev/en/stable/whats_new.html#${{ steps.versions.outputs.docs_version }}
**Git history**: https://github.com/${{ github.repository }}/compare/vTODO...${{ github.ref_name }}


# Creates a PyPI release (using an environment which requires separate confirmation).
release-pypi:
name: Publish package to pypi.org
environment:
name: release-pypi
url: https://pypi.org/project/disnake/
runs-on: ubuntu-latest
if: startsWith(github.ref, 'refs/tags/')
needs:
- build
- validate-tag
permissions:
id-token: write # this permission is mandatory for trusted publishing

steps:
- name: Download build artifact
uses: actions/download-artifact@v3
with:
name: dist
path: dist/

- name: Upload to pypi
uses: pypa/gh-action-pypi-publish@f5622bde02b04381239da3573277701ceca8f6a0 # v1.8.7
with:
print-hash: true


# Creates a PR to bump to an alpha version for development, if applicable.
create-dev-version-pr:
name: Create dev version bump PR
runs-on: ubuntu-latest
if: startsWith(github.ref, 'refs/tags/') && needs.validate-tag.outputs.bump_dev
needs:
- validate-tag
- release-github
- release-pypi

steps:
# 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
- name: Generate app token
id: generate_token
uses: tibdex/github-app-token@b62528385c34dbc9f38e5f4225ac829252d1ea92 # v1.8.0
with:
app_id: ${{ secrets.BOT_APP_ID }}
private_key: ${{ secrets.BOT_PRIVATE_KEY }}

- uses: actions/checkout@v3
with:
token: ${{ steps.generate_token.outputs.token }}
persist-credentials: false
ref: master # the PR action wants a proper base branch

- name: Set git name/email
env:
GIT_USER: ${{ vars.GIT_APP_USER_NAME }}
GIT_EMAIL: ${{ vars.GIT_APP_USER_EMAIL }}
run: |
git config user.name "$GIT_USER"
git config user.email "$GIT_EMAIL"

- name: Update version to dev
id: update-version
run: |
NEW_VERSION="$(python scripts/ci/versiontool.py --set dev)"
git commit -a -m "chore: update version to v$NEW_VERSION"
echo "new_version=$NEW_VERSION" >> $GITHUB_OUTPUT

- name: Create pull request
uses: peter-evans/create-pull-request@153407881ec5c347639a548ade7d8ad1d6740e38 # v5.0.2
with:
token: ${{ steps.generate_token.outputs.token }}
branch: auto/dev-v${{ steps.update-version.outputs.new_version }}
delete-branch: true
base: master
title: "chore: update version to v${{ steps.update-version.outputs.new_version }}"
body: |
Automated dev version PR.

<sub>https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}</sub>
labels: |
skip news
t: meta
2 changes: 1 addition & 1 deletion .github/workflows/changelog.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ jobs:
python-version: '3.9'

- name: Install dependencies
run: pdm install -dG tools
run: pdm install -dG changelog

- name: Check for presence of a Change Log fragment (only pull requests)
# NOTE: The pull request' base branch needs to be fetched so towncrier
Expand Down
81 changes: 81 additions & 0 deletions .github/workflows/create-release-pr.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# SPDX-License-Identifier: MIT

name: Create Release PR

on:
workflow_dispatch:
inputs:
version:
description: "The new version number, e.g. `1.2.3`."
type: string
required: true

permissions: {}

jobs:
create-release-pr:
name: Create Release PR
runs-on: ubuntu-latest

env:
VERSION_INPUT: ${{ inputs.version }}

steps:
# 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
- name: Generate app token
id: generate_token
uses: tibdex/github-app-token@b62528385c34dbc9f38e5f4225ac829252d1ea92 # v1.8.0
with:
app_id: ${{ secrets.BOT_APP_ID }}
private_key: ${{ secrets.BOT_PRIVATE_KEY }}

- uses: actions/checkout@v3
with:
token: ${{ steps.generate_token.outputs.token }}
persist-credentials: false

- name: Set git name/email
env:
GIT_USER: ${{ vars.GIT_APP_USER_NAME }}
GIT_EMAIL: ${{ vars.GIT_APP_USER_EMAIL }}
run: |
git config user.name "$GIT_USER"
git config user.email "$GIT_EMAIL"

- name: Set up environment
uses: ./.github/actions/setup-env
with:
python-version: 3.8

- name: Install dependencies
run: pdm install -dG changelog

- name: Update version
run: |
python scripts/ci/versiontool.py --set "$VERSION_INPUT"
git commit -a -m "chore: update version to $VERSION_INPUT"

- name: Build changelog
run: |
pdm run towncrier build --yes --version "$VERSION_INPUT"
git commit -a -m "docs: build changelog"

- name: Create pull request
uses: peter-evans/create-pull-request@153407881ec5c347639a548ade7d8ad1d6740e38 # v5.0.2
with:
token: ${{ steps.generate_token.outputs.token }}
branch: auto/release-v${{ inputs.version }}
delete-branch: true
title: "release: v${{ inputs.version }}"
body: |
Automated release PR, triggered by @${{ github.actor }} for ${{ github.sha }}.

### Tasks
- [ ] Add changelogs from backports, if applicable.
- [ ] Once merged, create + push a tag.

<sub>https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}</sub>
labels: |
t: release
assignees: |
${{ github.actor }}
9 changes: 5 additions & 4 deletions .github/workflows/lint-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ on:
push:
branches:
- 'master'
- 'v[0-9]+.[0-9]+.x' # matches to backport branches, e.g. 3.6
- 'v[0-9]+.[0-9]+.x' # matches to backport branches, e.g. v3.6.x
- 'run-ci/*'
tags:
pull_request:
Expand Down Expand Up @@ -124,10 +124,11 @@ jobs:
run: nox -s check-manifest

# This only runs if the previous steps were successful, no point in running it otherwise
- name: Build package
- name: Try building package
run: |
python -m pip install -U build
python -m build
pdm install -dG build
pdm run python -m build
ls -la dist/

# run the libcst parsers and check for changes
- name: libcst codemod
Expand Down
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ repos:
args: [--negate]
types: [text]
exclude_types: [json, pofile]
exclude: 'changelog/|py.typed|disnake/bin/COPYING|.github/PULL_REQUEST_TEMPLATE.md|LICENSE|MANIFEST.in'
exclude: 'changelog/|py.typed|disnake/bin/COPYING|.github/PULL_REQUEST_TEMPLATE.md|.github/CODEOWNERS|LICENSE|MANIFEST.in'

- repo: https://github.com/pycqa/isort
rev: 5.12.0
Expand Down
Loading