-
Notifications
You must be signed in to change notification settings - Fork 2
143 lines (134 loc) · 5.49 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
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
type: string
default: dependabot
mustBeGreen:
description: "Only combine PRs that are green (status is success)"
type: boolean
required: true
default: true
combineBranchName:
description: "Name of the branch to combine PRs into"
type: string
required: true
default: "combine-prs-branch"
ignoreLabel:
description: "Exclude PRs with this label"
type: string
required: true
default: nocombine
# 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
# Steps represent a sequence of tasks that will be executed as part of the job
steps:
- uses: actions/github-script@v7
id: fetch-branch-names
name: Fetch branch names
with:
github-token: ${{secrets.GITHUB_TOKEN}}
script: |
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 pr = pull['number']
const branch = pull['head']['ref'];
console.log('Pull ' + pr + ' 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 prDetails = await github.rest.pulls.get({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: pr,
});
console.log('PR mergeable? ' + prDetails.data.mergeable);
if(!prDetails.data.mergeable) {
console.log('Discarding ' + branch);
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@v4
with:
fetch-depth: 0
# Creates a branch with other PR branches merged together
- name: Created 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 [email protected]
git branch $COMBINE_BRANCH_NAME $basebranch
git checkout $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@v7
name: Create Combined Pull Request
env:
PRS_STRING: ${{ steps.fetch-branch-names.outputs.prs-string }}
with:
github-token: ${{secrets.GITHUB_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: 'Combined PR',
head: '${{ github.event.inputs.combineBranchName }}',
base: '${{ steps.fetch-branch-names.outputs.base-branch }}',
body: body
});