Merge pull request #639 from bzsuni/case/update #331
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: Auto CherryPick PR | |
permissions: write-all | |
env: | |
PR_LABEL_PREFIX_CHERRYPICK: "cherrypick-" | |
CHERRYPICK_LABEL: "robot-cherrypick" | |
DEFAULT_REVIEWER: "weizhoublue" | |
on: | |
push: | |
branches: | |
- 'release-*' | |
- 'main' | |
jobs: | |
cherry_pick: | |
runs-on: ubuntu-latest | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v3 | |
with: | |
fetch-depth: 0 | |
# ${{ secrets.GITHUB_TOKEN }} is forbidden to create or approve pull requests | |
- name: cherry pick | |
env: | |
GITHUB_TOKEN: ${{ secrets.WELAN_PAT}} | |
JSON: ${{ toJSON(github) }} | |
run: | | |
set -x | |
PR_NUMBER=$(grep -Eio "Merge pull request #[0-9]+ " <<< "${JSON}" | grep -Eo "[0-9]+" | uniq || true) | |
if [ -z "$PR_NUMBER" ]; then | |
PR_NUMBER=$(grep -oP '(?<=\(#)\d+(?=\))' <<< "${JSON}" | head -n 1 || true) | |
fi | |
if [ -z "$PR_NUMBER" ]; then | |
echo "No PR number, ignoring" | |
exit 0 | |
fi | |
PR_URL="https://github.com/${{ github.repository }}/pull/${PR_NUMBER}" | |
ACTION_URL="${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" | |
grep '"username":' <<< "${JSON}" | |
PR_AUTHOR=` grep '"username":' <<< "${JSON}" | awk -F'"' '{print $4}' | sort | uniq | grep -v "web-flow" | head -1 | tr -d '\n' ` | |
[ -n "${PR_AUTHOR}" ] || { echo "no PR_AUTHOR, ignore" ; } | |
gh pr view ${PR_NUMBER} | |
PR_LABEL=` gh pr view ${PR_NUMBER} | grep -i "^labels:" | tr ',' ' ' | tr -s ' ' | sed 's/labels://g' ` | |
[ -n "${PR_LABEL}" ] || { echo "no PR_LABEL, ignore" ; } | |
PR_TITLE=`gh pr view ${PR_NUMBER} | sed -n '1 p' ` | |
[ -n "${PR_TITLE}" ] || { echo "error, no PR_TITLE " ; exit 1 ; } | |
# | |
grep -Ei "https://github.com/.*/commit" <<< "${JSON}" | |
PR_COMMITS=` grep -Ei "https://github.com/.*/commit" <<< "${JSON}" | awk -F'"' '{print $4}' | uniq -c | awk '{ if ($1 == 1 ) print $2}' | awk -F'/' '{print $NF}' | tr '\n' ' ' ` | |
[ -n "${PR_COMMITS}" ] || { echo "no PR_COMMITS, ignore" ; } | |
# | |
echo "number: ${PR_NUMBER}" | |
echo "action url: ${ACTION_URL}" | |
echo "PR_COMMITS: ${PR_COMMITS}" | |
echo "author: ${PR_AUTHOR}" | |
echo "url: ${PR_URL}" | |
echo "PR_LABEL: ${PR_LABEL}" | |
echo "PR_TITLE: ${PR_TITLE}" | |
# | |
# | |
echo "=============================== get dest branch from labels ======== " | |
WANT_MERGE_BRANCH_LIST="" | |
for LABEL in ${PR_LABEL} ; do | |
echo "checking label $LABEL " | |
PREFIX="${{ env.PR_LABEL_PREFIX_CHERRYPICK }}" | |
grep -E "^${PREFIX}" <<< "${LABEL}" &>/dev/null || continue | |
BRANCH_NAME=` sed 's?'"${PREFIX}"'??' <<< "$LABEL" ` | |
WANT_MERGE_BRANCH_LIST+=" $BRANCH_NAME " | |
done | |
[ -z "$WANT_MERGE_BRANCH_LIST" ] && echo "no branch to cherry pick" && exit 0 | |
echo "cherry pick to $WANT_MERGE_BRANCH_LIST " | |
# | |
# | |
echo "============ begin to cherry pick ============ " | |
FINAL_FAILURE=false | |
git branch | |
git config user.email "[email protected]" | |
git config user.name "robot" | |
gh label create ${{ env.CHERRYPICK_LABEL }} || true | |
for BRANCH in $WANT_MERGE_BRANCH_LIST ; do | |
echo "************** cherry for branch ${BRANCH}" | |
if ! git ls-remote --exit-code --heads origin ${BRANCH} ; then | |
# todo: create issue | |
echo "error, branch $BRANCH does not exist" | |
gh issue create \ | |
--body "reason: the branch $BRANCH does not exist. PR <${PR_URL}> , action <${ACTION_URL}> " \ | |
--title "failed to auto cherry pick PR ${PR_NUMBER} to branch ${BRANCH}" \ | |
--label "${{ env.CHERRYPICK_LABEL }}" \ | |
--assignee "${PR_AUTHOR},${{ env.DEFAULT_REVIEWER }}" | |
if (($?!=0)) ; then | |
echo "!!!! error, failed to create issue" | |
FINAL_FAILURE=true | |
fi | |
continue | |
fi | |
git fetch origin ${BRANCH}:${BRANCH} || true | |
if ! git checkout ${BRANCH} ; then | |
echo "error, failed to checkout to branch $BRANCH" | |
gh issue create \ | |
--body "reason: failed to get the branch $BRANCH. PR <${PR_URL}> , action <${ACTION_URL}> " \ | |
--title "failed to auto cherry pick PR ${PR_NUMBER} to branch ${BRANCH}" \ | |
--label "${{ env.CHERRYPICK_LABEL }}" \ | |
--assignee "${PR_AUTHOR},${{ env.DEFAULT_REVIEWER }}" | |
if (($?!=0)) ; then | |
echo "!!!! error, failed to create issue" | |
FINAL_FAILURE=true | |
fi | |
continue | |
fi | |
PR_BRANCH=robot/cherrypick/pr${PR_NUMBER}/${BRANCH} | |
git checkout -b ${PR_BRANCH} | |
git branch --show-current | |
FAIL=false | |
UPDATE=false | |
ERROR_MESSAGE="" | |
for COMMIT in $PR_COMMITS; do | |
if ! ERROR_MESSAGE=`git cherry-pick $COMMIT 2>&1` ; then | |
echo ">>>>>>>>>>>> fail when cherry pick $COMMIT to branch $BRANCH " | |
echo "$ERROR_MESSAGE" | |
echo "---- failure detail" | |
git status | |
git diff | |
echo "<<<<<<<<<<<<<" | |
if git diff --exit-code --quiet ; then | |
echo "no changes happen, ignore cherry pick $COMMIT " | |
git cherry-pick --abort || true | |
git reset --hard HEAD || true | |
continue | |
else | |
FAIL=true | |
echo "error, failed to cherry pick $COMMIT " | |
git cherry-pick --abort || true | |
git reset --hard HEAD || true | |
break | |
fi | |
else | |
UPDATE=true | |
echo "succeed to cherry pick $COMMIT to branch $BRANCH " | |
fi | |
done | |
if [ "$FAIL" == "true" ] ; then | |
echo "failed to cherry pick to branch $BRANCH " | |
FINAL_FAILURE=true | |
echo -e "commits $PR_COMMITS conflict when merging to branch $BRANCH, please manually cherry pick it by yourself. \n PR <${PR_URL}> , action <${ACTION_URL}> \n\n \`\`\`\n${ERROR_MESSAGE}\n\`\`\` " | \ | |
gh issue create \ | |
--title "failed to auto cherry pick PR ${PR_NUMBER} to branch ${BRANCH}" \ | |
--label "${{ env.CHERRYPICK_LABEL }}" \ | |
--assignee "${PR_AUTHOR},${{ env.DEFAULT_REVIEWER }}" \ | |
--body-file - | |
fi | |
if [ "$UPDATE" == "true" ] ; then | |
echo "succeeded to cherry pick to branch $BRANCH " | |
# create a pr | |
git push origin ${PR_BRANCH}:${PR_BRANCH} -f | |
gh pr create --title "${PR_TITLE}" \ | |
--assignee "${PR_AUTHOR},${{ env.DEFAULT_REVIEWER }}" \ | |
--label ${{ env.CHERRYPICK_LABEL }} \ | |
--body "robot cherry pick pr <${PR_URL}> to branch ${BRANCH}, action <${ACTION_URL}> , commits $PR_COMMITS " \ | |
--base ${BRANCH} | |
else | |
echo "no changes happened for commits $PR_COMMITS, ignore create pr" | |
fi | |
done | |
echo "=========== check result ============" | |
if [ "$FINAL_FAILURE" == "true" ] ; then | |
# if failed to create issue or pr, fails | |
echo "error, failure happened" | |
else | |
echo "all done" | |
fi |