Skip to content

Commit

Permalink
feat(ci): automated release workflow (#1072)
Browse files Browse the repository at this point in the history
  • Loading branch information
shiftinv committed Oct 30, 2023
1 parent 6fed323 commit 1e46654
Show file tree
Hide file tree
Showing 10 changed files with 505 additions and 7 deletions.
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 @@ -122,10 +122,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

0 comments on commit 1e46654

Please sign in to comment.