-
Notifications
You must be signed in to change notification settings - Fork 6
142 lines (125 loc) · 6.68 KB
/
cherry-pick-rc-to-develop.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
# GitHub Action: Cherry-pick from `release/candidate` to `TARGET_BRANCH`
#
# This action automates the process of cherry-picking merged PRs from `release/candidate` branch to `TARGET_BRANCH`.
# It is triggered whenever a pull request is merged into `release/candidate`.
#
# The action performs the following steps:
# 1. Checkout the merged PR.
# 2. If changes are made outside the specified submodule or no submodule is specified, the action proceeds.
# 3. If a submodule name is provided in the `SUBMODULE_NAME` environment variable:
# a. The action creates a temporary branch.
# b. Updates the submodule to its latest version from `develop`.
# c. Commits the submodule updates.
# 4. Squashes the commit with the commit message of the merged PR (if a submodule was updated).
# 5. Cherry-picks the squashed (or original if no squashing occurred) commit to a new branch based on `develop`.
# 6. If any conflicts arise during the cherry-pick, they are committed.
# 7. The branch with the cherry-picked changes is pushed.
# 8. A new pull request is created against `develop` with the cherry-picked changes.
#
# Note: Ensure you add a "cherry-pick" label to your project. This label is required for the creation of cherry-picked PRs.
# If needed, you can also set the `TARGET_BRANCH` environment variable to specify a different target branch for the cherry-pick.
# By default, it's set to `develop`.
name: "Cherry-pick from rc to develop"
on:
pull_request:
branches:
- release/candidate
types:
- closed
env:
TARGET_BRANCH: develop
# SUBMODULE_NAME:
jobs:
cherry-pick:
runs-on: ubuntu-latest
if: github.event.pull_request.merged == true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
submodules: recursive
- name: Append -cherry-pick to branch name
id: extract
run: |
PR_BRANCH="${{ github.event.pull_request.head.ref }}"
NEW_BRANCH_NAME="${PR_BRANCH}-cherry-pick"
echo "New branch name: $NEW_BRANCH_NAME"
echo "newBranchName=$NEW_BRANCH_NAME" >> $GITHUB_ENV
- name: Check for changes excluding submodule
id: check_changes
run: |
if [[ -n "${{ env.SUBMODULE_NAME }}" ]]; then
# If SUBMODULE_NAME is set
NUM_CHANGES=$(git diff origin/${{ env.TARGET_BRANCH }} --name-only | grep -v "^${{ env.SUBMODULE_NAME }}/" | wc -l)
else
# If SUBMODULE_NAME is not set
NUM_CHANGES=$(git diff origin/${{ env.TARGET_BRANCH }} --name-only | wc -l)
fi
if [ "$NUM_CHANGES" -gt 0 ]; then
echo "shouldCherryPick=true" >> $GITHUB_ENV
else
if [[ -n "${{ env.SUBMODULE_NAME }}" ]]; then
echo "No changes outside of ${{ env.SUBMODULE_NAME }} submodule, skipping cherry-pick"
else
echo "No changes detected, skipping cherry-pick"
fi
echo "shouldCherryPick=false" >> $GITHUB_ENV
fi
- uses: fregante/setup-git-user@v2
- name: Update submodule
if: env.SUBMODULE_NAME && env.shouldCherryPick == 'true'
run: |
set -x
# Create a temporary branch and get the last commit message
git checkout -b temp-branch-for-cherry-pick
LAST_COMMIT_MESSAGE=$(git log --format=%B -n 1 ${{ github.event.pull_request.merge_commit_sha }})
cd ${{ env.SUBMODULE_NAME }}
git checkout ${{ env.TARGET_BRANCH }}
git pull origin ${{ env.TARGET_BRANCH }}
cd ..
git add ${{ env.SUBMODULE_NAME }}
git commit -m "Update submodule ${{ env.SUBMODULE_NAME }} to latest from ${{ env.TARGET_BRANCH }}"
echo "lastCommitMessage=LAST_COMMIT_MESSAGE" >> $GITHUB_ENV
- name: Get Cherry-pick commit
id: get-cherry
if: env.shouldCherryPick == 'true'
run: |
if [[ -n "${{ env.SUBMODULE_NAME }}" ]]; then
# If SUBMODULE_NAME is set
git reset --soft HEAD~2
git commit -m "${{ env.lastCommitMessage }}"
fi
# Get the SHA of the current commit (either squashed or not based on the condition above)
CHERRY_PICK_COMMIT=$(git rev-parse HEAD)
echo "cherryPickCommit=$CHERRY_PICK_COMMIT" >> $GITHUB_ENV
- name: Cherry-pick commits
id: commit-cherry-pick
if: env.shouldCherryPick == 'true'
run: |
# Checkout the desired branch and cherry-pick the commit
git checkout ${{ env.TARGET_BRANCH }}
git checkout -b ${{ env.newBranchName }}
OUTPUT=$(git cherry-pick ${{ env.cherryPickCommit }} || true)
# Handle conflicts
CONFLICTED_FILES=$(git diff --name-only --diff-filter=U)
if [[ "$OUTPUT" == *"CONFLICT"* ]]; then
# Commit the remaining conflicts
git commit -am "Commit with unresolved merge conflicts outside of ${{ env.SUBMODULE_NAME }}"
fi
# Push branch and remove temp
git push origin ${{ env.newBranchName }} || (echo "Failed to push to origin" && exit 1)
echo "conflictedFiles=$CONFLICTED_FILES" >> $GITHUB_ENV
if [[ -n "${{ env.SUBMODULE_NAME }}" ]]; then
git branch -D temp-branch-for-cherry-pick
fi
- name: Create PR
if: env.shouldCherryPick == 'true'
env:
PR_TITLE: ${{ github.event.pull_request.title }}
PR_BRANCH: ${{ env.newBranchName }}
PR_ASSIGNEE: ${{ github.event.pull_request.user.login }}
PR_BODY: "${{ format('Cherry pick from the original PR: \n- #{0}\n\n---- \n\n ⚠️ Conflicts during cherry-pick:\n{1}\n\n{2}', github.event.pull_request.number, env.conflictedFiles, github.event.pull_request.body) }}"
run: gh pr create --title "$PR_TITLE" --body "$PR_BODY" --base ${{ env.TARGET_BRANCH }} --head "$PR_BRANCH" --label "cherry-pick" --assignee "$PR_ASSIGNEE"