Skip to content

Commit 154e33a

Browse files
authored
Merge branch 'main' into yaananth-patch-1
2 parents 1e87113 + cfbc6f6 commit 154e33a

4,488 files changed

Lines changed: 97909 additions & 114753 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.

.devcontainer/devcontainer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,5 @@
3333

3434
// Comment out connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root.
3535
"remoteUser": "node"
36+
3637
}

.eslintrc.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ module.exports = {
1313
babelOptions: { configFile: './.babelrc' },
1414
sourceType: 'module',
1515
},
16-
ignorePatterns: ['tmp/*'],
16+
ignorePatterns: ['tmp/*', '!/.*', '/.next/'],
1717
rules: {
1818
'import/no-extraneous-dependencies': ['error', { packageDir: '.' }],
1919
},

.github/CODEOWNERS

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
/.github/ @github/docs-engineering
1111
/script/ @github/docs-engineering
1212
/includes/ @github/docs-engineering
13+
/lib/search/popular-pages.json @github/docs-engineering
1314
app.json @github/docs-engineering
1415
Dockerfile @github/docs-engineering
1516
package-lock.json @github/docs-engineering
@@ -19,8 +20,8 @@ package.json @github/docs-engineering
1920
/.github/workflows/create-translation-batch-pr.yml @github/docs-localization
2021
/.github/workflows/crowdin.yml @github/docs-localization
2122
/crowdin*.yml @github/docs-engineering @github/docs-localization
22-
/translations/ @github/docs-engineering @github/docs-localization @github-actions
23-
/translations/log/ @github/docs-localization
23+
/translations/ @github/docs-engineering @github/docs-localization @Octomerger
24+
/translations/log/ @github/docs-localization @Octomerger
2425

2526
# Site Policy
2627
/content/github/site-policy/ @github/site-policy-admins

.github/actions-scripts/fr-add-docs-reviewers-requests.js

Lines changed: 99 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -8,88 +8,83 @@ import {
88
generateUpdateProjectNextItemFieldMutation,
99
} from './projects.js'
1010

11-
async function run() {
12-
// Get info about the docs-content review board project
13-
// and about open github/github PRs
14-
const data = await graphql(
15-
`
16-
query ($organization: String!, $repo: String!, $projectNumber: Int!, $num_prs: Int!) {
17-
organization(login: $organization) {
18-
projectNext(number: $projectNumber) {
19-
id
20-
items(last: 100) {
11+
async function getAllOpenPRs() {
12+
let prsRemaining = true
13+
let cursor
14+
let prData = []
15+
while (prsRemaining) {
16+
const data = await graphql(
17+
`
18+
query ($organization: String!, $repo: String!) {
19+
repository(name: $repo, owner: $organization) {
20+
pullRequests(last: 100, states: OPEN${cursor ? ` before:"${cursor}"` : ''}) {
21+
pageInfo{startCursor, hasPreviousPage},
2122
nodes {
2223
id
23-
}
24-
}
25-
fields(first: 20) {
26-
nodes {
27-
id
28-
name
29-
settings
30-
}
31-
}
32-
}
33-
}
34-
repository(name: $repo, owner: $organization) {
35-
pullRequests(last: $num_prs, states: OPEN) {
36-
nodes {
37-
id
38-
isDraft
39-
reviewRequests(first: 10) {
40-
nodes {
41-
requestedReviewer {
42-
... on Team {
43-
name
24+
isDraft
25+
reviewRequests(first: 10) {
26+
nodes {
27+
requestedReviewer {
28+
... on Team {
29+
name
30+
}
4431
}
4532
}
4633
}
47-
}
48-
labels(first: 5) {
49-
nodes {
50-
name
34+
labels(first: 5) {
35+
nodes {
36+
name
37+
}
5138
}
52-
}
53-
reviews(first: 10) {
54-
nodes {
55-
onBehalfOf(first: 1) {
56-
nodes {
57-
name
39+
reviews(first: 10) {
40+
nodes {
41+
onBehalfOf(first: 1) {
42+
nodes {
43+
name
44+
}
5845
}
5946
}
6047
}
61-
}
62-
author {
63-
login
48+
author {
49+
login
50+
}
6451
}
6552
}
6653
}
6754
}
55+
`,
56+
{
57+
organization: process.env.ORGANIZATION,
58+
repo: process.env.REPO,
59+
headers: {
60+
authorization: `token ${process.env.TOKEN}`,
61+
},
6862
}
69-
`,
70-
{
71-
organization: process.env.ORGANIZATION,
72-
repo: process.env.REPO,
73-
projectNumber: parseInt(process.env.PROJECT_NUMBER),
74-
num_prs: parseInt(process.env.NUM_PRS),
75-
headers: {
76-
authorization: `token ${process.env.TOKEN}`,
77-
'GraphQL-Features': 'projects_next_graphql',
78-
},
79-
}
80-
)
63+
)
64+
65+
prsRemaining = data.repository.pullRequests.pageInfo.hasPreviousPage
66+
cursor = data.repository.pullRequests.pageInfo.startCursor
67+
prData = [...prData, ...data.repository.pullRequests.nodes]
68+
}
69+
70+
return prData
71+
}
72+
73+
async function run() {
74+
// Get info about open github/github PRs
75+
const prData = await getAllOpenPRs()
8176

8277
// Get the PRs that are:
8378
// - not draft
8479
// - not a train
8580
// - are requesting a review by docs-reviewers
8681
// - have not already been reviewed on behalf of docs-reviewers
87-
const prs = data.repository.pullRequests.nodes.filter(
82+
const prs = prData.filter(
8883
(pr) =>
8984
!pr.isDraft &&
9085
!pr.labels.nodes.find((label) => label.name === 'Deploy train 🚂') &&
9186
pr.reviewRequests.nodes.find(
92-
(requestedReviewers) => requestedReviewers.requestedReviewer.name === process.env.REVIEWER
87+
(requestedReviewers) => requestedReviewers.requestedReviewer?.name === process.env.REVIEWER
9388
) &&
9489
!pr.reviews.nodes
9590
.flatMap((review) => review.onBehalfOf.nodes)
@@ -104,28 +99,60 @@ async function run() {
10499
const prAuthors = prs.map((pr) => pr.author.login)
105100
console.log(`PRs found: ${prIDs}`)
106101

102+
// Get info about the docs-content review board project
103+
const projectData = await graphql(
104+
`
105+
query ($organization: String!, $projectNumber: Int!) {
106+
organization(login: $organization) {
107+
projectNext(number: $projectNumber) {
108+
id
109+
items(last: 100) {
110+
nodes {
111+
id
112+
}
113+
}
114+
fields(first: 100) {
115+
nodes {
116+
id
117+
name
118+
settings
119+
}
120+
}
121+
}
122+
}
123+
}
124+
`,
125+
{
126+
organization: process.env.ORGANIZATION,
127+
projectNumber: parseInt(process.env.PROJECT_NUMBER),
128+
headers: {
129+
authorization: `token ${process.env.TOKEN}`,
130+
},
131+
}
132+
)
133+
107134
// Get the project ID
108-
const projectID = data.organization.projectNext.id
135+
const projectID = projectData.organization.projectNext.id
109136

110137
// Get the IDs of the last 100 items on the board.
111138
// Until we have a way to check from a PR whether the PR is in a project,
112139
// this is how we (roughly) avoid overwriting PRs that are already on the board.
113140
// If we are overwriting items, query for more items.
114-
const existingItemIDs = data.organization.projectNext.items.nodes.map((node) => node.id)
141+
const existingItemIDs = projectData.organization.projectNext.items.nodes.map((node) => node.id)
115142

116143
// Get the ID of the fields that we want to populate
117-
const datePostedID = findFieldID('Date posted', data)
118-
const reviewDueDateID = findFieldID('Review due date', data)
119-
const statusID = findFieldID('Status', data)
120-
const featureID = findFieldID('Feature', data)
121-
const contributorTypeID = findFieldID('Contributor type', data)
122-
const sizeTypeID = findFieldID('Size', data)
123-
const authorID = findFieldID('Contributor', data)
144+
const datePostedID = findFieldID('Date posted', projectData)
145+
const reviewDueDateID = findFieldID('Review due date', projectData)
146+
const statusID = findFieldID('Status', projectData)
147+
const featureID = findFieldID('Feature', projectData)
148+
const contributorTypeID = findFieldID('Contributor type', projectData)
149+
const sizeTypeID = findFieldID('Size', projectData)
150+
const authorID = findFieldID('Contributor', projectData)
124151

125152
// Get the ID of the single select values that we want to set
126-
const readyForReviewID = findSingleSelectID('Ready for review', 'Status', data)
127-
const hubberTypeID = findSingleSelectID('Hubber or partner', 'Contributor type', data)
128-
const docsMemberTypeID = findSingleSelectID('Docs team', 'Contributor type', data)
153+
const readyForReviewID = findSingleSelectID('Ready for review', 'Status', projectData)
154+
const hubberTypeID = findSingleSelectID('Hubber or partner', 'Contributor type', projectData)
155+
const docsMemberTypeID = findSingleSelectID('Docs team', 'Contributor type', projectData)
129156

130157
// Add the PRs to the project
131158
const itemIDs = await addItemsToProject(prIDs, projectID)
@@ -134,8 +161,8 @@ async function run() {
134161
// Exclude existing items going forward.
135162
// Until we have a way to check from a PR whether the PR is in a project,
136163
// this is how we (roughly) avoid overwriting PRs that are already on the board
137-
let newItemIDs = []
138-
let newItemAuthors = []
164+
const newItemIDs = []
165+
const newItemAuthors = []
139166
itemIDs.forEach((id, index) => {
140167
if (!existingItemIDs.includes(id)) {
141168
newItemIDs.push(id)

.github/actions-scripts/projects.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,29 @@ export async function isDocsTeamMember(login) {
114114
return teamMembers.includes(login)
115115
}
116116

117+
// Given a GitHub login, returns a bool indicating
118+
// whether the login is part of the GitHub org
119+
export async function isGitHubOrgMember(login) {
120+
const data = await graphql(
121+
`
122+
query {
123+
user(login: "${login}") {
124+
organization(login: "github"){
125+
name
126+
}
127+
}
128+
}
129+
`,
130+
{
131+
headers: {
132+
authorization: `token ${process.env.TOKEN}`,
133+
},
134+
}
135+
)
136+
137+
return Boolean(data.user.organization)
138+
}
139+
117140
// Formats a date object into the required format for projects
118141
export function formatDateForProject(date) {
119142
return date.getFullYear() + '-' + (date.getMonth() + 1) + '-' + date.getDate()
@@ -246,6 +269,7 @@ export default {
246269
addItemsToProject,
247270
addItemToProject,
248271
isDocsTeamMember,
272+
isGitHubOrgMember,
249273
findFieldID,
250274
findSingleSelectID,
251275
formatDateForProject,

.github/actions-scripts/purge-fastly-edge-cache.js

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,4 @@
22

33
import purgeEdgeCache from '../../script/deployment/purge-edge-cache.js'
44

5-
try {
6-
await purgeEdgeCache()
7-
} catch (error) {
8-
console.error(`Failed to purge the edge cache: ${error.message}`)
9-
console.error(error)
10-
throw error
11-
}
5+
await purgeEdgeCache()

.github/actions-scripts/ready-for-docs-review.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { graphql } from '@octokit/graphql'
33
import {
44
addItemToProject,
55
isDocsTeamMember,
6+
isGitHubOrgMember,
67
findFieldID,
78
findSingleSelectID,
89
generateUpdateProjectNextItemFieldMutation,
@@ -85,8 +86,8 @@ async function run() {
8586
// - affected docs sets (not considering changes to data/assets)
8687
let numFiles = 0
8788
let numChanges = 0
88-
let features = new Set([])
89-
const files = data.item.files.nodes.forEach((node) => {
89+
const features = new Set([])
90+
data.item.files.nodes.forEach((node) => {
9091
numFiles += 1
9192
numChanges += node.additions
9293
numChanges += node.deletions
@@ -178,9 +179,12 @@ async function run() {
178179
let contributorType
179180
if (await isDocsTeamMember(process.env.AUTHOR_LOGIN)) {
180181
contributorType = docsMemberTypeID
182+
} else if (await isGitHubOrgMember(process.env.AUTHOR_LOGIN)) {
183+
contributorType = hubberTypeID
181184
} else if (process.env.REPO === 'github/docs') {
182185
contributorType = osContributorTypeID
183186
} else {
187+
// use hubber as the fallback so that the PR doesn't get lost on the board
184188
contributorType = hubberTypeID
185189
}
186190

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
#!/usr/bin/env node
2+
3+
import * as github from '@actions/github'
4+
5+
import getOctokit from '../../script/helpers/github.js'
6+
7+
const { GITHUB_TOKEN } = process.env
8+
9+
// Exit if GitHub Actions PAT is not found
10+
if (!GITHUB_TOKEN) {
11+
throw new Error('You must supply a GITHUB_TOKEN environment variable!')
12+
}
13+
14+
// This helper uses the `GITHUB_TOKEN` implicitly!
15+
// We're using our usual version of Octokit vs. the provided `github`
16+
// instance to avoid versioning discrepancies.
17+
const octokit = getOctokit()
18+
19+
const { CONTEXT_NAME, ACTIONS_RUN_LOG, HEAD_SHA } = process.env
20+
if (!CONTEXT_NAME) {
21+
throw new Error('$CONTEXT_NAME not set')
22+
}
23+
if (!ACTIONS_RUN_LOG) {
24+
throw new Error('$ACTIONS_RUN_LOG not set')
25+
}
26+
if (!HEAD_SHA) {
27+
throw new Error('$HEAD_SHA not set')
28+
}
29+
30+
const { context } = github
31+
const owner = context.repo.owner
32+
const repo = context.payload.repository.name
33+
34+
await octokit.repos.createCommitStatus({
35+
owner,
36+
repo,
37+
sha: HEAD_SHA,
38+
context: CONTEXT_NAME,
39+
state: 'success',
40+
description: 'Successfully deployed! See logs.',
41+
target_url: ACTIONS_RUN_LOG,
42+
})

0 commit comments

Comments
 (0)