From 2396de58cd13bec5d53378fb8147325faa597c1e Mon Sep 17 00:00:00 2001 From: shilongliu Date: Fri, 30 Sep 2022 14:25:49 +0800 Subject: [PATCH] Add README, fix workflow --- .github/workflows/README.md | 38 +++++ .github/workflows/pr_cherrypick_poststep.yml | 27 ++-- .github/workflows/pr_cherrypick_prestep.yml | 157 +++++++++++-------- 3 files changed, 139 insertions(+), 83 deletions(-) create mode 100644 .github/workflows/README.md diff --git a/.github/workflows/README.md b/.github/workflows/README.md new file mode 100644 index 000000000000..d013edd4bdea --- /dev/null +++ b/.github/workflows/README.md @@ -0,0 +1,38 @@ +# Github actions README +This is an introduction about auto-cherry-pick workflow. +take 202205 branch for example: +1. pr_cherrypick_prestep: +```mermaid +graph +Start(Origin PR) --> A{merged?} +A -- NO --> STOP +A -- YES --> A1{Approved
for 202205
Branch?} +A1 -- NO --> STOP +A1 -- YES --> A2(pr_cherrypick_prestep) +B(pr_cherrypick_prestep) +B --> B1{cherry pick
conflict?} +B1 -- YES --> B2(Add tag:
Cherry Pick Confclit_202205) --> B3(Add comment:
refer author code conflict) --> STOP1(STOP) +B1 -- NO --> B4(Create New PR) -- success --> B5(New PR add tag:
automerge) --> B6(New PR add comment:
Origin PR link) --> B7(Origin PR add tag:
Created PR to 202205 Branch) --> B8(Origin PR add comment:
New PR link) +B4 -- fail --> STOP1 +``` + +2. automerge: +```mermaid +graph +Start(PR azp finished successfully) --> A{author:
mssonicbld?} +A -- NO --> STOP +A -- YES --> B{tag:
automerge?} -- YES --> C(Merge PR) +B -- NO --> STOP +``` + +3. pr_cherrypick_poststep: +```mermaid +graph +A(PR is Merged) --> B{tag:
automerge?} +B -- YES --> B1{author:
mssonicbld?} +B1 -- YES --> B2{"title starts:
[action] [PR:123]"} +B2 -- YES --> C(Origin PR remove tag:
Created PR to 202205 Branch) --> D(Origin PR add tag:
Included in 202205 Branch) +B -- NO --> STOP +B1 -- NO --> STOP +B2 -- NO --> STOP +``` diff --git a/.github/workflows/pr_cherrypick_poststep.yml b/.github/workflows/pr_cherrypick_poststep.yml index 29f7cb102e63..0ab5bab235ae 100644 --- a/.github/workflows/pr_cherrypick_poststep.yml +++ b/.github/workflows/pr_cherrypick_poststep.yml @@ -4,16 +4,11 @@ on: types: - closed branches: - - 202205 - - 202111 - - 202106 - - 202012 - - 201911 - - 201811 + - '20*' jobs: post_cherry_pick: - if: github.event.pull_request.merged == true && contains(github.event.pull_request.labels.*.name, 'automerge') + if: github.event.pull_request.merged == true && contains(github.event.pull_request.labels.*.name, 'automerge') && github.event.pull_request.head.user.login == "mssonicbld" && startsWith(github.event.pull_request.title, "[action]") runs-on: ubuntu-latest steps: - name: Debug @@ -30,21 +25,25 @@ jobs: TOKEN: ${{ secrets.TOKEN }} run: | set -e - pr_url=$(echo $GITHUB_CONTEXT | jq ".event.pull_request._links.html.href" | sed 's/"//g') - base_ref=$(echo $GITHUB_CONTEXT | jq ".base_ref" | sed 's/"//g') + pr_url=$(echo $GITHUB_CONTEXT | jq -r ".event.pull_request._links.html.href") + pr_id=$(echo $GITHUB_CONTEXT | jq -r ".event.number") + base_ref=$(echo $GITHUB_CONTEXT | jq -r ".base_ref") echo ${TOKEN} | gh auth login --with-token - comment=$(gh pr view $pr_url --json comments | jq -r '.comments | [.[] | select(.author.login=="mssonicbld")] | first | .body') - origin_pr_url=$(echo $comment | sed 's/Original PR: //') + title=$(echo $GITHUB_CONTEXT | jq -r ".event.pull_request.title") + origin_pr_id=$(echo $title | grep -Eo "\[action\] \[PR:[0-9]*\]" | grep -Eo "[0-9]*") + origin_pr_url=$(echo $pr_url | sed "s/$pr_id/$origin_pr_id/") echo ============================= echo pr_url: $pr_url + echo pr_id: $pr_id echo base_ref: $base_ref - echo comment: $comment + echo title: $title + echo origin_pr_id: $origin_pr_id echo origin_pr_url: $origin_pr_url echo ============================= # Add label if [[ "$origin_pr_url" == "" ]];then - echo No comment from mssonicbld - exit 0 + echo original PR didn't found. + exit 1 fi gh pr edit $origin_pr_url --add-label "Included in ${base_ref} Branch" gh pr edit $origin_pr_url --remove-label "Created PR to ${base_ref} Branch" diff --git a/.github/workflows/pr_cherrypick_prestep.yml b/.github/workflows/pr_cherrypick_prestep.yml index a2d54881b2ff..418f35935dce 100644 --- a/.github/workflows/pr_cherrypick_prestep.yml +++ b/.github/workflows/pr_cherrypick_prestep.yml @@ -9,11 +9,8 @@ on: jobs: pre_cherry_pick: - if: github.event.pull_request.merged == true && (github.event.action == "closed" || contains(github.event.label.name, "Approved for ${{ matrix.branch }} Branch") ) + if: github.event.pull_request.merged == true && contains(join(github.event.pull_request.labels.*.name, ','), 'Approved for 20') runs-on: ubuntu-latest - strategy: - matrix: - branch: [202205,202111,202106,202012,201911,201811] steps: - name: Checkout uses: actions/checkout@v3 @@ -35,85 +32,107 @@ jobs: pr_id=$(echo $GITHUB_CONTEXT | jq -r ".event.number") pr_url=$(echo $GITHUB_CONTEXT | jq -r ".event.pull_request._links.html.href") repository=$(echo $GITHUB_CONTEXT | jq -r ".repository") - labels_count=$(echo $GITHUB_CONTEXT | jq ".event.pull_request.labels | length") - labels_json=$(echo $GITHUB_CONTEXT | jq ".event.pull_request.labels") + labels=$(echo $GITHUB_CONTEXT | jq -r ".event.pull_request.labels[].name") + author=$(echo $GITHUB_CONTEXT | jq -r ".event.pull_request.base.user.login") + branches=$(git branch -a --list 'origin/20????' | awk -F/ '{print$3}' | grep -E "202[0-9]{3}") + if [[ $(echo $GITHUB_CONTEXT | jq -r ".event.action") == "labeled" ]];then + labels=$(echo $GITHUB_CONTEXT | jq -r ".event.label.name") + fi + title=$(echo $GITHUB_CONTEXT | jq -r ".event.pull_request.title") echo ============================= echo SHA: $sha echo PRID: $pr_id echo pr_url: $pr_url echo repository: $repository - echo labels_count: $labels_count - echo labels_json: $labels_json + echo branches: $branches + echo labels: + echo "$labels" echo ${TOKEN} | gh auth login --with-token + echo author: $author + echo title: $title echo ============================= - if [[ "$(echo $GITHUB_CONTEXT | jq -r '.event.action')" == "labeled" ]] && \ - [[ "$(echo $GITHUB_CONTEXT | jq -r '.event.label.name')" != "Approved for ${{ matrix.branch }} Branch" ]];then - echo "Newly added label didn't match." - exit 0 - fi - create_pr='' - for (( i=0; i<$labels_count; i++ )) - do - label=$(echo $labels_json | jq -r ".[$i].name") - echo label ${i}: $label - if [[ "$label" == "Approved for ${{ matrix.branch }} Branch" ]];then - create_pr=1 - fi - if [[ "$label" == "Created PR to ${{ matrix.branch }} Branch" ]];then - echo "already has tag: Created PR to ${{ matrix.branch }} Branch, exit" - exit 0 - fi - if [[ "$label" == "Included in ${{ matrix.branch }} Branch" ]];then - echo "already has tag: Included in ${{ matrix.branch }} Branch, exit" - exit 0 - fi - done - if [[ "$create_pr" != "1" ]];then - echo "Didn't find 'Approved for ${{ matrix.branch }} Branch' tag." - exit 0 - fi - - # Begin to cherry-pick PR - git checkout -b ${{ matrix.branch }} --track origin/${{ matrix.branch }} - git checkout . - git clean -xdff git config user.name mssonicbld - git config user.email sonicbuildadmin@microsoft.com - + git config user.email sonicbld@microsoft.com git config credential.https://github.aaakk.us.kg.username mssonicbld git remote add mssonicbld https://mssonicbld:${TOKEN}@github.com/mssonicbld/sonic-buildimage git fetch mssonicbld git remote -vv - if ! git cherry-pick $sha;then - echo 'cherry-pick failed.' - # Add label - gh pr edit $pr_url --add-label "Cherry Pick Conflict_${{ matrix.branch }}" - echo 'Add label "Cherry Pick Conflict_${{ matrix.branch }}" success' - author=$(gh pr view $pr_url --json author | jq '.author.login' | sed 's/"//g') - gh pr comment $pr_url --body "@${author} PR conflicts with ${{ matrix.branch }} branch" - echo 'Add commnet "@${author} PR conflicts with ${{ matrix.branch }} branch"' - else - # Create PR to release branch - git push mssonicbld HEAD:${{ matrix.branch }}-${pr_id} -f - result=$(gh pr create -R ${repository} -H mssonicbld:${{ matrix.branch }}-${pr_id} -B ${{ matrix.branch }} -t "[action] Auto cherry-pick PR:#${pr_id} into ${{ matrix.branch }} branch" -b '') - if [[ "$(echo $result | grep github.com)" == "" ]];then echo $result; exit 1;fi + cherry_pick(){ + set -e + local create_pr='' + local branch=$1 + if [ -z $branch ];then return 0;fi + while read label + do + echo label: $label + if [[ "$label" == "Approved for $branch Branch" ]];then + create_pr=1 + fi + if [[ "$label" == "Created PR to $branch Branch" ]];then + echo "already has tag: Created PR to $branch Branch, return" + return 0 + fi + if [[ "$label" == "Included in $branch Branch" ]];then + echo "already has tag: Included in $branch Branch, return" + return 0 + fi + if [[ "$label" == "Cherry Pick Conflict_$branch" ]];then + echo "already has tag: Cherry Pick Conflict_$branch, return" + return 0 + fi - new_pr_rul=$(echo $result | grep github.com) - echo new_pr_rul: $new_pr_rul + if [[ "$create_pr" != "1" ]];then + echo "Didn't find 'Approved for $branch Branch' tag." + return 0 + fi + # Begin to cherry-pick PR + git cherry-pick --abort || true + git clean -xdff || true + git reset HEAD --hard || true + git checkout -b $branch --track origin/$branch + git status | grep "working tree clean" - # Add label to old PR - gh pr edit $pr_url --add-label "Created PR to ${{ matrix.branch }} Branch" - echo Add label Created PR to ${{ matrix.branch }} Branch - # Add comment to old PR - gh pr comment $pr_url --body "Cherry-pick PR to ${{ matrix.branch }}: ${new_pr_rul}" - echo Add comment to old PR + if ! git cherry-pick $sha;then + echo 'cherry-pick failed.' + git cherry-pick --abort + git status | grep "working tree clean" + # Add label + gh pr edit $pr_url --add-label "Cherry Pick Conflict_$branch" + echo 'Add label "Cherry Pick Conflict_$branch" success' + gh pr comment $pr_url --body "@${author} PR conflicts with $branch branch" + echo 'Add commnet "@${author} PR conflicts with $branch branch"' + else + # Create PR to release branch + git push mssonicbld HEAD:$branch-${pr_id} -f + result=$(gh pr create -R ${repository} -H mssonicbld:$branch-${pr_id} -B $branch -t "[action] [PR:$pr_id] $title" -b '' 2>&1) + echo $result | grep "already exists" && { echo $result; return 0; } + echo $result | grep github.com || { echo $result; return 1; } + new_pr_rul=$(echo $result | grep github.com) + echo new_pr_rul: $new_pr_rul + + # Add label to old PR + gh pr edit $pr_url --add-label "Created PR to $branch Branch" + echo Add label Created PR to $branch Branch + # Add comment to old PR + gh pr comment $pr_url --body "Cherry-pick PR to $branch: ${new_pr_rul}" + echo Add comment to old PR + + # Add label to new PR + gh pr edit $new_pr_rul --add-label "automerge" + echo Add label automerge to new PR + # Add comment to new PR + gh pr comment $new_pr_rul --body "Original PR: ${pr_url}" + echo Add comment to new PR + fi + done <<< "$labels" + } + + for branch in $branches + do + echo ----------------------------- + echo Begin to parse Branch: $branch + cherry_pick $branch + done - # Add label to new PR - gh pr edit $new_pr_rul --add-label "automerge" - echo Add label Created PR to ${{ matrix.branch }} Branch - # Add comment to new PR - gh pr comment $new_pr_rul --body "Original PR: ${pr_url}" - echo Add comment to new PR - fi