Unverified Commit 413f0644 authored by Thomas Gerbet's avatar Thomas Gerbet Committed by GitHub
Browse files

Merge pull request #172098 from risicle/ris-cherry-pick-check

add "check cherry-picks" github action
parents f955c923 fbad66da
Loading
Loading
Loading
Loading
+24 −0
Original line number Diff line number Diff line
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 −0
Original line number Diff line number Diff line
#!/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