Skip to content

Commit a260105

Browse files
authored
Merge branch 'main' into main
2 parents 07325c3 + 6063288 commit a260105

153 files changed

Lines changed: 3638 additions & 2213 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/actions-scripts/create-enterprise-issue.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,9 @@ async function run() {
8686
'utf8'
8787
)
8888
const issueLabels =
89-
milestone === 'release' ? ['enterprise release'] : ['enterprise deprecation', 'priority-4', 'batch', 'time sensitive']
89+
milestone === 'release'
90+
? ['enterprise release']
91+
: ['enterprise deprecation', 'priority-4', 'batch', 'time sensitive']
9092
const issueTitle = `[${nextMilestoneDate}] Enterprise Server ${versionNumber} ${milestone} (technical steps)`
9193

9294
const issueBody = `GHES ${versionNumber} ${milestone} occurs on ${nextMilestoneDate}.

.github/actions-scripts/enable-automerge.js

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,23 @@
11
import { getOctokit } from '@actions/github'
2-
const token = process.env.GITHUB_TOKEN
3-
const prNumber = process.env.AUTOMERGE_PR_NUMBER
4-
const github = getOctokit(token)
52

63
main()
74
async function main() {
8-
const pull = await github.pulls.get({
9-
...context.repo,
5+
const [org, repo] = process.env.GITHUB_REPOSITORY.split('/')
6+
if (!org || !repo) {
7+
throw new Error('GITHUB_REPOSITORY environment variable not set')
8+
}
9+
const prNumber = process.env.AUTOMERGE_PR_NUMBER
10+
if (!prNumber) {
11+
throw new Error(`AUTOMERGE_PR_NUMBER environment variable not set`)
12+
}
13+
const token = process.env.GITHUB_TOKEN
14+
if (!token) {
15+
throw new Error(`GITHUB_TOKEN environment variable not set`)
16+
}
17+
const github = getOctokit(token)
18+
const pull = await github.rest.pulls.get({
19+
owner: org,
20+
repo: repo,
1021
pull_number: parseInt(prNumber),
1122
})
1223

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
#!/usr/bin/env node
2+
3+
import { getOctokit } from '@actions/github'
4+
const token = process.env.GITHUB_TOKEN
5+
const github = getOctokit(token)
6+
7+
// Mergeable status documentation here:
8+
// https://docs.github.com/en/graphql/reference/enums#mergestatestatus
9+
// https://docs.github.com/en/graphql/reference/enums#mergeablestate
10+
11+
/*
12+
This script gets a list of automerge-enabled PRs and sorts them
13+
by priority. The PRs with the skip-to-front-of-merge-queue label
14+
are prioritized first. The rest of the PRs are sorted by the date
15+
they were updated. This is basically a FIFO queue, while allowing
16+
writers the ability to skip the line when high-priority ships are
17+
needed but a freeze isn't necessary.
18+
*/
19+
20+
main()
21+
22+
async function main() {
23+
const [org, repo] = process.env.GITHUB_REPOSITORY.split('/')
24+
if (!org || !repo) {
25+
throw new Error('GITHUB_REPOSITORY environment variable not set')
26+
}
27+
// Get a list of open PRs and order them from oldest to newest
28+
const query = `query ($first: Int, $after: String, $firstLabels: Int, $repo: String!, $org: String!) {
29+
organization(login: $org) {
30+
repository(name: $repo) {
31+
pullRequests(first: $first, after: $after, states: OPEN, orderBy: {field: UPDATED_AT, direction: ASC}) {
32+
edges{
33+
node {
34+
number
35+
url
36+
updatedAt
37+
mergeable
38+
mergeStateStatus
39+
autoMergeRequest {
40+
enabledBy {
41+
login
42+
}
43+
enabledAt
44+
}
45+
labels (first:$firstLabels){
46+
nodes {
47+
name
48+
}
49+
}
50+
}
51+
}
52+
pageInfo {
53+
hasNextPage
54+
endCursor
55+
}
56+
}
57+
}
58+
}
59+
}`
60+
61+
const queryVariables = {
62+
repo,
63+
org,
64+
first: 100,
65+
after: null, // when pagination in null it will get first page
66+
firstLabels: 100,
67+
headers: {
68+
// required for the mergeStateStatus enum
69+
accept: 'application/vnd.github.merge-info-preview+json',
70+
},
71+
}
72+
let hasNextPage = true
73+
const autoMergeEnabledPRs = []
74+
75+
// we need to get all the paginated results in the case that
76+
// there are more than 100 PRs
77+
while (hasNextPage) {
78+
const graph = await github.graphql(query, queryVariables)
79+
const dataRoot = graph.organization.repository.pullRequests
80+
const pullRequests = dataRoot.edges
81+
// update pagination variables
82+
hasNextPage = dataRoot.pageInfo.hasNextPage
83+
// the endCursor is the start cursor for the next page
84+
queryVariables.after = dataRoot.pageInfo.endCursor
85+
86+
const filteredPrs = pullRequests
87+
// this simplifies the format received from the graphql query to
88+
// remove the unnecessary nested objects
89+
.map((pr) => {
90+
// make the labels object just an array of the label names
91+
const labelArray = pr.node.labels.nodes.map((label) => label.name)
92+
pr.node.labels = labelArray
93+
// return the pr object and ✂️ the node property
94+
return pr.node
95+
})
96+
.filter((pr) => pr.autoMergeRequest !== null)
97+
.filter((pr) => pr.mergeable === 'MERGEABLE')
98+
// filter out prs that don't have a calculated mergeable state yet
99+
.filter((pr) => pr.mergeStateStatus !== 'UNKNOWN')
100+
// filter out prs that still need a review, have merge conflicts,
101+
// or have failing ci tests
102+
.filter((pr) => pr.mergeStateStatus !== 'BLOCKED')
103+
// **NOTE**: In the future we may want to send slack message to initiators
104+
// of PRs with the following merge states because these can happen after
105+
// a PR is green and the automerge is enabled
106+
.filter((pr) => pr.mergeStateStatus !== 'DIRTY')
107+
.filter((pr) => pr.mergeStateStatus !== 'UNSTABLE')
108+
109+
autoMergeEnabledPRs.push(...filteredPrs)
110+
}
111+
112+
// Get the list of prs with the skip label so they can
113+
// be put at the beginning of the list
114+
const prioritizedPrList = autoMergeEnabledPRs.sort(
115+
(a, b) =>
116+
Number(b.labels.includes('skip-to-front-of-merge-queue')) -
117+
Number(a.labels.includes('skip-to-front-of-merge-queue'))
118+
)
119+
120+
if (prioritizedPrList.length) {
121+
const nextInQueue = prioritizedPrList.shift()
122+
// Update the branch for the next PR in the merge queue
123+
github.rest.pulls.updateBranch({
124+
owner: org,
125+
repo,
126+
pull_number: nextInQueue.number,
127+
})
128+
console.log(`⏱ Total PRs in the merge queue: ${prioritizedPrList.length + 1}`)
129+
console.log(`🚂 Updated branch for PR #${JSON.stringify(nextInQueue, null, 2)}`)
130+
}
131+
132+
prioritizedPrList.length
133+
? console.log(`🚏 Next up in the queue: \n ${JSON.stringify(prioritizedPrList, null, 2)}`)
134+
: console.log(`⚡ The merge queue is empty`)
135+
}

.github/allowed-actions.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ export default [
1717
'cschleiden/actions-linter@caffd707beda4fc6083926a3dff48444bc7c24aa', // uses github-actions-parser v0.23.0
1818
'dawidd6/action-delete-branch@47743101a121ad657031e6704086271ca81b1911', // v3.0.2
1919
'dawidd6/action-download-artifact@af92a8455a59214b7b932932f2662fdefbd78126', // v2.15.0
20-
'docker://chinthakagodawita/autoupdate-action:v1',
2120
'dorny/paths-filter@eb75a1edc117d3756a18ef89958ee59f9500ba58',
2221
'trilom/file-changes-action@a6ca26c14274c33b15e6499323aac178af06ad4b', // v1.2.4
2322
'github/codeql-action/analyze@v1',
Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,22 @@
11
name: Autoupdate branch
22

3-
# **What it does**: Any pull requests with "autoupdate" label will get main branch updates.
4-
# **Why we have it**: Our repo-sync automation relies on it.
5-
# **Who does it impact**: Our ability to support the open-source repository.
6-
3+
# **What it does**: The next pull request in the merge queue will get its
4+
# branch updated with main. Only updating one branch ensures that pull requests
5+
# in the queue are merged sequentially.
6+
# **Why we have it**: So we don't have to watch pull requests and click
7+
# update branch 1000x.
8+
# **Who does it impact**: Our health.
79
#
8-
# This workflow checks all open PRs targeting `main` as their base branch and
9-
# will attempt to update them if they have the `autoupdate` label applied.
10-
# It is triggered when a `push` event occurs ON the `main` branch (e.g. a PR
11-
# was merged or a force-push was done).
10+
# The merge queue consists of any pull requests with automerge enabled and
11+
# are mergeable. There is a label that can be used to skip to the front of
12+
# the queue (`skip-to-front-of-merge-queue`).
1213
#
13-
# It should work on all PRs created from source branches within the repo itself
14-
# but is unlikely to work for PRs created from forked repos.
14+
# This workflow is triggered when a `push` event occurs ON the `main` branch
15+
# (e.g. a PR was merged or a force-push was done).
1516
#
16-
# It is still worthwhile to leave it enabled for the `docs` open source repo as
17-
# it should at least be running on `repo-sync` branch PRs.
17+
# This workflow runs on all PRs created from source branches within the
18+
# public and private docs repos but is won't work for PRs created from
19+
# forked repos.
1820
#
1921

2022
on:
@@ -28,9 +30,19 @@ jobs:
2830
name: autoupdate
2931
runs-on: ubuntu-latest
3032
steps:
31-
- uses: docker://chinthakagodawita/autoupdate-action:v1
33+
- name: Check out repo content
34+
uses: actions/checkout@1e204e9a9253d643386038d443f96446fa156a97
35+
36+
- name: Setup Node
37+
uses: actions/setup-node@270253e841af726300e85d718a5f606959b2903c
38+
with:
39+
node-version: 16.13.x
40+
cache: npm
41+
42+
- name: Install dependencies
43+
run: npm ci
44+
45+
- name: Update next PR in queue
3246
env:
33-
GITHUB_TOKEN: ${{ secrets.OCTOMERGER_PAT_WITH_REPO_AND_WORKFLOW_SCOPE }}
34-
PR_FILTER: labelled
35-
PR_LABELS: autoupdate
36-
MERGE_MSG: "Branch was updated using the 'autoupdate branch' Actions workflow."
47+
GITHUB_TOKEN: ${{ secrets.DOCUBOT_REPO_PAT }}
48+
run: node .github/actions-scripts/update-merge-queue-branch.js

0 commit comments

Comments
 (0)