Skip to content

Commit a113ce1

Browse files
addshoreoutdooracorn
authored andcommitted
Add .github/workflows/github.prs.combine.yml
1 parent 6d1d0b7 commit a113ce1

File tree

1 file changed

+136
-0
lines changed

1 file changed

+136
-0
lines changed
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
# From https://github.com/testcontainers/testcontainers-java/blob/master/.github/workflows/combine-prs.yml
2+
name: 'Combine PRs'
3+
4+
# Controls when the action will run - in this case triggered manually
5+
on:
6+
workflow_dispatch:
7+
inputs:
8+
branchPrefix:
9+
description: 'Branch prefix to find combinable PRs based on'
10+
required: true
11+
default: 'dependabot'
12+
mustBeGreen:
13+
description: 'Only combine PRs that are green (status is success)'
14+
required: true
15+
default: 'true'
16+
combineBranchName:
17+
description: 'Name of the branch to combine PRs into'
18+
required: true
19+
default: 'combine-prs-branch'
20+
ignoreLabel:
21+
description: 'Exclude PRs with this label'
22+
required: true
23+
default: 'nocombine'
24+
25+
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
26+
jobs:
27+
# This workflow contains a single job called "combine-prs"
28+
combine-prs:
29+
# The type of runner that the job will run on
30+
runs-on: ubuntu-latest
31+
32+
# Steps represent a sequence of tasks that will be executed as part of the job
33+
steps:
34+
- uses: actions/github-script@v4.1
35+
id: fetch-branch-names
36+
name: Fetch branch names
37+
with:
38+
github-token: ${{secrets.GH_TOKEN_PLUSW}}
39+
script: |
40+
const pulls = await github.paginate('GET /repos/:owner/:repo/pulls', {
41+
owner: context.repo.owner,
42+
repo: context.repo.repo
43+
});
44+
branches = [];
45+
prs = [];
46+
base_branch = null;
47+
for (const pull of pulls) {
48+
const branch = pull['head']['ref'];
49+
console.log('Pull for branch: ' + branch);
50+
if (branch.startsWith('${{ github.event.inputs.branchPrefix }}')) {
51+
console.log('Branch matched: ' + branch);
52+
statusOK = true;
53+
if(${{ github.event.inputs.mustBeGreen }}) {
54+
console.log('Checking green status: ' + branch);
55+
const checkRuns = await github.request('GET /repos/{owner}/{repo}/commits/{ref}/check-runs', {
56+
owner: context.repo.owner,
57+
repo: context.repo.repo,
58+
ref: branch
59+
});
60+
for await (const cr of checkRuns.data.check_runs) {
61+
console.log('Validating check conclusion: ' + cr.conclusion);
62+
if(cr.conclusion != 'success') {
63+
console.log('Discarding ' + branch + ' with check conclusion ' + cr.conclusion);
64+
statusOK = false;
65+
}
66+
}
67+
}
68+
console.log('Checking labels: ' + branch);
69+
const labels = pull['labels'];
70+
for(const label of labels) {
71+
const labelName = label['name'];
72+
console.log('Checking label: ' + labelName);
73+
if(labelName == '${{ github.event.inputs.ignoreLabel }}') {
74+
console.log('Discarding ' + branch + ' with label ' + labelName);
75+
statusOK = false;
76+
}
77+
}
78+
if (statusOK) {
79+
console.log('Adding branch to array: ' + branch);
80+
branches.push(branch);
81+
prs.push('#' + pull['number'] + ' ' + pull['title']);
82+
base_branch = pull['base']['ref'];
83+
}
84+
}
85+
}
86+
if (branches.length == 0) {
87+
core.setFailed('No PRs/branches matched criteria');
88+
return;
89+
}
90+
core.setOutput('base-branch', base_branch);
91+
core.setOutput('prs-string', prs.join('\n'));
92+
combined = branches.join(' ')
93+
console.log('Combined: ' + combined);
94+
return combined
95+
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
96+
- uses: actions/checkout@v2.3.3
97+
with:
98+
fetch-depth: 0
99+
token: ${{ secrets.GH_TOKEN_PLUSW }}
100+
# Creates a branch with other PR branches merged together
101+
- name: Created combined branch
102+
env:
103+
BASE_BRANCH: ${{ steps.fetch-branch-names.outputs.base-branch }}
104+
BRANCHES_TO_COMBINE: ${{ steps.fetch-branch-names.outputs.result }}
105+
COMBINE_BRANCH_NAME: ${{ github.event.inputs.combineBranchName }}
106+
run: |
107+
echo "$BRANCHES_TO_COMBINE"
108+
sourcebranches="${BRANCHES_TO_COMBINE%\"}"
109+
sourcebranches="${sourcebranches#\"}"
110+
basebranch="${BASE_BRANCH%\"}"
111+
basebranch="${basebranch#\"}"
112+
git config pull.rebase false
113+
git config user.name github-actions
114+
git config user.email github-actions@github.com
115+
git branch $COMBINE_BRANCH_NAME $basebranch
116+
git checkout $COMBINE_BRANCH_NAME
117+
git pull origin $sourcebranches --no-edit
118+
git push origin $COMBINE_BRANCH_NAME --force-with-lease
119+
# Creates a PR with the new combined branch
120+
- uses: actions/github-script@v4.1
121+
name: Create Combined Pull Request
122+
env:
123+
PRS_STRING: ${{ steps.fetch-branch-names.outputs.prs-string }}
124+
with:
125+
github-token: ${{secrets.GH_TOKEN_PLUSW}}
126+
script: |
127+
const prString = process.env.PRS_STRING;
128+
const body = 'This PR was created by the Combine PRs action by combining the following PRs:\n' + prString;
129+
await github.pulls.create({
130+
owner: context.repo.owner,
131+
repo: context.repo.repo,
132+
title: 'Combined PR for prefix: ${{ github.event.inputs.branchPrefix }}',
133+
head: '${{ github.event.inputs.combineBranchName }}',
134+
base: '${{ steps.fetch-branch-names.outputs.base-branch }}',
135+
body: body
136+
});

0 commit comments

Comments
 (0)