Skip to content

Commit e9a7f08

Browse files
devlooped-botkzu
authored andcommitted
⬆️ Bump files with dotnet-file sync
# devlooped/oss - Add attribution to upstream and note on regex devlooped/oss@c161088
1 parent f347d1a commit e9a7f08

File tree

1 file changed

+157
-0
lines changed

1 file changed

+157
-0
lines changed

.github/workflows/combine-prs.yml

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
# Source: https://github.com/hrvey/combine-prs-workflow
2+
# Tweaks: regex support for branch
3+
4+
name: '⛙ combine-prs'
5+
6+
on:
7+
workflow_dispatch:
8+
inputs:
9+
branchExpression:
10+
description: 'Regular expression to match against PR branches to find combinable PRs'
11+
required: true
12+
default: 'dependabot'
13+
mustBeGreen:
14+
description: 'Only combine PRs that are green (status is success)'
15+
required: true
16+
default: true
17+
combineTitle:
18+
description: 'Title of the combined PR'
19+
required: true
20+
default: '⬆️ Bump dependencies'
21+
combineBranchName:
22+
description: 'Name of the branch to combine PRs into'
23+
required: true
24+
default: 'combine-prs'
25+
ignoreLabel:
26+
description: 'Exclude PRs with this label'
27+
required: true
28+
default: 'nocombine'
29+
30+
jobs:
31+
combine-prs:
32+
name: ${{ github.event.inputs.combineBranchName }}
33+
runs-on: ubuntu-latest
34+
steps:
35+
- uses: actions/github-script@v6
36+
with:
37+
github-token: ${{secrets.GITHUB_TOKEN}}
38+
script: |
39+
const pulls = await github.paginate('GET /repos/:owner/:repo/pulls', {
40+
owner: context.repo.owner,
41+
repo: context.repo.repo
42+
});
43+
const branchRegExp = new RegExp(`${{github.event.inputs.branchExpression}}`);
44+
let branchesAndPRStrings = [];
45+
let baseBranch = null;
46+
let baseBranchSHA = null;
47+
for (const pull of pulls) {
48+
const branch = pull['head']['ref'];
49+
console.log('Pull for branch: ' + branch);
50+
if (branchRegExp.test(branch)) {
51+
console.log('Branch matched: ' + branch);
52+
let statusOK = true;
53+
if(${{ github.event.inputs.mustBeGreen }}) {
54+
console.log('Checking green status: ' + branch);
55+
const stateQuery = `query($owner: String!, $repo: String!, $pull_number: Int!) {
56+
repository(owner: $owner, name: $repo) {
57+
pullRequest(number:$pull_number) {
58+
commits(last: 1) {
59+
nodes {
60+
commit {
61+
statusCheckRollup {
62+
state
63+
}
64+
}
65+
}
66+
}
67+
}
68+
}
69+
}`
70+
const vars = {
71+
owner: context.repo.owner,
72+
repo: context.repo.repo,
73+
pull_number: pull['number']
74+
};
75+
const result = await github.graphql(stateQuery, vars);
76+
const [{ commit }] = result.repository.pullRequest.commits.nodes;
77+
const state = commit.statusCheckRollup.state
78+
console.log('Validating status: ' + state);
79+
if(state != 'SUCCESS') {
80+
console.log('Discarding ' + branch + ' with status ' + state);
81+
statusOK = false;
82+
}
83+
}
84+
console.log('Checking labels: ' + branch);
85+
const labels = pull['labels'];
86+
for(const label of labels) {
87+
const labelName = label['name'];
88+
console.log('Checking label: ' + labelName);
89+
if(labelName == '${{ github.event.inputs.ignoreLabel }}') {
90+
console.log('Discarding ' + branch + ' with label ' + labelName);
91+
statusOK = false;
92+
}
93+
}
94+
if (statusOK) {
95+
console.log('Adding branch to array: ' + branch);
96+
const prString = '#' + pull['number'] + ' ' + pull['title'];
97+
branchesAndPRStrings.push({ branch, prString });
98+
baseBranch = pull['base']['ref'];
99+
baseBranchSHA = pull['base']['sha'];
100+
}
101+
}
102+
}
103+
if (branchesAndPRStrings.length == 0) {
104+
core.setFailed('No PRs/branches matched criteria');
105+
return;
106+
}
107+
if (branchesAndPRStrings.length == 1) {
108+
core.setFailed('Only one PR/branch matched criteria');
109+
return;
110+
}
111+
112+
try {
113+
await github.rest.git.createRef({
114+
owner: context.repo.owner,
115+
repo: context.repo.repo,
116+
ref: 'refs/heads/' + '${{ github.event.inputs.combineBranchName }}',
117+
sha: baseBranchSHA
118+
});
119+
} catch (error) {
120+
console.log(error);
121+
core.setFailed('Failed to create combined branch - maybe a branch by that name already exists?');
122+
return;
123+
}
124+
125+
let combinedPRs = [];
126+
let mergeFailedPRs = [];
127+
for(const { branch, prString } of branchesAndPRStrings) {
128+
try {
129+
await github.rest.repos.merge({
130+
owner: context.repo.owner,
131+
repo: context.repo.repo,
132+
base: '${{ github.event.inputs.combineBranchName }}',
133+
head: branch,
134+
});
135+
console.log('Merged branch ' + branch);
136+
combinedPRs.push(prString);
137+
} catch (error) {
138+
console.log('Failed to merge branch ' + branch);
139+
mergeFailedPRs.push(prString);
140+
}
141+
}
142+
143+
console.log('Creating combined PR');
144+
const combinedPRsString = combinedPRs.join('\n');
145+
let body = '⛙ Combined PRs:\n' + combinedPRsString;
146+
if(mergeFailedPRs.length > 0) {
147+
const mergeFailedPRsString = mergeFailedPRs.join('\n');
148+
body += '\n\n⚠️ The following PRs were left out due to merge conflicts:\n' + mergeFailedPRsString
149+
}
150+
await github.rest.pulls.create({
151+
owner: context.repo.owner,
152+
repo: context.repo.repo,
153+
title: '⛙ ${{github.event.inputs.combineTitle}}',
154+
head: '${{ github.event.inputs.combineBranchName }}',
155+
base: baseBranch,
156+
body: body
157+
});

0 commit comments

Comments
 (0)