Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ci: Refactor release workflow #174

Merged
merged 6 commits into from
Oct 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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://git@github.com
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://git@github.com
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