Compare commits

...

18 Commits

Author SHA1 Message Date
Bart Thomee
b251d73f87 Remove unnecessary check 2025-10-22 14:14:17 -04:00
Bart Thomee
be55d27fff Improve comments 2025-10-17 15:23:20 -04:00
Bart Thomee
cd2b194b0a Separate out merge queue from pull request workflows 2025-10-17 15:18:27 -04:00
Bart Thomee
99397dfb2e Merge branch 'develop' into bthomee/merge_queue 2025-10-17 13:17:56 -04:00
Bart
15e2150cdf Apply suggestion from @ximinez
Co-authored-by: Ed Hennis <ed@ripple.com>
2025-10-17 13:13:41 -04:00
Bart
1e41b68d71 Apply suggestion from @ximinez
Co-authored-by: Ed Hennis <ed@ripple.com>
2025-10-17 13:13:30 -04:00
Bart Thomee
a3fa2bd1c5 Review feedback 2025-10-17 12:32:44 -04:00
Bart Thomee
7d9b2dbd10 Merge branch 'develop' into bthomee/merge_queue 2025-10-17 12:26:56 -04:00
Bart Thomee
b4dbe8d7e7 Fix trigger workflow, support non-default remotes 2025-10-16 16:27:32 -04:00
Bart Thomee
f71d058c29 Merge branch 'develop' into bthomee/merge_queue 2025-10-16 16:14:31 -04:00
Bart Thomee
3ca5a958d7 Fix typo 2025-10-16 14:12:02 -04:00
Bart Thomee
a84c1f69d5 Update script echo statement 2025-10-15 17:22:11 -04:00
Bart Thomee
38999b2ff8 Remove unnecessary script 2025-10-15 17:10:03 -04:00
Bart Thomee
f611938a7b Skip CI if the 'SkipRunCI' label has been added 2025-10-15 17:09:03 -04:00
Bart Thomee
78f390714d Remove script meant for different PR 2025-10-15 12:02:11 -04:00
Bart Thomee
72f91e289b Add check to run during merge queue to ensure a custom commit message has been written 2025-10-15 11:59:37 -04:00
Bart Thomee
24f5c2f08b Merge branch 'develop' into bthomee/merge_queue 2025-10-15 11:04:26 -04:00
Bart Thomee
779094f6aa chore: Add script to squash commits in PRs ready to merge 2025-10-14 14:14:21 -04:00
4 changed files with 258 additions and 18 deletions

View File

@@ -1,13 +1,8 @@
# This workflow runs all workflows to check, build and test the project on
# various Linux flavors, as well as on MacOS and Windows, on every push to a
# user branch. However, it will not run if the pull request is a draft unless it
# has the 'DraftRunCI' label.
# various Linux flavors, as well as on MacOS and Windows, for various PR events.
name: PR
on:
merge_group:
types:
- checks_requested
pull_request:
types:
- opened
@@ -25,10 +20,18 @@ defaults:
jobs:
# This job determines whether the rest of the workflow should run. It runs
# when the PR is not a draft (which should also cover merge-group) or
# has the 'DraftRunCI' label.
# when the PR is not a draft or has the 'DraftRunCI' label and does NOT have
# the 'SkipRunCI' and 'MergeQueueCI' labels. The former two labels will result
# in the PR not being allowed to be merged, whereas the latter label will
# allow it to be merged without running the full CI suite, because the merge
# queue will verify that the code builds and passes tests before the PR is
# actually merged.
should-run:
if: ${{ !github.event.pull_request.draft || contains(github.event.pull_request.labels.*.name, 'DraftRunCI') }}
if: ${{
(!github.event.pull_request.draft || contains(github.event.pull_request.labels.*.name, 'DraftRunCI')) &&
!contains(github.event.pull_request.labels.*.name, 'SkipRunCI') &&
!contains(github.event.pull_request.labels.*.name, 'MergeQueueCI')
}}
runs-on: ubuntu-latest
steps:
- name: Checkout repository
@@ -75,20 +78,20 @@ jobs:
conanfile.py
conan.lock
- name: Check whether to run
# This step determines whether the rest of the workflow should
# run. The rest of the workflow will run if this job runs AND at
# least one of:
# * Any of the files checked in the `changes` step were modified
# * The PR is NOT a draft and is labeled "Ready to merge"
# * The workflow is running from the merge queue
# This step determines whether the rest of the workflow should run. If
# it runs and all jobs complete successfully, then the 'passed' job is
# marked as 'skipped' and, because its direct dependencies ran, the PR
# is allowed to be merged. This workflow will run when at least one of
# the following is true:
# * Any of the files checked in the `changes` step were modified.
# * The PR is NOT a draft and is labeled 'Ready to merge'.
id: go
env:
FILES: ${{ steps.changes.outputs.any_changed }}
DRAFT: ${{ github.event.pull_request.draft }}
READY: ${{ contains(github.event.pull_request.labels.*.name, 'Ready to merge') }}
MERGE: ${{ github.event_name == 'merge_group' }}
run: |
echo "go=${{ (env.DRAFT != 'true' && env.READY == 'true') || env.FILES == 'true' || env.MERGE == 'true' }}" >> "${GITHUB_OUTPUT}"
echo "go=${{ (env.DRAFT != 'true' && env.READY == 'true') || env.FILES == 'true' }}" >> "${GITHUB_OUTPUT}"
cat "${GITHUB_OUTPUT}"
outputs:
go: ${{ steps.go.outputs.go == 'true' }}
@@ -123,7 +126,7 @@ jobs:
conan_remote_password: ${{ secrets.CONAN_REMOTE_PASSWORD }}
passed:
if: failure() || cancelled()
if: ${{ failure() || cancelled() }}
needs:
- build-test
- check-levelization

35
.github/workflows/on-queue.yml vendored Normal file
View File

@@ -0,0 +1,35 @@
# This workflow runs all workflows to check, build and test the project on
# various Linux flavors, as well as on MacOS and Windows, when a PR is added to
# the merge queue.
name: Merge Queue
on:
merge_group:
types:
- checks_requested
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
defaults:
run:
shell: bash
jobs:
check-commit-message:
uses: ./.github/workflows/reusable-check-commit-message.yml
check-levelization:
uses: ./.github/workflows/reusable-check-levelization.yml
build-test:
uses: ./.github/workflows/reusable-build-test.yml
strategy:
fail-fast: false
matrix:
os: [linux, macos, windows]
with:
os: ${{ matrix.os }}
secrets:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}

View File

@@ -0,0 +1,72 @@
# This workflow checks that the commit message follows our expected format.
name: Check commit message
# This workflow can only be triggered by other workflows.
on: workflow_call
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}-single-commit
cancel-in-progress: true
defaults:
run:
shell: bash
jobs:
check:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
with:
fetch-depth: 0
- name: Check commit message
env:
MESSAGE: |
If you are reading this, then the commit message does not match our
expected format. See CONTRIBUTING.md for instructions.
It is further possible that you did not run the script in
`bin/git/squash-commits.sh` before clicking the 'Merge when ready'
button in GitHub's UI.
run: |
set -o pipefail
COMMIT_MSG='${{ github.event.head_commit.message }}'
echo "Commit message: ${COMMIT_MSG}"
# If the commit title contains a prefix then it must be one we permit.
COMMIT_TITLE=$(echo "${COMMIT_MSG}" | head -n1)
echo "Commit title: '${COMMIT_TITLE}'"
if [[ "${COMMIT_TITLE}" =~ ^[^:]+:[^:]+ ]]; then
if ! [[ "${COMMIT_TITLE}" =~ ^(build|chore|docs|fix|perf|refactor|test):[^:]+ ]]; then
echo "Commit title prefix is not permitted."
echo "${MESSAGE}"
exit 1
fi
fi
# The commit description may not only contain a list of commits, which
# is what happens if a PR containing multiple commits is squashed and
# merged by GitHub.
COMMIT_DESC=$(echo "${COMMIT_MSG}" | tail -n+3)
echo "Commit description: '${COMMIT_DESC}'"
while IFS=$'\n' read -r LINE; do
echo "Processing: ${LINE}"
# Check for lines starting with '-' or '*' followed by a space.
if ! [[ "${LINE}" =~ ^[[:space:]]*[-*][[:space:]]+.* ]]; then
exit 0
fi
# Check if the next line is empty.
IFS=$'\n' read -r LINE
if [ -n "${LINE}" ]; then
exit 0
fi
done <<< "${COMMIT_DESC}"
echo "Commit description is not permitted."
echo "${MESSAGE}"
exit 1

130
bin/git/squash-commits.sh Normal file
View File

@@ -0,0 +1,130 @@
#!/bin/bash
if [[ $# -ne 3 || "$1" == "--help" || "$1" = "-h" ]]
then
name=$( basename $0 )
cat <<- USAGE
Usage: $name pr "title" "description"
* All commits in the specified PR will be squashed and a new commit prepared
with the provided title and description as commit message.
* This script will not push the new commit. You will need to do so yourself
by force-pushing, since you will be rewriting history. You must be the
author of the PR or a maintainer of the repository in order to perform this
operation.
* The 'gh' CLI tool must be installed and authenticated.
* To write a multiline description, you can use "\$(cat <<EOF
line 1
line 2
EOF
)" to pass it as a single argument.
* If you get a '[rejected]' error when updating the target branch and then
locally merging the changes into the source branch, it is likely because the
source branch already exists on your machine (e.g. you ran this script
multiple times). In that case, you can delete the local source branch
(e.g. 'git branch -D [source]') and try again.
USAGE
exit 0
fi
pr="$1"
shift
title=$1
shift
description=$1
shift
set -e
echo "Checking workspace."
diff=$(git status --porcelain)
if [ -n "${diff}" ]; then
echo "Error: Workspace is not clean. Please commit or stash your changes."
exit 1
fi
echo "Checking out PR ${pr}."
gh pr checkout "${pr}"
echo "Getting the target branch of the PR."
target=$(gh pr view --json "baseRefName" --jq '.baseRefName')
if [ -z "${target}" ]; then
echo "Error: Could not determine target branch of PR ${pr}."
exit 1
fi
echo "Getting the source branch of the PR."
source=$(git branch --show-current)
echo "Ensuring the PR source branch '${source}' is up to date with the target branch '${target}'."
git checkout ${target}
git pull --rebase
gh pr checkout "${pr}"
git merge ${target} --no-edit
# TODO: check for conflicts and abort if there are any.
echo "Squashing commits in the PR."
git reset --soft $(git merge-base ${target} HEAD)
git commit -S -m "${title}" -m "${description}"
# We assume that external contributors will create a fork in their personal
# repository, i.e. the repo owner matches the currently logged in user. In that
# case they can push directly to their branch. If the owner is 'XRPLF', we also
# push directly to the branch, as we assume that the user running this script
# will be a maintainer.
echo "Gathering user details."
owner=$(gh pr view --json "headRepositoryOwner" --jq '.headRepositoryOwner.login')
user=$(gh api user --jq '.login')
echo "The PR is owned by '${owner}'. The current user is '${user}'."
if [ "${owner}" = 'XRPLF' ] || [ "${owner}" = "${user}" ]; then
remote="$(git remote -v | grep ":${owner}/rippled.git (push)" | head -1 | cut -f1)"
else
remote="${owner}"
fi
if [ "${remote}" = "origin" ]; then
cat << EOF
----------------------------------------------------------------------
This script will not push. Verify everything is correct, then force
push to the source branch using the following commands:
gh pr edit ${pr} --add-label 'MergeQueueCI'
git push --force-with-lease origin ${source}
The first command adds a label to the PR to skip running CI on the new
commit. As we are using a merge queue, CI will be run when the PR is added to
the queue, which is required to pass before the changes are merged.
Remember to navigate back to your previous branch after pushing. You
may also want to delete the branch after the commit has been pushed.
git branch -D ${source}
----------------------------------------------------------------------
EOF
else
cat << EOF
----------------------------------------------------------------------
This script will not push. Verify everything is correct, then force
push to the fork using the following commands:
gh pr edit ${pr} --add-label 'MergeQueueCI'
git remote add ${remote} git@github.com:${remote}/rippled.git
git fetch ${remote}
git push --force-with-lease ${remote} ${source}
git remote remove ${remote}
The first command adds a label to the PR to skip running CI on the new
commit. As we are using a merge queue, CI will be run when the PR is added to
the queue, which is required to pass before the changes are merged.
Remember to navigate back to your previous branch after pushing. You
may also want to delete the branch after the commit has been pushed.
git branch -D ${source}
----------------------------------------------------------------------
EOF
fi