From 5a13f214514533521d282b99e3e96b0a7640bdd4 Mon Sep 17 00:00:00 2001 From: Jonathan Giannuzzi Date: Tue, 17 Oct 2023 02:00:34 +0100 Subject: [PATCH] Create release branches automatically during tag creation --- .github/workflows/create.yml | 67 ++++++++--------------------------- .github/workflows/release.yml | 2 +- docs/maintainer.md | 12 +++---- 3 files changed, 22 insertions(+), 59 deletions(-) diff --git a/.github/workflows/create.yml b/.github/workflows/create.yml index 0186b0c37..4fb291b7c 100644 --- a/.github/workflows/create.yml +++ b/.github/workflows/create.yml @@ -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: @@ -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 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 1db79309a..b5b49b435 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -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". diff --git a/docs/maintainer.md b/docs/maintainer.md index e4aedae7d..01af21a10 100644 --- a/docs/maintainer.md +++ b/docs/maintainer.md @@ -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