Skip to content

Commit

Permalink
add "Check cherry-picks" github action
Browse files Browse the repository at this point in the history
the intention being to catch commits which declare themselves as
cherry-picks, but either:

 - don't refer to a commit in the master or staging branches
 - are significantly altered from their original commit

determining the latter is not an exact science, but the heuristic of
looking for differences in only the added or removed lines seems to
work quite well. still, this should be considered an assistant
for reviewers rather than a hard failure. unfortunately github
workflows don't have a way of raising a gentle warning instead of a
failure.

the formatting of the output also leaves something to be desired due
to the limitations of github actions' "group" commands.
  • Loading branch information
risicle committed Apr 1, 2024
1 parent 354e136 commit fbad66d
Show file tree
Hide file tree
Showing 2 changed files with 116 additions and 0 deletions.
24 changes: 24 additions & 0 deletions .github/workflows/check-cherry-picks.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: "Check cherry-picks"
on:
pull_request_target:
branches:
- 'release-*'
- 'staging-*'

permissions: {}

jobs:
check:
runs-on: ubuntu-latest
if: github.repository_owner == 'NixOS'
steps:
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
with:
fetch-depth: 0
filter: blob:none
- name: Check cherry-picks
env:
BASE_SHA: ${{ github.event.pull_request.base.sha }}
HEAD_SHA: ${{ github.event.pull_request.head.sha }}
run: |
./maintainers/scripts/check-cherry-picks.sh "$BASE_SHA" "$HEAD_SHA"
92 changes: 92 additions & 0 deletions maintainers/scripts/check-cherry-picks.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
#!/usr/bin/env bash
# Find alleged cherry-picks

set -e

if [ $# != "2" ] ; then
echo "usage: check-cherry-picks.sh base_rev head_rev"
exit 2
fi

PICKABLE_BRANCHES=${PICKABLE_BRANCHES:-master staging release-??.?? staging-??.??}
problem=0

while read new_commit_sha ; do
if [ "$GITHUB_ACTIONS" = 'true' ] ; then
echo "::group::Commit $new_commit_sha"
else
echo "================================================="
fi
git rev-list --max-count=1 --format=medium "$new_commit_sha"
echo "-------------------------------------------------"

original_commit_sha=$(
git rev-list --max-count=1 --format=format:%B "$new_commit_sha" \
| grep -Ei -m1 "cherry.*[0-9a-f]{40}" \
| grep -Eoi -m1 '[0-9a-f]{40}'
)
if [ "$?" != "0" ] ; then
echo " ? Couldn't locate original commit hash in message"
[ "$GITHUB_ACTIONS" = 'true' ] && echo ::endgroup::
continue
fi

set -f # prevent pathname expansion of patterns
for branch_pattern in $PICKABLE_BRANCHES ; do
set +f # re-enable pathname expansion

while read -r picked_branch ; do
if git merge-base --is-ancestor "$original_commit_sha" "$picked_branch" ; then
echo "$original_commit_sha present in branch $picked_branch"

range_diff_common='git range-diff
--no-notes
--creation-factor=100
'"$original_commit_sha~..$original_commit_sha"'
'"$new_commit_sha~..$new_commit_sha"'
'

if $range_diff_common --no-color | grep -E '^ {4}[+-]{2}' > /dev/null ; then
if [ "$GITHUB_ACTIONS" = 'true' ] ; then
echo ::endgroup::
echo -n "::warning ::"
else
echo -n ""
fi
echo "Difference between $new_commit_sha and original $original_commit_sha may warrant inspection:"

$range_diff_common --color

problem=1
else
echo "$original_commit_sha highly similar to $new_commit_sha"
$range_diff_common --color
[ "$GITHUB_ACTIONS" = 'true' ] && echo ::endgroup::
fi

# move on to next commit
continue 3
fi
done <<< "$(
git for-each-ref \
--format="%(refname)" \
"refs/remotes/origin/$branch_pattern"
)"
done

if [ "$GITHUB_ACTIONS" = 'true' ] ; then
echo ::endgroup::
echo -n "::error ::"
else
echo -n ""
fi
echo "$original_commit_sha not found in any pickable branch"

problem=1
done <<< "$(
git rev-list \
-E -i --grep="cherry.*[0-9a-f]{40}" --reverse \
"$1..$2"
)"

exit $problem

0 comments on commit fbad66d

Please sign in to comment.