Skip to content

Create release PR

Create release PR #22

# Workflow to create a new release PR, which does the following:
#
# - Pushes a new `release/<light-client>-v<version>` branch based on latest `dev`
# - Creates a new branch from the release, then bumps the version with the `version` input
# - Opens a PR from the `version-bump` branch to the release branch
# - When merged, triggers a release from `tag-release.yml`
#
# The `version-bump` branch can then be safely deleted, while the release branch will be protected
name: Bump Version
on:
workflow_dispatch:
inputs:
light-client:
description: 'aptos or ethereum'
type: choice
options:
- aptos
- ethereum
- kadena
required: true
default: 'aptos'
type:
description: 'release or hotfix'
type: choice
options:
- release
- hotfix
required: true
default: 'release'
# NOTE: For a `release` branch, only specify the `major.minor` version. This branch will be persistent across patches,
# so any patch number specified in this case will be dropped. For a hotfix, specify the full `major.minor.patch` version
version:
description: 'Version'
required: true
jobs:
release:
runs-on: ubuntu-latest
steps:
- name: Git config
run: |
git config --global user.name "github-actions[bot]"
git config --global user.email "github-actions[bot]@users.noreply.github.com"
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Install Rust
uses: dtolnay/rust-toolchain@master
with:
toolchain: nightly-2024-05-31
- name: Install `tq-rs`
run: cargo install tq-rs
#- uses: tibdex/github-app-token@v2
# id: generate-token
# with:
# app_id: ${{ secrets.TOKEN_APP_ID }}
# private_key: ${{ secrets.TOKEN_APP_PRIVATE_KEY }}
# The `release/<aptos|ethereum|kadena>-v1.0` branch is always truncated, as we don't want to change
# the release branch name for patch versions
#
# However, when we make e.g. a `release/<aptos|ethereum|kadena>-v1.0` version bump, we include the full
# `1.0.0` in `Cargo.toml` and the release for clarity
- name: Create release branch
run: |
BASE_VERSION="${{ inputs.version}}.0"
BASE_VERSION_SHORT=$(echo "${{ inputs.version }}" | cut -d'.' -f1-2)
BASE_BRANCH="release/${{ inputs.light-client }}-v$BASE_VERSION_SHORT"
if [[ "${{ inputs.type }}" == "release" ]]; then
git checkout -b $BASE_BRANCH
git push origin $BASE_BRANCH
else
git checkout $BASE_BRANCH
fi
echo "BASE_VERSION=$BASE_VERSION" | tee -a $GITHUB_ENV
echo "BASE_BRANCH=$BASE_BRANCH" | tee -a $GITHUB_ENV
env:
GITHUB_TOKEN: ${{ secrets.REPO_TOKEN }}
- name: Create PR branch
run: |
if [[ "${{ inputs.type }}" == "hotfix" ]]; then
VERSION=${{ inputs.version }}
PR_BRANCH="${{ inputs.type }}/${{ inputs.light-client }}-v${{ inputs.version }}"
else
VERSION=$BASE_VERSION
PR_BRANCH="version-bump"
fi
git checkout -b $PR_BRANCH
echo "VERSION=$VERSION" | tee -a $GITHUB_ENV
echo "PR_BRANCH=$PR_BRANCH" | tee -a $GITHUB_ENV
echo "PR_TITLE=chore(${{ inputs.light-client }}): Release $VERSION" | tee -a $GITHUB_ENV
env:
GITHUB_TOKEN: ${{ secrets.REPO_TOKEN }}
# Regex from https://semver.org/#is-there-a-suggested-regular-expression-regex-to-check-a-semver-string
- name: Validate version
run: |
echo "Validating version ${{ env.VERSION }}..."
D='0|[1-9][0-9]*'
PW='[0-9]*[a-zA-Z-][0-9a-zA-Z-]*'
MW='[0-9a-zA-Z-]+'
if [[ "${{ env.VERSION }}" =~ ^($D)\.($D)\.($D)(-(($D|$PW)(\.($D|$PW))*))?(\+($MW(\.$MW)*))?$ ]]; then
echo "Version ${{ env.VERSION }} is valid."
else
echo "Version is not valid SemVer. Aborting..."
exit 1
fi
- name: Update version in Cargo.toml
run: |
echo "Updating version in Cargo.toml..."
if [[ "${{ inputs.light-client }}" == "ethereum" ]]; then
members=$(tq workspace.members -f Cargo.toml | jq -r '. += ["programs/inclusion", "programs/committee-change"] | .[]')
elif [[ "${{ inputs.light-client }}" == "aptos" ]]; then
members=$(tq workspace.members -f Cargo.toml | jq -r '. += ["programs/inclusion", "programs/epoch-change"] | .[]')
elif [[ "${{ inputs.light-client }}" == "kadena" ]]; then
members=$(tq workspace.members -f Cargo.toml | jq -r '. += [""] | .[]')
else
echo "Unknown light-client: ${{ inputs.light-client }}. Aborting..."
exit 1
fi
bump_version() {
cd "$1"
OLD_VERSION=$(grep -oP 'version = "\K[^"]+' Cargo.toml | head -n1)
if [[ "${{ env.VERSION }}" > "$OLD_VERSION" ]]; then
sed -i "s/version = \"$OLD_VERSION\"/version = \"${{ env.VERSION }}\"/" Cargo.toml
else
echo "New version is not greater than the current version for $1. Aborting..."
exit 1
fi
cd ${{ github.workspace }}/${{ inputs.light-client }}
}
while IFS= read -r path; do
if [[ "$path" == *"/*" ]]; then
for dir in "${path%/*}"/*; do
if [ -d "$dir" ] && [ -f "$dir/Cargo.toml" ]; then
bump_version "$dir"
fi
done
else
bump_version "$path"
fi
done <<< "$members"
working-directory: ${{ github.workspace }}/${{ inputs.light-client }}
- name: Commit changes
run: |
git add .
git commit -m "${{ env.PR_TITLE }}"
git push origin ${{ env.PR_BRANCH }}
env:
GITHUB_TOKEN: ${{ secrets.REPO_TOKEN }}
# Note: Can't use `peter-evans/create-pull-request` because for hotfixes we need to make the PR with an existing branch
# The former always creates a new one for single-commit PRs, thus overwriting the actual hotfix
- name: Create PR
run: |
cat << 'EOF' > body.md
This is an automated release PR for version `${{ env.VERSION }}` of the ${{ inputs.light-client }} light client.
Please update the Sphinx dependency versions to the appropriate release tag manually. (TODO: Automate)
On merge, this will trigger the [release publish workflow](${{ github.server_url }}/${{ github.repository }}/actions/workflows/tag-release.yml), which will upload a new GitHub release with tag `${{ inputs.light-client }}-v${{ env.VERSION }}`.
[Workflow run](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})
EOF
gh pr create --title "${{ env.PR_TITLE }}" --body-file ./body.md --head ${{ env.PR_BRANCH }} --base ${{ env.BASE_BRANCH }}
env:
GH_TOKEN: ${{ secrets.REPO_TOKEN }}