Skip to content

Commit

Permalink
Add workflow for creating release branches
Browse files Browse the repository at this point in the history
This change adds a GitHub Actions workflow for creating release branches
with jobs to 1) create the branch and 2) open a pull request with the
generated THIRD_PARTY_LICENSES file and updated getting started guide
version.

Signed-off-by: Austin Vazquez <[email protected]>
  • Loading branch information
austinvazquez committed Aug 27, 2024
1 parent a0a2671 commit 916aae9
Show file tree
Hide file tree
Showing 4 changed files with 231 additions and 8 deletions.
130 changes: 130 additions & 0 deletions .github/workflows/create-release-branch.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
name: Create release branch

on:
workflow_dispatch:
inputs:
major_minor_version:
description: 'Major.Minor release version'
required: true
base_commit:
description: 'Base commit SHA'
required: true
pull_request:
# Workflow should only ever be run from main, so exclude
# running on pull requests to release branch resources.
branches: ['main']
paths:
# Run workflow on changes to the workflow definition and its
# dependencies to spot check the workflow functionality.
- '.github/workflows/create-release-branch.yml'
- 'scripts/create-release-branch.sh'
- 'scripts/build-third-party-licenses.sh'
- 'scripts/update-getting-started-guide-.sh'

jobs:
test-create-branch:
if: github.event_name == 'pull_request'
runs-on: ubuntu-20.04

env:
VERSION: ''

steps:
- uses: actions/checkout@v4

- name: Mock workflow inputs on pull request
run: |
echo "VERSION=0.${{ github.event.pull_request.number }}" >> $GITHUB_ENV
- name: Test create release branch
run: bash scripts/create-release-branch.sh --assert --base ${{ github.sha }} --dry-run ${{ env.VERSION }}

- uses: actions/setup-go@v5

- name: Install go-licenses
run: go install github.com/google/[email protected]

- name: Generate third party licenses file
run: bash scripts/build-third-party-licenses.sh

- name: Test update getting started version in release branch
run: bash scripts/update-getting-started-guide-version.sh --assert ${{ env.VERSION }}.0

create-branch:
if: github.event_name == 'workflow_dispatch'
runs-on: ubuntu-20.04

permissions:
# Write permissions needed to create release branch.
# Risk for pwn requests is mitigated by seperating jobs such that
# workflows running with write permissions only use code from main.
contents: write

env:
VERSION: ''

steps:
- uses: actions/checkout@v4
with:
ref: main
sparse-checkout: |
scripts/create-release-branch.sh
- name: Set environment variable version to output to dependent jobs
run: |
echo "VERSION=${{ github.event.inputs.major_minor_version }}" >> $GITHUB_ENV
- name: Create release branch
run: bash scripts/create-release-branch.sh --base ${{ github.event.inputs.base_commit }} ${{ github.event.inputs.major_minor_version }}

outputs:
version: ${{ env.VERSION }}

initial-pr:
needs: create-branch
if: github.event_name == 'workflow_dispatch' && needs.create-branch.result == 'success'
runs-on: ubuntu-20.04

permissions:
# Write permissions needed to create pull request.
# Risk for pwn requests is mitigated by seperating jobs such that
# workflows running with write permissions only use code from the
# branch which was cut from main.
contents: write
pull-requests: write

steps:
- uses: actions/checkout@v4
with:
ref: release/${{ needs.create-branch.outputs.version }}

- uses: actions/setup-go@v5

- name: Install go-licenses
run: go install github.com/google/[email protected]

- name: Generate third party licenses file
run: bash scripts/build-third-party-licenses.sh

- name: Update getting started version in release branch
run: bash scripts/update-getting-started-guide-version.sh --verbose "${{ needs.create-branch.outputs.version }}.0"

- name: Create PR
uses: peter-evans/create-pull-request@v6
with:
title: 'Prepare release ${{ needs.create-branch.outputs.version }}'
commit-message: |
Prepare release ${{ needs.create-branch.outputs.version }}
This change adds the THIRD_PARTY_LICENSES file and updates the getting started guide for release/${{ needs.create-branch.outputs.version }}.
body: |
This change adds the THIRD_PARTY_LICENSES file and updates the getting started guide for release/${{ needs.create-branch.outputs.version }}.
Auto-generated by [create-pull-request](https://github.com/peter-evans/create-pull-request)
labels: easy-to-review, automated-pr
token: ${{ secrets.GITHUB_TOKEN }}
author: "GitHub <[email protected]>"
signoff: true
branch: 'create-pull-request/prepare-release-${{ needs.create-branch.outputs.version }}'
base: 'release/${{ needs.create-branch.outputs.version }}'
delete-branch: true
6 changes: 3 additions & 3 deletions .github/workflows/update-getting-started-guide.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ on:
release:
types: ['released']
pull_request:
branches: ['main', 'release/**']
branches: ['main']
paths:
# Run workflow on changes to the workflow definition itself to spot check
# the core version update functionality.
Expand Down Expand Up @@ -39,8 +39,8 @@ jobs:

permissions:
# Write permissions needed to create pull request.
# Risk is mitigated by seperating jobs such that workflows
# running with write permissions only use code from main.
# Risk for pwn requests is mitigated by seperating jobs such that
# workflows running with write permissions only use code from main.
contents: write
pull-requests: write

Expand Down
90 changes: 90 additions & 0 deletions scripts/create-release-branch.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
#!/usr/bin/env bash

# Copyright The Soci Snapshotter Authors.

# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at

# http://www.apache.org/licenses/LICENSE-2.0

# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# A script to create a release branch on origin from the given commit.
#
# Usage: bash create-release-branch.sh [-a|--assert] [-b|--base] [-d|--dry-run] <MAJOR_MINOR_VERSION>

set -eux -o pipefail

ASSERT=false
BASE_COMMIT=""
DRYRUN=false

while [[ $# -gt 0 ]]; do
case $1 in
--assert|-a)
ASSERT=true
shift # past argument
;;
--base|-b)
shift # past argument
BASE_COMMIT=$1
shift # past value
;;
--dry-run|-d)
DRYRUN=true
shift # past argument
;;
--*|-*)
echo "Unknown option $1"
exit 1
;;
*)
VERSION=$1
shift # past argument
;;
esac
done

sanitize_input() {
# Strip 'v' prefix from input if present.
VERSION=${VERSION/v/}
[[ $VERSION =~ ^[0-9]+\.[0-9]+$ ]] || (echo "Error: version does not match expected <major>.<minor> format" && exit 1)

if [ -n "$BASE_COMMIT" ]; then
[[ $BASE_COMMIT =~ ^[0-9a-fA-F]{7,40}$ ]] || (echo "Error: base commit does not match expected short|full format" && exit 1)
FOUND=$(git log --pretty=format:"%H" | grep "$BASE_COMMIT")
[ -n "$FOUND" ] || (echo "Error: base commit not found in history" && exit 1)
fi
}

assert_create_branch() {
local current_branch
current_branch=$(git rev-parse --abbrev-ref HEAD)
[ "$current_branch" = "release/${VERSION}" ] || (echo "Error: incorrect branch, expected: release/${VERSION}, actual: $current_branch" && exit 1)

local base_commit
base_commit=$(git show -s --format="%H")
[ "$base_commit" = "$BASE_COMMIT" ] || (echo "Error: incorrect base commit, expected: $BASE_COMMIT, actual: $base_commit" && exit 1)
}

sanitize_input

git checkout -b "release/${VERSION}" "${BASE_COMMIT}"

[ $ASSERT = true ] && assert_create_branch

PUSH_CMD="git push origin release/${VERSION}"
if [ $DRYRUN = true ]; then
# Dry-run mode is not able to use git push --dry-run as it still requires
# write permissions to the remote repository. The intent is to run dry-run mode
# in pull request workflows with a reduced permission set to mitigate risk for pwn requests.
# Alternatively assert the push command is correct.
[[ $PUSH_CMD == "git push origin release/${VERSION}" ]] || (echo "Error: expected: 'git push origin release/${VERSION}', actual: '$PUSH_CMD'" && exit 1)
else
$PUSH_CMD
fi
13 changes: 8 additions & 5 deletions scripts/update-getting-started-guide-version.sh
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@

set -eux -o pipefail

tag=$1

ASSERT=false
VERBOSE=false

Expand All @@ -41,14 +39,19 @@ while [[ $# -gt 0 ]]; do
exit 1
;;
*)
tag=$1
VERSION=$1
shift # past argument
;;
esac
done

# Strip 'v' prefix from tag if not already stripped.
VERSION=${tag/v/}
sanitize_input() {
# Strip 'v' prefix from input if present.
VERSION=${VERSION/v/}
[[ $VERSION =~ ^([0-9]+\.){2}[0-9]+(-.*){0,1}$ ]] || (echo "Error: version does not match expect <major>.<minor>.<patch> version format" && exit 1)
}

sanitize_input

assert_diff() {
local diff_output
Expand Down

0 comments on commit 916aae9

Please sign in to comment.