-
Notifications
You must be signed in to change notification settings - Fork 4
189 lines (186 loc) · 8.63 KB
/
create-docs-pr.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
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
# Commits 0 Open PRs 1 Open PR 2 Open PRs
# ------------------------------------------- ---------------------------------------------------- ------------------------------------------------------------------------------------------------------- ---------------------------------------------------------
# Neither ahead or behind Nothing Dismiss PRs Dismiss PRs
# `documentation-gitbook` is behind Open A PR from `main` into `documentation-gitbook` Determine the directionality, if wrong dismiss and open a PR from `main` into `documentation-gitbook` Dismiss the PR from `documentation-gitbook` into `main`
# `documentation-gitbook` is behind Open A PR from `documentation-gitbook` into `main` Determine the directionality, if wrong dismiss and open a PR from `documentation-gitbook` into `main` Dismiss the PR from `main` into `documentation-gitbook`
# `documentation-gitbook` is ahead & behind Open 2 PRs Determine the directionality of the missing one and open that Nothing
name: create-docs-pr
on:
workflow_dispatch:
schedule:
- cron: '1 10 * * 1-5'
jobs:
create-pr:
runs-on: ubuntu-latest
env:
DOCS_BRANCH: documentation-gitbook
PR_LABELS: 'documentation,high priority'
PR_ASSIGNEES: 'emprzy,jcblemai,pearsonca,saraloo,TimothyWillard'
PR_TITLE: 'Sync GitBook'
OWNER: 'HopkinsIDD'
REPO: 'flepiMoP'
steps:
- name: Checkout
uses: actions/checkout@v4
with:
lfs: true
fetch-depth: 0
- name: Determine Commits Ahead/Behind
run: |
git fetch --all
DOCS_AHEAD_MAIN=$( eval "git rev-list --count origin/main..origin/$DOCS_BRANCH -- documentation/" )
DOCS_BEHIND_MAIN=$( eval "git rev-list --count origin/$DOCS_BRANCH..origin/main -- documentation/" )
echo "DOCS_AHEAD_MAIN=$DOCS_AHEAD_MAIN" >> $GITHUB_ENV
echo "DOCS_BEHIND_MAIN=$DOCS_BEHIND_MAIN" >> $GITHUB_ENV
- name: Create PR If Needed
uses: actions/github-script@v7
id: create-pr
with:
result-encoding: string
retries: 5
script: |
const { DOCS_AHEAD_MAIN, DOCS_BEHIND_MAIN, DOCS_BRANCH, PR_LABELS, PR_ASSIGNEES, PR_TITLE, OWNER, REPO } = process.env
const prLabels = PR_LABELS.split(",")
const prAssignees = PR_ASSIGNEES.split(",")
const cc = prAssignees.map(x => "@" + x).join(", ")
const docsAheadMain = parseInt(DOCS_AHEAD_MAIN, 10)
const docsBehindMain = parseInt(DOCS_BEHIND_MAIN, 10)
if (isNaN(docsAheadMain) || isNaN(docsBehindMain)) {
throw new Error(`Cannot convert either "${DOCS_AHEAD_MAIN}" or "${DOCS_BEHIND_MAIN}" to integers.`)
}
const initialResults = await github.rest.search.issuesAndPullRequests({
q: `owner:${OWNER} repo:${REPO} is:open is:pr in:title '${PR_TITLE}'`
})
const count = initialResults.data.total_count
if (count > 2) {
throw new Error(`There are ${count} open PRs containing '${PR_TITLE}', but this action can only handle 0, 1, or 2 open PRs.`)
}
console.log(`${DOCS_BRANCH} is ${docsAheadMain} ahead, ${docsBehindMain} behind main. The open PR count is ${count}.`)
async function dismissAllPRs() {
initialResults.data.items.forEach((item) => {
github.rest.pulls.update({
owner: OWNER,
repo: REPO,
pull_number: item.number,
state: "closed"
})
})
}
async function createPR({ from, to, body }) {
let prBody = `cc: ${cc}.`
if (body !== null) {
prBody = `${body} ${prBody}`
}
const today = (new Date()).toLocaleDateString()
const pr = await github.rest.pulls.create({
owner: OWNER,
repo: REPO,
head: from,
base: to,
title: `${today} ${PR_TITLE} From ${from} Into ${to}`,
body: prBody
})
github.rest.issues.addLabels({
owner: OWNER,
repo: REPO,
issue_number: pr.data.number,
labels: prLabels
})
github.rest.issues.addAssignees({
owner: OWNER,
repo: REPO,
issue_number: pr.data.number,
assignees: prAssignees
})
return pr.data.number
}
async function handleSingleDirection({ from, to }) {
if (count === 0) {
// There isn't the 1 expected PR, open it
createPR({
from: from,
to: to,
body: null
})
} else if (count === 1) {
// There is a PR open, determine direction
let title = initialResults.data.items[0].title
if (!title.includes(`${PR_TITLE} From ${from} Into ${to}`)) {
// Wrong direction, close & recreate
dismissAllPRs()
createPR({
from: from,
to: to,
body: null
})
}
} else {
// There are two PRs open, close the wrong direction
initialResults.data.items.forEach((item) => {
if (!title.includes(`${PR_TITLE} From ${from} Into ${to}`)) {
github.rest.pulls.update({
owner: OWNER,
repo: REPO,
pull_number: item.number,
state: "closed"
})
}
})
}
}
if (docsAheadMain > 0 && docsBehindMain > 0) {
// Need PRs both ways
if (count === 0) {
// There are 0 PRs open, open both of them
const docsIntoMainPrNumber = await createPR({
from: DOCS_BRANCH,
to: "main",
body: null
})
createPR({
from: "main",
to: DOCS_BRANCH,
body: `Please merge GH-${docsIntoMainPrNumber} first.`
})
} else if (count === 1) {
// There is already a PR open in one direction, open the other direction
let title = initialResults.data.items[0].title
let number = initialResults.data.items[0].number
if (title.includes(`${PR_TITLE} From ${DOCS_BRANCH} Into main`)) {
// From docs into main already exists, create main into docs
createPR({
from: "main",
to: DOCS_BRANCH,
body: `Please merge GH-${number} first.`
})
} else {
// From main into docs already exists, create docs into main
const docsIntoMainPrNumber = await createPR({
from: DOCS_BRANCH,
to: "main",
body: null
})
github.rest.issues.createComment({
owner: OWNER,
repo: REPO,
issue_number: number,
body: `Please merge GH-${docsIntoMainPrNumber} first.`
})
}
}
} else if (docsAheadMain > 0) {
// Need a PR from docs to main
handleSingleDirection({
from: DOCS_BRANCH,
to: "main"
})
} else if (docsBehindMain > 0) {
// Need a PR from main to docs
handleSingleDirection({
from: "main",
to: DOCS_BRANCH
})
} else if (count > 0) {
// Ahead/behind commits is 0 but there are stale PRs to close
dismissAllPRs()
}