Skip to content

Commit

Permalink
Create release branches automatically during tag creation
Browse files Browse the repository at this point in the history
  • Loading branch information
jgiannuzzi committed Oct 17, 2023
1 parent 24842be commit 5a13f21
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 59 deletions.
67 changes: 15 additions & 52 deletions .github/workflows/create.yml
Original file line number Diff line number Diff line change
@@ -1,62 +1,15 @@
name: Create release branch or tag
name: Create release

on:
workflow_dispatch:
inputs:
type:
description: "What to create (branch or tag)"
required: true
type: choice
options:
- "branch"
- "tag"
version:
description: "Version - major and minor for a branch (e.g. 0.3), semver for a tag (e.g. 0.3.1 or 0.3.1-rc.1)"
description: "Version - needs to adhere to Semantic Versioning (e.g. 0.3.1 or 0.3.1-rc.1)"
required: true

jobs:
create-release:
name: Create release branch from main
if: github.event.inputs.type == 'branch'
environment: create-release
runs-on: ubuntu-latest
steps:
- name: Check version
id: version
uses: actions/github-script@v6
with:
script: |
const semver = /^(0|[1-9]\d*)\.(0|[1-9]\d*)$/;
const version = context.payload.inputs.version;
const match = version.match(semver);
if (match === null) {
core.setFailed('Invalid version format. Expected "MAJOR.MINOR".');
} else {
core.setOutput('branch', `release/${version}`);
}
- name: Generate an app token
id: app-token
uses: actions/create-github-app-token@v1
with:
app-id: ${{ secrets.APP_ID }}
private-key: ${{ secrets.APP_PRIVATE_KEY }}

- name: Checkout main branch
uses: actions/checkout@v4
with:
ref: main
token: ${{ steps.app-token.outputs.token }}

- name: Push
run: |
branch=${{ steps.version.outputs.branch }}
git checkout -b $branch
git push origin $branch
create-tag:
name: Create release tag from release branch
if: github.event.inputs.type == 'tag'
name: Create release ${{ github.event.inputs.version }}
environment: create-release
runs-on: ubuntu-latest
steps:
Expand All @@ -83,14 +36,24 @@ jobs:
app-id: ${{ secrets.APP_ID }}
private-key: ${{ secrets.APP_PRIVATE_KEY }}

- name: Checkout release branch
- name: Checkout
uses: actions/checkout@v4
with:
ref: ${{ steps.version.outputs.branch }}
token: ${{ steps.app-token.outputs.token }}
fetch-depth: 0

- name: Push
run: |
branch=${{ steps.version.outputs.branch }}
tag=${{ steps.version.outputs.tag }}
if git show-ref --verify --quiet refs/remotes/origin/$branch; then
echo "Checking out branch $branch"
git checkout --track origin/$branch
else
echo "Branch $branch does not exist, creating it"
git checkout -b $branch
git push origin $branch
fi
echo "Creating tag $tag"
git tag $tag
git push origin $tag
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ jobs:
if: startsWith(github.ref, 'refs/tags/v')
uses: actions/checkout@v4
with:
fetch-depth: 0
fetch-tags: 1

# The main branch is tagged as "main" and "edge".
# Tags are named after the version, e.g. "v0.1.0" -> "0.1.0".
Expand Down
12 changes: 6 additions & 6 deletions docs/maintainer.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,22 @@
* All development goes into the `main` branch via pull requests that need to be
approved and checks that need to pass.
* When we want to cut a new major or minor release, we can create a new release
branch named `release/MAJOR.MINOR` (e.g. `release/0.4`) by manually running
the `Create release branch or tag` workflow.
* We can then run the workflow again to create a tag, specifying the complete
branch named `release/MAJOR.MINOR` (e.g. `release/0.4`) and the accompanying
tag by manually running the `Create release` workflow, specifying the complete
semantic version (e.g. `0.4.0` or `0.4.0-beta.1`).
* Development continues on the `main` branch.
* Fixes can be backported to the release branch via pull requests that need to
be approved and checks that need to pass.
* A new patch release can then be made by calling the
`Create release branch or tag` workflow again.
* A new patch release can then be made by calling the `Create release` workflow
again.

## How is it enforced

* A GitHub app needs to exist and be installed on the repo with the
`contents:write` permissions. Its ID and private key need to be stored as
secrets under the `create-release` environment. This environment needs to be
limited to the `main` branch only.
limited to the `main` branch only, and require approval by the maintainers
(denying self-reviews).
* An environment named `release` needs to exist and be limited to the `main`
branch and the `v*` tags only. It needs to contain the Docker Hub credentials
as secrets and be registered on PyPI as a trusted provider for our Python
Expand Down

0 comments on commit 5a13f21

Please sign in to comment.