Skip to content

Commit e9fac19

Browse files
authored
Merge pull request #158 from papr/automate_maintenance
Split version-bumping and deployment into separate workflows
2 parents adcbbee + 5cf8046 commit e9fac19

File tree

3 files changed

+129
-136
lines changed

3 files changed

+129
-136
lines changed

.github/workflows/bump_version.yml

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
name: Bump version
2+
on:
3+
pull_request:
4+
branches: [master]
5+
types: [closed]
6+
workflow_dispatch:
7+
inputs:
8+
version_part:
9+
description: >
10+
Version part to bump before deployment.
11+
Possible options {none, major, minor, patch}
12+
required: true
13+
default: 'patch'
14+
15+
jobs:
16+
get_version_part_manually:
17+
name: Bump version on manual workflow dispatch
18+
if: github.event.inputs.version_part
19+
runs-on: ubuntu-latest
20+
env:
21+
VERSION_PART: ${{ github.event.inputs.version_part }}
22+
outputs:
23+
# will be empty if validation fails
24+
version_part: ${{ steps.validated_input.outputs.version_part }}
25+
steps:
26+
- name: Cancel on invalid input
27+
if: >
28+
!(
29+
env.VERSION_PART == 'none' ||
30+
env.VERSION_PART == 'major' ||
31+
env.VERSION_PART == 'minor' ||
32+
env.VERSION_PART == 'patch'
33+
)
34+
run: |
35+
echo "::error:: \`$VERSION_PART\` is not a valid version part. Must be one of {none, major, minor, patch}"
36+
exit 1
37+
- name: Set version part based on manual input
38+
id: validated_input
39+
run: echo "::set-output name=version_part::$VERSION_PART"
40+
41+
get_version_part_on_pr_merge:
42+
name: Bump version on pull reuqest merge
43+
if: github.event.pull_request.merged == true
44+
runs-on: ubuntu-latest
45+
outputs:
46+
version_part: ${{ join(steps.*.outputs.version_part, '') }}
47+
steps:
48+
- name: Cancel on bump:none
49+
id: bump_none
50+
if: contains(github.event.pull_request.labels.*.name, 'bump:none')
51+
run: echo "::set-output name=version_part::none"
52+
- name: Bump major
53+
id: bump_major
54+
if: >
55+
steps.bump_none.conclusion == 'skipped' &&
56+
contains(github.event.pull_request.labels.*.name, 'bump:major')
57+
run: echo "::set-output name=version_part::major"
58+
- name: Bump minor
59+
id: bump_minor
60+
if: >
61+
steps.bump_none.conclusion == 'skipped' &&
62+
steps.bump_major.conclusion == 'skipped' &&
63+
contains(github.event.pull_request.labels.*.name, 'bump:minor')
64+
run: echo "::set-output name=version_part::minor"
65+
- name: Bump patch
66+
id: bump_patch
67+
if: >
68+
steps.bump_none.conclusion == 'skipped' &&
69+
steps.bump_major.conclusion == 'skipped' &&
70+
steps.bump_minor.conclusion == 'skipped'
71+
run: echo "::set-output name=version_part::patch"
72+
73+
bump_version:
74+
name: Bump version
75+
needs: [get_version_part_on_pr_merge, get_version_part_manually]
76+
# always() needed to not automatically skip this job due to one of the
77+
# get_version_part_* jobs being skipped and bump_version depending on both.
78+
if: >
79+
always() &&
80+
(
81+
needs.get_version_part_on_pr_merge.result == 'success' ||
82+
needs.get_version_part_manually.result == 'success'
83+
) &&
84+
join(needs.*.outputs.version_part, '') != 'none'
85+
env:
86+
VERSION_PART: ${{ join(needs.*.outputs.version_part, '') }}
87+
runs-on: ubuntu-latest
88+
steps:
89+
- uses: actions/checkout@v2
90+
- uses: actions/setup-python@v1
91+
with:
92+
python-version: 3.7
93+
- name: Install bump2version
94+
run: pip install bump2version
95+
- uses: oleksiyrudenko/gha-git-credentials@v2-latest
96+
with:
97+
token: ${{ secrets.GITHUB_TOKEN }}
98+
- name: Bump version
99+
run: bump2version --verbose "$VERSION_PART"
100+
- name: Push changes
101+
uses: ad-m/github-push-action@master
102+
with:
103+
tags: true
104+
branch: ${{ github.ref }}
105+
github_token: ${{ secrets.PERSONAL_ACCESS_TOKEN }}

.github/workflows/deploy.yml

Lines changed: 3 additions & 124 deletions
Original file line numberDiff line numberDiff line change
@@ -1,133 +1,15 @@
11
name: Deploy to PyPI
22
on:
3-
pull_request:
4-
branches: [master]
5-
types: [closed]
6-
workflow_dispatch:
7-
inputs:
8-
version_part:
9-
description: >
10-
Version part to bump before deployment.
11-
Possible options {none, major, minor, patch}
12-
required: true
13-
default: 'patch'
3+
push:
4+
tags:
5+
- "**"
146

157
jobs:
16-
get_version_part_manually:
17-
name: Bump version on manual workflow dispatch
18-
if: github.event.inputs.version_part
19-
runs-on: ubuntu-latest
20-
env:
21-
VERSION_PART: ${{ github.event.inputs.version_part }}
22-
outputs:
23-
# will be empty if validation fails
24-
version_part: ${{ steps.validated_input.outputs.version_part }}
25-
steps:
26-
- name: Cancel on invalid input
27-
if: >
28-
!(
29-
env.VERSION_PART == 'none' ||
30-
env.VERSION_PART == 'major' ||
31-
env.VERSION_PART == 'minor' ||
32-
env.VERSION_PART == 'patch'
33-
)
34-
run: |
35-
echo "::error:: \`$VERSION_PART\` is not a valid version part. Must be one of {none, major, minor, patch}"
36-
exit 1
37-
- name: Set version part based on manual input
38-
id: validated_input
39-
run: echo "::set-output name=version_part::$VERSION_PART"
40-
41-
get_version_part_on_pr_merge:
42-
name: Bump version on pull reuqest merge
43-
if: github.event.pull_request.merged == true
44-
runs-on: ubuntu-latest
45-
outputs:
46-
version_part: ${{ join(steps.*.outputs.version_part, '') }}
47-
steps:
48-
- name: Cancel on bump:none
49-
id: bump_none
50-
if: contains(github.event.pull_request.labels.*.name, 'bump:none')
51-
run: echo "::set-output name=version_part::none"
52-
- name: Bump major
53-
id: bump_major
54-
if: >
55-
steps.bump_none.conclusion == 'skipped' &&
56-
contains(github.event.pull_request.labels.*.name, 'bump:major')
57-
run: echo "::set-output name=version_part::major"
58-
- name: Bump minor
59-
id: bump_minor
60-
if: >
61-
steps.bump_none.conclusion == 'skipped' &&
62-
steps.bump_major.conclusion == 'skipped' &&
63-
contains(github.event.pull_request.labels.*.name, 'bump:minor')
64-
run: echo "::set-output name=version_part::minor"
65-
- name: Bump patch
66-
id: bump_patch
67-
if: >
68-
steps.bump_none.conclusion == 'skipped' &&
69-
steps.bump_major.conclusion == 'skipped' &&
70-
steps.bump_minor.conclusion == 'skipped'
71-
run: echo "::set-output name=version_part::patch"
72-
73-
bump_version:
74-
name: Bump version
75-
needs: [get_version_part_on_pr_merge, get_version_part_manually]
76-
# always() needed to not automatically skip this job due to one of the
77-
# get_version_part_* jobs being skipped and bump_version depending on both.
78-
if: >
79-
always() &&
80-
(
81-
needs.get_version_part_on_pr_merge.result == 'success' ||
82-
needs.get_version_part_manually.result == 'success'
83-
) &&
84-
join(needs.*.outputs.version_part, '') != 'none'
85-
env:
86-
VERSION_PART: ${{ join(needs.*.outputs.version_part, '') }}
87-
outputs:
88-
bumped_version_sha: >
89-
${{ steps.save_bumped_version_sha.outputs.bumped_version_sha || github.sha }}
90-
runs-on: ubuntu-latest
91-
steps:
92-
- uses: actions/checkout@v2
93-
- uses: actions/setup-python@v1
94-
with:
95-
python-version: 3.7
96-
- name: Install bump2version
97-
run: pip install bump2version
98-
- uses: oleksiyrudenko/gha-git-credentials@v2-latest
99-
with:
100-
token: ${{ secrets.GITHUB_TOKEN }}
101-
- name: Bump version
102-
run: bump2version --verbose "$VERSION_PART"
103-
- name: Push changes
104-
uses: ad-m/github-push-action@master
105-
with:
106-
tags: true
107-
branch: ${{ github.ref }}
108-
github_token: ${{ secrets.PERSONAL_ACCESS_TOKEN }}
109-
- name: Save new git commit SHA to job output
110-
id: save_bumped_version_sha
111-
run: |
112-
echo "Setting bumped_version_sha=$(git rev-parse HEAD)"
113-
echo "::set-output name=bumped_version_sha::$(git rev-parse HEAD)"
114-
1158
build_sdist:
1169
name: Build source distribution
11710
runs-on: ubuntu-latest
118-
needs: [bump_version]
119-
# always() needed to not automatically skip this job due to one of the
120-
# get_version_part_* jobs being skipped and bump_version depending on both.
121-
if: >
122-
always() &&
123-
(
124-
needs.bump_version.result == 'success' ||
125-
needs.bump_version.result == 'skipped'
126-
)
12711
steps:
12812
- uses: actions/checkout@v2
129-
with:
130-
ref: ${{ needs.bump_version.outputs.bumped_version_sha }}
13113
- uses: actions/setup-python@v1
13214
with:
13315
python-version: 3.7
@@ -145,9 +27,6 @@ jobs:
14527
name: Deploy to PyPI
14628
runs-on: ubuntu-latest
14729
needs: [build_sdist]
148-
# always() needed to not automatically skip this job due to one of the
149-
# get_version_part_* jobs being skipped and bump_version depending on both.
150-
if: always() && needs.build_sdist.result == 'success'
15130
steps:
15231
- uses: actions/checkout@v2
15332
- name: Download source package

MAINTENANCE.md

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@
33
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).
44
The sections below refer to them as "extra requirements".
55

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

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

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

3435
### Versioning
3536

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

44-
**Note:** It is **not** recommended to run this tool manually. Instead, this step has
45-
been automated as part of the ["Deploy to PyPI" Github Action](.github/workflows/deploy.yml).
45+
**Note 1:** It is **not** recommended to run this tool manually. Instead, this step has
46+
been automated as part of the ["Bump version" Github Action](.github/workflows/bump_version.yml).
4647
To push the version-bumped commit back to the repo, the action requires more permissions
4748
than the [default `GITHUB_TOKEN` provides](https://github.com/zeromq/pyre/pull/155#issuecomment-861020168).
4849
Instead, it [requires a personal access token](https://docs.github.com/en/actions/reference/authentication-in-a-workflow#granting-additional-permissions)
49-
(PAT; stored and accessed as the `PERSONAL_ACCESS_TOKEN` secret). See below for further details.
50+
(PAT; stored and accessed as the `PERSONAL_ACCESS_TOKEN` secret). This allows writing
51+
to the repository and triggering the ["Deploy to PyPI" Github Action](.github/workflows/deploy.yml).
52+
53+
**Note 2:** Due to security restrictions, pull requests from forked repositories do not
54+
have access to the workflow's secret. As a result, the "Bump version" workflow will fail
55+
and not trigger a deployment. In these cases, the deployment needs to be triggered by
56+
manually dispatching the workflow or pushing a tagged commit.
5057

5158
### Building a distribution
5259

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

72-
When triggered, the ["Deploy to PyPI" Github Action](.github/workflows/deploy.yml) bumps
73-
the version, builds a source distribution, and deploys it to PyPI. See [Github Action usage](#github-action-usage)
79+
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)
7480
below for information when the Github Action is triggered and how to control the version
7581
part that will be bumped.
7682

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

8490
### Github Action usage
8591

86-
The ["Deploy to PyPI" Github Action](.github/workflows/deploy.yml) triggers on:
87-
- merged pull requests
88-
- commits being pushed to the `master` branch
89-
- manual dispatch via [Github UI](https://github.com/zeromq/pyre/actions/workflows/deploy.yml)
92+
The [Bump version](.github/workflows/bump_version.yml) Github Action triggers on:
93+
- Merged pull requests to the `master` branch
94+
- [Manual workflow dispatch](https://github.com/zeromq/pyre/actions/workflows/bump_version.yml)
95+
96+
97+
The ["Deploy to PyPI"](.github/workflows/deploy.yml) Github Action triggers on:
98+
- tags being pushed to the repository, including version bumps created by the [Bump version](.github/workflows/bump_version.yml) Github Action
9099

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

0 commit comments

Comments
 (0)