-
Notifications
You must be signed in to change notification settings - Fork 0
157 lines (140 loc) · 6.53 KB
/
backport.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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
# Cherry-picks commits from current branch to a specified one in a command "@metabase-bot backport release-x.40.x"
name: Backport
on:
issue_comment:
types: [created]
jobs:
create_pull_request:
name: Creates a pull request
if: contains(github.event.comment.body, '@metabase-bot backport')
runs-on: ubuntu-22.04
steps:
- uses: tibdex/[email protected]
id: generate-token
with:
app_id: ${{ secrets.METABASE_BOT_APP_ID }}
private_key: ${{ secrets.METABASE_BOT_APP_PRIVATE_KEY }}
- id: is_organization_member
uses: JamesSingleton/[email protected]
with:
organization: metabase
username: ${{ github.event.issue.user.login }}
token: ${{ steps.generate-token.outputs.token }}
- run: |
result=${{ steps.is_organization_member.outputs.result }}
if [ $result == false ]; then
echo User ${{ github.event.comment.user.login }} is not a member of Metabase organization
exit 1
fi
- uses: actions/github-script@v6
id: branch_info
with:
script: |
// Example: @metabase-bot backport release-x.40.x
const [_botName, _command, targetBranch] = context.payload.comment.body.split(" ");
console.log(`Target branch is ${targetBranch}`);
const { data: originalPullRequest } = await github.rest.pulls.get({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: context.payload.issue.number,
});
const { data: commits } = await github.rest.pulls.listCommits({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: context.payload.issue.number,
});
const targetRef = await github.rest.git.getRef({
owner: context.repo.owner,
repo: context.repo.repo,
ref: `heads/${targetBranch}`,
});
const backportBranch = `backport-${originalPullRequest.head.ref}`
try {
await github.rest.git.getRef({
owner: context.repo.owner,
repo: context.repo.repo,
ref: `heads/${backportBranch}`,
});
} catch(e) {
if (e.status === 404) {
await github.rest.git.createRef({
owner: context.repo.owner,
repo: context.repo.repo,
ref: `refs/heads/${backportBranch}`,
sha: targetRef.data.object.sha,
});
}
}
return {
backportBranch,
targetBranch,
originalPullRequest,
startSha: commits[0].sha,
endSha: commits[commits.length - 1].sha
}
- uses: actions/checkout@v3
name: Cherry-pick commits and create PR
with:
fetch-depth: 0
- id: create_backport_pull_request
name: Create backport pull request
run: |
git config --global user.email "[email protected]"
git config --global user.name "Metabase bot"
git fetch --all
git checkout "${BACKPORT_BRANCH}"
git reset --hard origin/${TARGET_BRANCH}
if [[ -z $(git ls-remote --heads origin ${ORIGINAL_HEAD_REF}) ]]; then
echo "PR has been merged, searching for a squashed commit in the base branch"
echo "searching for a commit in a ${ORIGINAL_BASE_REF} that contains pull request number ${ORIGINAL_PULL_REQUEST_NUMBER}"
SQUASHED_COMMIT=$(env -i git log ${ORIGINAL_BASE_REF} --grep="(#${ORIGINAL_PULL_REQUEST_NUMBER})" --format="%H")
echo "found commit ${SQUASHED_COMMIT}"
git cherry-pick ${SQUASHED_COMMIT}
else
echo "PR has not been merged, copying all commits"
git cherry-pick ${ORIGINAL_BASE_SHA}..${ORIGINAL_HEAD_SHA}
fi
git push origin "${BACKPORT_BRANCH}" --force-with-lease
if [[ $(hub pr list -b "${TARGET_BRANCH}" -h "${BACKPORT_BRANCH}" -s "open") ]]; then
echo "PR already exists"
else
BACKPORT_PR_URL=$(hub pull-request -b "${TARGET_BRANCH}" -h "${BACKPORT_BRANCH}" -l "was-backported" -a "${GITHUB_ACTOR}" -F- <<<"🤖 backported \"${ORIGINAL_TITLE}\"
#${ORIGINAL_PULL_REQUEST_NUMBER}")
BACKPORT_PR_NUMBER=${BACKPORT_PR_URL##*/}
echo "backport_pr_number=$BACKPORT_PR_NUMBER" >> $GITHUB_OUTPUT
echo "New PR has been created"
fi
env:
ORIGINAL_TITLE: ${{ fromJson(steps.branch_info.outputs.result).originalPullRequest.title }}
ORIGINAL_BASE_REF: ${{ fromJson(steps.branch_info.outputs.result).originalPullRequest.base.ref }}
ORIGINAL_BASE_SHA: ${{ fromJson(steps.branch_info.outputs.result).originalPullRequest.base.sha }}
ORIGINAL_HEAD_REF: ${{ fromJson(steps.branch_info.outputs.result).originalPullRequest.head.ref }}
ORIGINAL_HEAD_SHA: ${{ fromJson(steps.branch_info.outputs.result).originalPullRequest.head.sha }}
ORIGINAL_PULL_REQUEST_NUMBER: ${{ fromJson(steps.branch_info.outputs.result).originalPullRequest.number }}
TARGET_BRANCH: ${{ fromJson(steps.branch_info.outputs.result).targetBranch }}
BACKPORT_BRANCH: ${{ fromJson(steps.branch_info.outputs.result).backportBranch }}
START_SHA: ${{ fromJson(steps.branch_info.outputs.result).startSha }}
END_SHA: ${{ fromJson(steps.branch_info.outputs.result).endSha }}
GITHUB_TOKEN: ${{ steps.generate-token.outputs.token }}
- name: Auto approve backport PR
uses: juliangruber/approve-pull-request-action@v1
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
number: ${{ steps.create_backport_pull_request.outputs.backport_pr_number }}
- name: Enable Pull Request Automerge
uses: peter-evans/enable-pull-request-automerge@v2
with:
token: ${{ steps.generate-token.outputs.token }}
pull-request-number: ${{ steps.create_backport_pull_request.outputs.backport_pr_number }}
merge-method: squash
notify_when_failed:
runs-on: ubuntu-22.04
name: Notify about failure
needs: create_pull_request
if: ${{ failure() }}
steps:
- uses: actions/checkout@v3
- uses: ./.github/actions/notify-pull-request
with:
include-log: true
message: something went wrong while creating a backport