-
Notifications
You must be signed in to change notification settings - Fork 27
171 lines (159 loc) · 6.72 KB
/
combine_prs.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
158
159
160
161
162
163
164
165
166
167
168
169
170
171
# Workflow for combining pull requests by renovate
name: combine-prs
# Controls when the action will run - in this case triggered manually
on:
workflow_dispatch:
inputs:
branchPrefix:
description: 'Branch prefix to find combinable PRs based on'
required: true
default: 'renovate'
mustBeGreen:
description: 'Only combine PRs that are green (status is success)'
required: true
default: true
combineBranchName:
description: 'Name of the branch to combine PRs into'
required: true
default: 'renovate-dependencies-grouped'
ignoreLabel:
description: 'Exclude PRs with this label'
required: true
default: 'nocombine'
prTitle:
description: 'Title of the pull request submitted'
default: 'chore: combine renovate upgrades'
required: true
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
# This workflow contains a single job called "combine-prs"
combine-prs:
# The type of runner that the job will run on
runs-on: ubuntu-latest
environment: 'Combine PR'
# Steps represent a sequence of tasks that will be executed as part of the job
steps:
- uses: tibdex/github-app-token@v1
id: generate-token
with:
app_id: ${{ secrets.APP_ID }}
private_key: ${{ secrets.APP_PRIVATE_KEY }}
- uses: actions/github-script@v6
id: fetch-branch-names
name: Fetch branch names
with:
github-token: ${{ steps.generate-token.outputs.token }}
script: |
const CI_TEST_THAT_NEEDS_TO_BE_GREEN = [
'codecov/patch',
'SonarCloud',
'SonarCloud Code Analysis',
'test-support-scripts',
'test-code-generation',
'build-and-test (windows-latest)',
'build-and-test (macos-latest)',
'Run Sorald Buildbreaker',
'build-and-test (ubuntu-latest)'
]
const pulls = await github.paginate('GET /repos/:owner/:repo/pulls', {
owner: context.repo.owner,
repo: context.repo.repo
});
branches = [];
prs = [];
base_branch = null;
for (const pull of pulls) {
const branch = pull['head']['ref'];
console.log('Pull for branch: ' + branch);
if (branch.startsWith('${{ github.event.inputs.branchPrefix }}')) {
console.log('Branch matched: ' + branch);
statusOK = true;
if(${{ github.event.inputs.mustBeGreen }}) {
console.log('Checking green status: ' + branch);
const check_runs = await github.paginate('GET /repos/{owner}/{repo}/commits/{ref}/check-runs', {
owner: context.repo.owner,
repo: context.repo.repo,
ref: branch
});
for (const check of check_runs) {
if (CI_TEST_THAT_NEEDS_TO_BE_GREEN.includes(check.name)) {
if (check.conclusion !== 'success') {
console.log(
'Discarding ' + branch + ' because ' + check.name + '\'s conclusion is not success. It is: ' + check.conclusion
);
statusOK = false;
}
}
}
}
console.log('Checking labels: ' + branch);
const labels = pull['labels'];
for(const label of labels) {
const labelName = label['name'];
console.log('Checking label: ' + labelName);
if(labelName == '${{ github.event.inputs.ignoreLabel }}') {
console.log('Discarding ' + branch + ' with label ' + labelName);
statusOK = false;
}
}
if (statusOK) {
console.log('Adding branch to array: ' + branch);
branches.push(branch);
prs.push('#' + pull['number'] + ' ' + pull['title']);
base_branch = pull['base']['ref'];
}
}
}
if (branches.length == 0) {
core.setFailed('No PRs/branches matched criteria');
return;
}
core.setOutput('base-branch', base_branch);
core.setOutput('prs-string', prs.join('\n'));
combined = branches.join(' ')
console.log('Combined: ' + combined);
return combined
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@v3.5.2
with:
fetch-depth: 0
token: ${{ steps.generate-token.outputs.token }}
# Creates a branch with other PR branches merged together
- name: Created combined branch
id: combined-branch
env:
BASE_BRANCH: ${{ steps.fetch-branch-names.outputs.base-branch }}
BRANCHES_TO_COMBINE: ${{ steps.fetch-branch-names.outputs.result }}
COMBINE_BRANCH_NAME: ${{ github.event.inputs.combineBranchName }}
run: |
echo "$BRANCHES_TO_COMBINE"
sourcebranches="${BRANCHES_TO_COMBINE%\"}"
sourcebranches="${sourcebranches#\"}"
basebranch="${BASE_BRANCH%\"}"
basebranch="${basebranch#\"}"
git config pull.rebase false
git config user.name github-actions
git config user.email github-actions@github.com
echo "$COMBINE_BRANCH_NAME"
echo "$basebranch"
git checkout -b $COMBINE_BRANCH_NAME
git pull origin $sourcebranches --no-edit
git push origin $COMBINE_BRANCH_NAME
# Creates a PR with the new combined branch
- uses: actions/github-script@v6
name: Create Combined Pull Request
env:
PRS_STRING: ${{ steps.fetch-branch-names.outputs.prs-string }}
with:
github-token: ${{ steps.generate-token.outputs.token }}
script: |
const prString = process.env.PRS_STRING;
const body = 'This PR was created by the Combine PRs action by combining the following PRs:\n' + prString;
await github.rest.pulls.create({
owner: context.repo.owner,
repo: context.repo.repo,
title: '${{ github.event.inputs.prTitle }}',
head: '${{ github.event.inputs.combineBranchName }}',
base: '${{ steps.fetch-branch-names.outputs.base-branch }}',
body: body
});