Skip to content

Commit

Permalink
Merge pull request #158 from papr/automate_maintenance
Browse files Browse the repository at this point in the history
Split version-bumping and deployment into separate workflows
  • Loading branch information
keent authored Jun 23, 2021
2 parents adcbbee + 5cf8046 commit e9fac19
Show file tree
Hide file tree
Showing 3 changed files with 129 additions and 136 deletions.
105 changes: 105 additions & 0 deletions .github/workflows/bump_version.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
name: Bump version
on:
pull_request:
branches: [master]
types: [closed]
workflow_dispatch:
inputs:
version_part:
description: >
Version part to bump before deployment.
Possible options {none, major, minor, patch}
required: true
default: 'patch'

jobs:
get_version_part_manually:
name: Bump version on manual workflow dispatch
if: github.event.inputs.version_part
runs-on: ubuntu-latest
env:
VERSION_PART: ${{ github.event.inputs.version_part }}
outputs:
# will be empty if validation fails
version_part: ${{ steps.validated_input.outputs.version_part }}
steps:
- name: Cancel on invalid input
if: >
!(
env.VERSION_PART == 'none' ||
env.VERSION_PART == 'major' ||
env.VERSION_PART == 'minor' ||
env.VERSION_PART == 'patch'
)
run: |
echo "::error:: \`$VERSION_PART\` is not a valid version part. Must be one of {none, major, minor, patch}"
exit 1
- name: Set version part based on manual input
id: validated_input
run: echo "::set-output name=version_part::$VERSION_PART"

get_version_part_on_pr_merge:
name: Bump version on pull reuqest merge
if: github.event.pull_request.merged == true
runs-on: ubuntu-latest
outputs:
version_part: ${{ join(steps.*.outputs.version_part, '') }}
steps:
- name: Cancel on bump:none
id: bump_none
if: contains(github.event.pull_request.labels.*.name, 'bump:none')
run: echo "::set-output name=version_part::none"
- name: Bump major
id: bump_major
if: >
steps.bump_none.conclusion == 'skipped' &&
contains(github.event.pull_request.labels.*.name, 'bump:major')
run: echo "::set-output name=version_part::major"
- name: Bump minor
id: bump_minor
if: >
steps.bump_none.conclusion == 'skipped' &&
steps.bump_major.conclusion == 'skipped' &&
contains(github.event.pull_request.labels.*.name, 'bump:minor')
run: echo "::set-output name=version_part::minor"
- name: Bump patch
id: bump_patch
if: >
steps.bump_none.conclusion == 'skipped' &&
steps.bump_major.conclusion == 'skipped' &&
steps.bump_minor.conclusion == 'skipped'
run: echo "::set-output name=version_part::patch"

bump_version:
name: Bump version
needs: [get_version_part_on_pr_merge, get_version_part_manually]
# always() needed to not automatically skip this job due to one of the
# get_version_part_* jobs being skipped and bump_version depending on both.
if: >
always() &&
(
needs.get_version_part_on_pr_merge.result == 'success' ||
needs.get_version_part_manually.result == 'success'
) &&
join(needs.*.outputs.version_part, '') != 'none'
env:
VERSION_PART: ${{ join(needs.*.outputs.version_part, '') }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v1
with:
python-version: 3.7
- name: Install bump2version
run: pip install bump2version
- uses: oleksiyrudenko/gha-git-credentials@v2-latest
with:
token: ${{ secrets.GITHUB_TOKEN }}
- name: Bump version
run: bump2version --verbose "$VERSION_PART"
- name: Push changes
uses: ad-m/github-push-action@master
with:
tags: true
branch: ${{ github.ref }}
github_token: ${{ secrets.PERSONAL_ACCESS_TOKEN }}
127 changes: 3 additions & 124 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
@@ -1,133 +1,15 @@
name: Deploy to PyPI
on:
pull_request:
branches: [master]
types: [closed]
workflow_dispatch:
inputs:
version_part:
description: >
Version part to bump before deployment.
Possible options {none, major, minor, patch}
required: true
default: 'patch'
push:
tags:
- "**"

jobs:
get_version_part_manually:
name: Bump version on manual workflow dispatch
if: github.event.inputs.version_part
runs-on: ubuntu-latest
env:
VERSION_PART: ${{ github.event.inputs.version_part }}
outputs:
# will be empty if validation fails
version_part: ${{ steps.validated_input.outputs.version_part }}
steps:
- name: Cancel on invalid input
if: >
!(
env.VERSION_PART == 'none' ||
env.VERSION_PART == 'major' ||
env.VERSION_PART == 'minor' ||
env.VERSION_PART == 'patch'
)
run: |
echo "::error:: \`$VERSION_PART\` is not a valid version part. Must be one of {none, major, minor, patch}"
exit 1
- name: Set version part based on manual input
id: validated_input
run: echo "::set-output name=version_part::$VERSION_PART"

get_version_part_on_pr_merge:
name: Bump version on pull reuqest merge
if: github.event.pull_request.merged == true
runs-on: ubuntu-latest
outputs:
version_part: ${{ join(steps.*.outputs.version_part, '') }}
steps:
- name: Cancel on bump:none
id: bump_none
if: contains(github.event.pull_request.labels.*.name, 'bump:none')
run: echo "::set-output name=version_part::none"
- name: Bump major
id: bump_major
if: >
steps.bump_none.conclusion == 'skipped' &&
contains(github.event.pull_request.labels.*.name, 'bump:major')
run: echo "::set-output name=version_part::major"
- name: Bump minor
id: bump_minor
if: >
steps.bump_none.conclusion == 'skipped' &&
steps.bump_major.conclusion == 'skipped' &&
contains(github.event.pull_request.labels.*.name, 'bump:minor')
run: echo "::set-output name=version_part::minor"
- name: Bump patch
id: bump_patch
if: >
steps.bump_none.conclusion == 'skipped' &&
steps.bump_major.conclusion == 'skipped' &&
steps.bump_minor.conclusion == 'skipped'
run: echo "::set-output name=version_part::patch"

bump_version:
name: Bump version
needs: [get_version_part_on_pr_merge, get_version_part_manually]
# always() needed to not automatically skip this job due to one of the
# get_version_part_* jobs being skipped and bump_version depending on both.
if: >
always() &&
(
needs.get_version_part_on_pr_merge.result == 'success' ||
needs.get_version_part_manually.result == 'success'
) &&
join(needs.*.outputs.version_part, '') != 'none'
env:
VERSION_PART: ${{ join(needs.*.outputs.version_part, '') }}
outputs:
bumped_version_sha: >
${{ steps.save_bumped_version_sha.outputs.bumped_version_sha || github.sha }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v1
with:
python-version: 3.7
- name: Install bump2version
run: pip install bump2version
- uses: oleksiyrudenko/gha-git-credentials@v2-latest
with:
token: ${{ secrets.GITHUB_TOKEN }}
- name: Bump version
run: bump2version --verbose "$VERSION_PART"
- name: Push changes
uses: ad-m/github-push-action@master
with:
tags: true
branch: ${{ github.ref }}
github_token: ${{ secrets.PERSONAL_ACCESS_TOKEN }}
- name: Save new git commit SHA to job output
id: save_bumped_version_sha
run: |
echo "Setting bumped_version_sha=$(git rev-parse HEAD)"
echo "::set-output name=bumped_version_sha::$(git rev-parse HEAD)"
build_sdist:
name: Build source distribution
runs-on: ubuntu-latest
needs: [bump_version]
# always() needed to not automatically skip this job due to one of the
# get_version_part_* jobs being skipped and bump_version depending on both.
if: >
always() &&
(
needs.bump_version.result == 'success' ||
needs.bump_version.result == 'skipped'
)
steps:
- uses: actions/checkout@v2
with:
ref: ${{ needs.bump_version.outputs.bumped_version_sha }}
- uses: actions/setup-python@v1
with:
python-version: 3.7
Expand All @@ -145,9 +27,6 @@ jobs:
name: Deploy to PyPI
runs-on: ubuntu-latest
needs: [build_sdist]
# always() needed to not automatically skip this job due to one of the
# get_version_part_* jobs being skipped and bump_version depending on both.
if: always() && needs.build_sdist.result == 'success'
steps:
- uses: actions/checkout@v2
- name: Download source package
Expand Down
33 changes: 21 additions & 12 deletions MAINTENANCE.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@
Maintenance is based on extra tools that are defined as [optional dependencies](https://setuptools.readthedocs.io/en/latest/userguide/dependency_management.html#optional-dependencies) in [`setup.py`](setup.py).
The sections below refer to them as "extra requirements".

To automate maintenance as much as possible, this repository features two Github Actions:
To automate maintenance as much as possible, this repository features three Github Actions:
1. [Test on push or pull request](.github/workflows/test.yml) - see [Testing](#testing)
1. [Bump version](.github/workflows/bump_version.yml) - see [Deployment](#deployment)
1. [Deploy to PyPI](.github/workflows/deploy.yml) - see [Deployment](#deployment)

## Testing
Expand All @@ -28,8 +29,8 @@ triggers on:
Deployment works by bumping the version, building a source distribution (`sdist`), and
uploading it to [PyPI](https://pypi.org/project/zeromq-pyre/) using [`twine`](https://twine.readthedocs.io/).

These steps are automated as part of the ["Deploy to PyPI" Github Action](.github/workflows/deploy.yml).
See below for details.
These steps are automated as part of the ["Bump version"](.github/workflows/bump_version.yml) and ["Deploy to PyPI"](.github/workflows/deploy.yml)
Github Actions. See below for details.

### Versioning

Expand All @@ -41,12 +42,18 @@ To avoid human error, it is recommended to use the
the `deploy` extra requirements. To manually bump the version, run `bump2version <part>`,
where `<part>` is either `major`, `minor`, or `patch`.

**Note:** It is **not** recommended to run this tool manually. Instead, this step has
been automated as part of the ["Deploy to PyPI" Github Action](.github/workflows/deploy.yml).
**Note 1:** It is **not** recommended to run this tool manually. Instead, this step has
been automated as part of the ["Bump version" Github Action](.github/workflows/bump_version.yml).
To push the version-bumped commit back to the repo, the action requires more permissions
than the [default `GITHUB_TOKEN` provides](https://github.com/zeromq/pyre/pull/155#issuecomment-861020168).
Instead, it [requires a personal access token](https://docs.github.com/en/actions/reference/authentication-in-a-workflow#granting-additional-permissions)
(PAT; stored and accessed as the `PERSONAL_ACCESS_TOKEN` secret). See below for further details.
(PAT; stored and accessed as the `PERSONAL_ACCESS_TOKEN` secret). This allows writing
to the repository and triggering the ["Deploy to PyPI" Github Action](.github/workflows/deploy.yml).

**Note 2:** Due to security restrictions, pull requests from forked repositories do not
have access to the workflow's secret. As a result, the "Bump version" workflow will fail
and not trigger a deployment. In these cases, the deployment needs to be triggered by
manually dispatching the workflow or pushing a tagged commit.

### Building a distribution

Expand All @@ -69,8 +76,7 @@ package installer (`pip`)](https://pypi.org/project/pip/) is the easiest way for
to install the project. It also allows other projects to easily define this project as
a dependency.

When triggered, the ["Deploy to PyPI" Github Action](.github/workflows/deploy.yml) bumps
the version, builds a source distribution, and deploys it to PyPI. See [Github Action usage](#github-action-usage)
When triggered, the ["Deploy to PyPI" Github Action](.github/workflows/deploy.yml) builds a source distribution, and deploys it to PyPI. See [Github Action usage](#github-action-usage)
below for information when the Github Action is triggered and how to control the version
part that will be bumped.

Expand All @@ -83,10 +89,13 @@ as an API token.

### Github Action usage

The ["Deploy to PyPI" Github Action](.github/workflows/deploy.yml) triggers on:
- merged pull requests
- commits being pushed to the `master` branch
- manual dispatch via [Github UI](https://github.com/zeromq/pyre/actions/workflows/deploy.yml)
The [Bump version](.github/workflows/bump_version.yml) Github Action triggers on:
- Merged pull requests to the `master` branch
- [Manual workflow dispatch](https://github.com/zeromq/pyre/actions/workflows/bump_version.yml)


The ["Deploy to PyPI"](.github/workflows/deploy.yml) Github Action triggers on:
- tags being pushed to the repository, including version bumps created by the [Bump version](.github/workflows/bump_version.yml) Github Action

There are four version part values for automatic version bumping: `none`, `major`,
`minor`, `patch` (default). For pull requests, you can assign one of the `bump:*`
Expand Down

0 comments on commit e9fac19

Please sign in to comment.