Skip to content

Commit

Permalink
ci: Refactor release workflow (#174)
Browse files Browse the repository at this point in the history
* ci: Refactor release workflow

* Fix `check-downstream-compiles`

* Support manual release on `workflow_dispatch`

* Fix token

* Switch to `ci-workflows` `main`

* Update changelog config
  • Loading branch information
samuelburnham authored Oct 21, 2024
1 parent 68a48fb commit f346b37
Show file tree
Hide file tree
Showing 4 changed files with 146 additions and 150 deletions.
52 changes: 52 additions & 0 deletions .github/changelog-config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
{
"template": "#{{CHANGELOG}}",
"categories": [
{
"title": "## 🚀 Features",
"labels": [
"feat"
]
},
{
"title": "## 🐛 Fixes",
"labels": [
"fix"
]
},
{
"title": "## ⚡️ Performance",
"labels": [
"perf"
]
},
{
"title": "## 🧪 Tests",
"labels": [
"test"
]
},
{
"title": "## 📝 Docs",
"labels": [
"docs"
]
},
{
"title": "## 🤖 CI",
"labels": [
"automated-issue",
"ci"
]
},
{
"title": "## Other",
"labels": []
}
],
"label_extractor": [
{
"pattern": "^(build|chore|ci|docs|feat|fix|perf|refactor|revert|style|test){1}(\\([\\w\\-\\.]+\\))?(!)?: ([\\w ])+([\\s\\S]*)",
"target": "$1"
}
]
}
163 changes: 51 additions & 112 deletions .github/workflows/release-pr.yml
Original file line number Diff line number Diff line change
@@ -1,126 +1,65 @@
name: Bump Version
# Workflow to create a new release PR, with one of the following two scenarios:
#
# - Major release
# - Pushes a new `release/<tag-prefix>-v<version>` branch based on latest `major.minor` version, e.g. `release/sphinx-v1.0`
# - Creates a new `release-pr-<tag-prefix>-v<version>` branch from the release, then bumps the version with the `version` input
# - Opens a release PR from `release-pr-<tag-prefix>-v<version>` to `release/<tag-prefix>-v<version>`
# - Minor release
# - Pushes a new `release/<tag-prefix>-v<version>` branch based on the latest compatible major release
# - Creates a new `release-pr-<tag-prefix>-v<version` branch from the release, then bumps the version with the `version` input
# - Opens a release PR from `release-pr-<tag-prefix>-v<version` to `release/<tag-prefix>-v<version>`
# - Patch release
# - Pushes a new `patch/<tag-prefix>-v<version>` branch based on `release/<tag-prefix>-v<version>`, then bumps the verision with the `version` input
# - Errors if the `release/<tag-prefix>-v<version>` branch doesn't exist
# - Opens a release PR from `patch/<tag-prefix>-v<version>` to `release/<tag-prefix>-v<version>`
#
# When the PR is merged, the caller can then trigger a release from `ci-workflows/actions/tag-release`
# NOTE: To get a rich changelog based on each commit prefix, merge without squashing. Otherwise, the changelog will only show the release PR
# The PR branch can then be safely deleted, while the release branch should have a branch protection rule for historical preservation
#
# The `ci-workflows` release PR action can be found at https://github.com/argumentcomputer/ci-workflows/blob/main/.github/actions/release-pr/action.yml
name: Create release PR
on:
workflow_dispatch:
inputs:
type:
description: 'release or hotfix'
release-type:
description: 'Semver release type'
required: true
default: 'major'
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
- major
- minor
- patch
version:
description: 'Version'
description: '`<major>.<minor>.<patch>` version, e.g. `1.0.0`'
required: true
type: string

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"
git config --global url."https://${{ secrets.REPO_TOKEN }}@github.com/".insteadOf ssh://[email protected]
git config --global url."https://${{ secrets.REPO_TOKEN }}@github.com".insteadOf https://github.com
- name: Checkout code
uses: actions/checkout@v4

- name: Install Rust
uses: dtolnay/rust-toolchain@stable

- name: Install `tq-rs`
run: cargo install tq-rs

# The `release/1.0` branch is always truncated, so that patch version merges still are valid Semver
# However, when we make the initial `release/1.0` version bump, we include the full `1.0.0` in `Cargo.toml`
# and the release for clarity
- name: Set branches
run: |
BASE_VERSION_SHORT=$(echo "${{ inputs.version }}" | cut -d'.' -f1-2)
BASE_VERSION="${BASE_VERSION_SHORT}.0"
if [[ "${{ inputs.type }}" == "hotfix" ]]; then
VERSION=${{ inputs.version }}
BASE_BRANCH="release/v$BASE_VERSION_SHORT"
PR_BRANCH="${{ inputs.type }}/v${{ inputs.version }}"
git checkout $PR_BRANCH
else
VERSION=$BASE_VERSION
BASE_BRANCH="dev"
PR_BRANCH="release/v$BASE_VERSION_SHORT"
git checkout -b $PR_BRANCH
fi
echo "BASE_BRANCH=$BASE_BRANCH" | tee -a $GITHUB_ENV
echo "PR_BRANCH=$PR_BRANCH" | tee -a $GITHUB_ENV
echo "PR_DESCRIPTION=chore: Release $VERSION" | tee -a $GITHUB_ENV
echo "VERSION=$VERSION" | tee -a $GITHUB_ENV
# 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: |
members=$(tq workspace.members -f Cargo.toml | jq -r '.[]')
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 }}
}
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"
- name: Commit changes
run: |
git add .
git commit -m "${{ env.PR_DESCRIPTION }}"
git push origin ${{ env.PR_BRANCH }}
# 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 the patched version of `${{ env.VERSION }}`.
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 `v${{ env.VERSION }}`.
[Workflow run](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})
EOF
gh pr create --title "${{ env.PR_DESCRIPTION }}" --body-file ./body.md --head ${{ env.PR_BRANCH }} --base ${{ env.BASE_BRANCH }}
env:
GH_TOKEN: ${{ github.token }}
git config --global user.name "argument-ci[bot]"
git config --global user.email "argument-ci[bot]@users.noreply.github.com"
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/checkout@v4
with:
repository: argumentcomputer/ci-workflows
path: ci-workflows
- uses: tibdex/github-app-token@v2
id: generate-token
with:
app_id: ${{ secrets.TOKEN_APP_ID }}
private_key: ${{ secrets.TOKEN_APP_PRIVATE_KEY }}
- name: Open release PR
uses: ./ci-workflows/.github/actions/release-pr
with:
tag-prefix: sphinx
release-type: ${{ inputs.release-type }}
version: ${{ inputs.version }}
token: ${{ steps.generate-token.outputs.token }}
78 changes: 40 additions & 38 deletions .github/workflows/tag-release.yml
Original file line number Diff line number Diff line change
@@ -1,61 +1,63 @@
name: Tag release
# Workflow to create a new tag release when a release branch is merged
#
# The `ci-workflows` tag release action can be found at https://github.com/argumentcomputer/ci-workflows/blob/main/.github/actions/tag-release/action.yml
name: Create tag release

on:
pull_request:
types: [ closed ]
branches:
- dev
- release/*
workflow_dispatch:
inputs:
release-branch:
description: 'Branch to release'
type: 'string'
required: true
version:
description: 'SemVer release version, e.g. `1.0.0`'
type: 'string'
required: true

jobs:
# Creates a new tag if a release branch is merged
tag-bump:
tag-release:
if: |
github.event.pull_request.merged == true &&
((startsWith(github.event.pull_request.head.ref, 'release/') && github.event.pull_request.base.ref == 'dev') ||
(startsWith(github.event.pull_request.head.ref, 'hotfix/') && startsWith(github.event.pull_request.base.ref, 'release/')))
(github.event.pull_request.merged == true &&
(startsWith(github.event.pull_request.head.ref, 'release-pr') ||
startsWith(github.event.pull_request.head.ref, 'patch/'))) ||
github.event_name == 'workflow_dispatch'
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"
git config --global url."https://${{ secrets.REPO_TOKEN }}@github.com/".insteadOf ssh://[email protected]
git config --global url."https://${{ secrets.REPO_TOKEN }}@github.com".insteadOf https://github.com
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Get version
id: get-version
- uses: actions/checkout@v4
with:
repository: argumentcomputer/ci-workflows
path: ci-workflows
- name: Get branch and version info
run: |
VERSION=$(echo "${{ github.event.pull_request.head.ref }}" | cut -d'/' -f 2)
RELEASE_BRANCH="${{ startsWith(github.event.pull_request.head.ref, 'release/') && github.event.pull_request.head.ref || github.event.pull_request.base.ref }}"
if [[ "${{ startsWith(github.event.pull_request.head.ref, 'release/') }}" == "true" ]]; then
VERSION="${VERSION}.0"
if [[ "${{ github.event_name }}" == "pull_request" ]]; then
RELEASE_BRANCH=${{ github.event.pull_request.base.ref }}
# Get tag and version from PR title
TAG=$(echo '${{ github.event.pull_request.title }}' | awk '/Release/ {print $NF}' | tr -d '`')
VERSION="${TAG#*-v}"
else
RELEASE_BRANCH=${{ inputs.release-branch }}
VERSION=${{ inputs.version }}
fi
git tag -a $VERSION -m "$VERSION" origin/$RELEASE_BRANCH
git push origin $VERSION --follow-tags
echo "version=$VERSION" | tee -a "$GITHUB_OUTPUT"
echo "RELEASE_BRANCH=$RELEASE_BRANCH" | tee -a "$GITHUB_ENV"
- name: Build Changelog
id: github_release
uses: mikepenz/release-changelog-builder-action@v5
with:
toTag: ${{ steps.get-version.outputs.version }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: Create Release
uses: ncipollo/release-action@v1
echo "RELEASE_BRANCH=$RELEASE_BRANCH" | tee -a $GITHUB_ENV
echo "VERSION=$VERSION" | tee -a $GITHUB_ENV
- name: Publish release
uses: ./ci-workflows/.github/actions/tag-release
with:
body: ${{ steps.github_release.outputs.changelog }}
tag: ${{ steps.get-version.outputs.version }}
commit: ${{ env.RELEASE_BRANCH }}
allowUpdates: true
release-branch: ${{ env.RELEASE_BRANCH }}
version: ${{ env.VERSION }}
tag-prefix: sphinx
changelog-config-file: ${{ github.workspace }}/.github/changelog-config.json
3 changes: 3 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,9 @@ jobs:
- repo: zk-light-clients
path: ethereum
features: ethereum
- repo: zk-light-clients
path: kadena
features: kadena
- repo: lurk
path: ""
steps:
Expand Down

0 comments on commit f346b37

Please sign in to comment.