Skip to content

Commit 514e583

Browse files
authored
Merge branch 'main' into patch-2
2 parents 2877a01 + d615677 commit 514e583

File tree

3,753 files changed

+1180189
-17025
lines changed

Some content is hidden

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

3,753 files changed

+1180189
-17025
lines changed

.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/*', '!/.*', '/.next/', 'script/bookmarklets/*'],
16+
ignorePatterns: ['tmp/*', '!/.*', '/.next/', 'script/bookmarklets/*', 'lib/sigsci.js'],
1717
rules: {
1818
'import/no-extraneous-dependencies': ['error', { packageDir: '.' }],
1919
},

.github/actions-scripts/content-changes-table-comment.js

Lines changed: 47 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { getContents } from '../../script/helpers/git-utils.js'
77
import parse from '../../lib/read-frontmatter.js'
88
import getApplicableVersions from '../../lib/get-applicable-versions.js'
99
import nonEnterpriseDefaultVersion from '../../lib/non-enterprise-default-version.js'
10+
import { allVersionShortnames } from '../../lib/all-versions.js'
1011

1112
const { GITHUB_TOKEN, APP_URL } = process.env
1213
const context = github.context
@@ -22,6 +23,7 @@ if (!APP_URL) {
2223
const PROD_URL = 'https://docs.github.com'
2324
const octokit = github.getOctokit(GITHUB_TOKEN)
2425

26+
// get the list of file changes from the PR
2527
const response = await octokit.rest.repos.compareCommitsWithBasehead({
2628
owner: context.repo.owner,
2729
repo: context.payload.repository.name,
@@ -61,36 +63,54 @@ for (const file of articleFiles) {
6163
if (file.status === 'added') contentCell = `New file: `
6264
contentCell += `[\`${fileName}\`](${sourceUrl})`
6365

64-
for (const version in data.versions) {
65-
const currentApplicableVersions = getApplicableVersions({
66-
[version]: data.versions[version],
67-
})
68-
69-
if (currentApplicableVersions.length === 1) {
70-
// for fpt, ghec, and ghae
71-
if (currentApplicableVersions.toString() === nonEnterpriseDefaultVersion) {
72-
// omit version from fpt url
73-
previewCell += `[${version}](${APP_URL}/${fileUrl})<br>`
74-
prodCell += `[${version}](${PROD_URL}/${fileUrl})<br>`
75-
} else {
76-
// for non-versioned releases (ghae, ghec) use full url
77-
previewCell += `[${version}](${APP_URL}/${currentApplicableVersions}/${fileUrl})<br>`
78-
prodCell += `[${version}](${PROD_URL}/${currentApplicableVersions}/${fileUrl})<br>`
66+
try {
67+
// the try/catch is needed because getApplicableVersions() returns either [] or throws an error when it can't parse the versions frontmatter
68+
// try/catch can be removed if docs-engineering#1821 is resolved
69+
// i.e. for feature based versioning, like ghae: 'issue-6337'
70+
const fileVersions = getApplicableVersions(data.versions)
71+
72+
for (const plan in allVersionShortnames) {
73+
// plan is the shortName (i.e., fpt)
74+
// allVersionShortNames[plan] is the planName (i.e., free-pro-team)
75+
76+
// walk by the plan names since we generate links differently for most plans
77+
const versions = fileVersions.filter((fileVersion) =>
78+
fileVersion.includes(allVersionShortnames[plan])
79+
)
80+
81+
if (versions.length === 1) {
82+
// for fpt, ghec, and ghae
83+
84+
if (versions.toString() === nonEnterpriseDefaultVersion) {
85+
// omit version from fpt url
86+
87+
previewCell += `[${plan}](${APP_URL}/${fileUrl})<br>`
88+
prodCell += `[${plan}](${PROD_URL}/${fileUrl})<br>`
89+
} else {
90+
// for non-versioned releases (ghae, ghec) use full url
91+
92+
previewCell += `[${plan}](${APP_URL}/${versions}/${fileUrl})<br>`
93+
prodCell += `[${plan}](${PROD_URL}/${versions}/${fileUrl})<br>`
94+
}
95+
} else if (versions.length) {
96+
// for ghes releases, link each version
97+
98+
previewCell += `${plan}@ `
99+
prodCell += `${plan}@ `
100+
101+
versions.forEach((version) => {
102+
previewCell += `[${version.split('@')[1]}](${APP_URL}/${version}/${fileUrl}) `
103+
prodCell += `[${version.split('@')[1]}](${PROD_URL}/${version}/${fileUrl}) `
104+
})
105+
previewCell += '<br>'
106+
prodCell += '<br>'
79107
}
80-
} else {
81-
// for ghes releases, link each version
82-
previewCell += `${version}@ `
83-
prodCell += `${version}@ `
84-
85-
currentApplicableVersions.forEach((ghesVersion) => {
86-
previewCell += `[${ghesVersion.split('@')[1]}](${APP_URL}/${ghesVersion}/${fileUrl}) `
87-
prodCell += `[${ghesVersion.split('@')[1]}](${PROD_URL}/${ghesVersion}/${fileUrl}) `
88-
})
89-
previewCell += '<br>'
90-
prodCell += '<br>'
91108
}
109+
} catch (e) {
110+
console.error(
111+
`Version information for ${file.filename} couldn't be determined from its frontmatter.`
112+
)
92113
}
93114
markdownTable += `| ${contentCell} | ${previewCell} | ${prodCell} | |\n`
94115
}
95-
96116
setOutput('changesTable', markdownTable)

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ async function main() {
1717
const github = getOctokit(token)
1818
const pull = await github.rest.pulls.get({
1919
owner: org,
20-
repo: repo,
20+
repo,
2121
pull_number: parseInt(prNumber),
2222
})
2323

.github/actions-scripts/enterprise-server-issue-templates/release-issue.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -110,20 +110,20 @@ This file should be automatically updated, but you can also run `script/update-e
110110
111111
### 🚢 🛳️ 🚢 Shipping the release branch
112112
113-
- [ ] Remove `[DO NOT MERGE]` and other meta information from the PR title 😜.
114-
- [ ] The `github/docs-internal` repo is frozen, and the `Repo Freeze Check / Prevent merging during deployment freezes (pull_request_target)` test is expected to fail.
115-
116-
Use admin permissions to ship the release branch with this failure. Make sure that the merge's commit title does not include anything like `[DO NOT MERGE]`, and remove all the branch's commit details from the merge's commit message except for the co-author list.
117-
- [ ] Do any required smoke tests listed in the opening post in the megabranch PR. You can monitor and check when the production deploy completed by viewing the [`docs-internal` deployments page](https://github.com/github/docs-internal/deployments).
118-
- [ ] Once smoke tests have passed, you can [unfreeze the repos](https://github.com/github/docs-content/blob/main/docs-content-docs/docs-content-workflows/freezing.md) and post an announcement in Slack.
119-
- [ ] After unfreezing, the megabranch creator should push the search index LFS objects for the public `github/docs` repo. The LFS objects were already pushed for the internal repo after the `sync-english-index-for-<PLAN@RELEASE>` was added to the megabranch. To push the LFS objects to the public repo:
113+
- [ ] The megabranch creator should push the search index LFS objects for the public `github/docs` repo. The LFS objects were already pushed for the internal repo after the `sync-english-index-for-<PLAN@RELEASE>` was added to the megabranch. To push the LFS objects to the public repo:
120114
1. First navigate to the [sync search indices workflow](https://github.com/github/docs-internal/actions/workflows/sync-search-indices.yml).
121115
2. Then, to run the workflow with parameters, click on `Run workflow` button.
122116
3. A modal will pop up where you will set the following inputs:
123-
- Branch: The new version megabranch you're working on
117+
- Branch: The new `ghes-<RELEASE>-megabranch` version megabranch you're working on
124118
- Version: `enterprise-server@<RELEASE>`
125119
- Language: `en`
126120
4. Run the job. The workflow job may fail on the first run—so retry the failed job if needed.
121+
- [ ] Remove `[DO NOT MERGE]` and other meta information from the PR title 😜.
122+
- [ ] The `github/docs-internal` repo is frozen, and the `Repo Freeze Check / Prevent merging during deployment freezes (pull_request_target)` test is expected to fail.
123+
124+
Use admin permissions to ship the release branch with this failure. Make sure that the merge's commit title does not include anything like `[DO NOT MERGE]`, and remove all the branch's commit details from the merge's commit message except for the co-author list.
125+
- [ ] Do any required smoke tests listed in the opening post in the megabranch PR. You can monitor and check when the production deploy completed by viewing the [`docs-internal` deployments page](https://github.com/github/docs-internal/deployments).
126+
- [ ] Once smoke tests have passed, you can [unfreeze the repos](https://github.com/github/docs-content/blob/main/docs-content-docs/docs-content-workflows/freezing.md) and post an announcement in Slack.
127127
- [ ] After unfreezing, alert the Ecosystem-API team in #ecosystem-api the docs freeze is finished/thawed and the release has shipped.
128128
- [ ] You (or they) can now remove your blocking review on the auto-generated "Update OpenAPI Descriptions" PR in public REST API description (the `rest-api-descriptions` repo). (although it's likely newer PRs have been created since yours with the blocking review, in which case the Ecosystem-API team will close your PR and perform the next step on the most recent PR).
129129
- [ ] The Ecosystem-API team will merge the latest auto-generated "Update OpenAPI Descriptions" PR (which will contain the OpenAPI schema config that changed `published` to `true` for the release).

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

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -191,16 +191,16 @@ async function run() {
191191

192192
await graphql(updateProjectNextItemMutation, {
193193
project: projectID,
194-
statusID: statusID,
194+
statusID,
195195
statusValueID: readyForReviewID,
196-
datePostedID: datePostedID,
197-
reviewDueDateID: reviewDueDateID,
198-
contributorTypeID: contributorTypeID,
199-
contributorType: contributorType,
200-
sizeTypeID: sizeTypeID,
196+
datePostedID,
197+
reviewDueDateID,
198+
contributorTypeID,
199+
contributorType,
200+
sizeTypeID,
201201
sizeType: '', // Although we aren't populating size, we are passing the variable so that we can use the shared mutation function
202-
featureID: featureID,
203-
authorID: authorID,
202+
featureID,
203+
authorID,
204204
headers: {
205205
authorization: `token ${process.env.TOKEN}`,
206206
'GraphQL-Features': 'projects_next_graphql',
Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
#!/usr/bin/env node
2+
3+
import fs from 'fs'
4+
import github from '@actions/github'
5+
6+
const OPTIONS = Object.fromEntries(
7+
['BASE', 'BODY_FILE', 'GITHUB_TOKEN', 'HEAD', 'LANGUAGE', 'TITLE', 'GITHUB_REPOSITORY'].map(
8+
(envVarName) => {
9+
const envVarValue = process.env[envVarName]
10+
if (!envVarValue) {
11+
throw new Error(`You must supply a ${envVarName} environment variable`)
12+
}
13+
return [envVarName, envVarValue]
14+
}
15+
)
16+
)
17+
18+
if (!process.env.GITHUB_REPOSITORY) {
19+
throw new Error('GITHUB_REPOSITORY environment variable not set')
20+
}
21+
22+
const RETRY_STATUSES = [
23+
422, // Retry the operation if the PR already exists
24+
502, // Retry the operation if the API responds with a `502 Bad Gateway` error.
25+
]
26+
const RETRY_ATTEMPTS = 3
27+
const {
28+
// One of the default environment variables provided by Actions.
29+
GITHUB_REPOSITORY,
30+
31+
// These are passed in from the step in the workflow file.
32+
TITLE,
33+
BASE,
34+
HEAD,
35+
LANGUAGE,
36+
BODY_FILE,
37+
GITHUB_TOKEN,
38+
} = OPTIONS
39+
const [OWNER, REPO] = GITHUB_REPOSITORY.split('/')
40+
41+
const octokit = github.getOctokit(GITHUB_TOKEN)
42+
43+
/**
44+
* @param {object} config Configuration options for finding the PR.
45+
* @returns {Promise<number | undefined>} The PR number.
46+
*/
47+
async function findPullRequestNumber(config) {
48+
// Get a list of PRs and see if one already exists.
49+
const { data: listOfPullRequests } = await octokit.rest.pulls.list({
50+
owner: config.owner,
51+
repo: config.repo,
52+
head: `${config.owner}:${config.head}`,
53+
})
54+
55+
return listOfPullRequests[0]?.number
56+
}
57+
58+
/**
59+
* When this file was first created, we only introduced support for creating a pull request for some translation batch.
60+
* However, some of our first workflow runs failed during the pull request creation due to a timeout error.
61+
* There have been cases where, despite the timeout error, the pull request gets created _anyway_.
62+
* To accommodate this reality, we created this function to look for an existing pull request before a new one is created.
63+
* Although the "find" check is redundant in the first "cycle", it's designed this way to recursively call the function again via its retry mechanism should that be necessary.
64+
*
65+
* @param {object} config Configuration options for creating the pull request.
66+
* @returns {Promise<number>} The PR number.
67+
*/
68+
async function findOrCreatePullRequest(config) {
69+
const found = await findPullRequestNumber(config)
70+
71+
if (found) {
72+
return found
73+
}
74+
75+
try {
76+
const { data: pullRequest } = await octokit.rest.pulls.create({
77+
owner: config.owner,
78+
repo: config.repo,
79+
base: config.base,
80+
head: config.head,
81+
title: config.title,
82+
body: config.body,
83+
draft: false,
84+
})
85+
86+
return pullRequest.number
87+
} catch (error) {
88+
if (!error.response || !config.retryCount) {
89+
throw error
90+
}
91+
92+
if (!config.retryStatuses.includes(error.response.status)) {
93+
throw error
94+
}
95+
96+
console.error(`Error creating pull request: ${error.message}`)
97+
console.warn(`Retrying in 5 seconds...`)
98+
await new Promise((resolve) => setTimeout(resolve, 5000))
99+
100+
config.retryCount -= 1
101+
102+
return findOrCreatePullRequest(config)
103+
}
104+
}
105+
106+
/**
107+
* @param {object} config Configuration options for labeling the PR
108+
* @returns {Promise<undefined>}
109+
*/
110+
// async function labelPullRequest(config) {
111+
// await octokit.rest.issues.update({
112+
// owner: config.owner,
113+
// repo: config.repo,
114+
// issue_number: config.issue_number,
115+
// labels: config.labels,
116+
// })
117+
// }
118+
119+
async function main() {
120+
const options = {
121+
title: TITLE,
122+
base: BASE,
123+
head: HEAD,
124+
body: fs.readFileSync(BODY_FILE, 'utf8'),
125+
labels: ['translation-batch', `translation-batch-${LANGUAGE}`],
126+
owner: OWNER,
127+
repo: REPO,
128+
retryStatuses: RETRY_STATUSES,
129+
retryCount: RETRY_ATTEMPTS,
130+
}
131+
132+
options.issue_number = await findOrCreatePullRequest(options)
133+
const pr = `${GITHUB_REPOSITORY}#${options.issue_number}`
134+
console.log(`Created PR ${pr}`)
135+
136+
// metadata parameters aren't currently available in `github.rest.pulls.create`,
137+
// but they are in `github.rest.issues.update`.
138+
// await labelPullRequest(options)
139+
// console.log(`Updated ${pr} with these labels: ${options.labels.join(', ')}`)
140+
}
141+
142+
main()

.github/actions-scripts/projects.js

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ export async function addItemsToProject(items, project) {
5959
`
6060

6161
const newItems = await graphql(mutation, {
62-
project: project,
62+
project,
6363
headers: {
6464
authorization: `token ${process.env.TOKEN}`,
6565
'GraphQL-Features': 'projects_next_graphql',
@@ -221,40 +221,40 @@ export function generateUpdateProjectNextItemFieldMutation({
221221
$authorID: ID!
222222
) {
223223
${generateMutationToUpdateField({
224-
item: item,
224+
item,
225225
fieldID: '$statusID',
226226
value: '$statusValueID',
227227
})}
228228
${generateMutationToUpdateField({
229-
item: item,
229+
item,
230230
fieldID: '$datePostedID',
231231
value: formatDateForProject(datePosted),
232232
literal: true,
233233
})}
234234
${generateMutationToUpdateField({
235-
item: item,
235+
item,
236236
fieldID: '$reviewDueDateID',
237237
value: formatDateForProject(dueDate),
238238
literal: true,
239239
})}
240240
${generateMutationToUpdateField({
241-
item: item,
241+
item,
242242
fieldID: '$contributorTypeID',
243243
value: '$contributorType',
244244
})}
245245
${generateMutationToUpdateField({
246-
item: item,
246+
item,
247247
fieldID: '$sizeTypeID',
248248
value: '$sizeType',
249249
})}
250250
${generateMutationToUpdateField({
251-
item: item,
251+
item,
252252
fieldID: '$featureID',
253253
value: feature,
254254
literal: true,
255255
})}
256256
${generateMutationToUpdateField({
257-
item: item,
257+
item,
258258
fieldID: '$authorID',
259259
value: author,
260260
literal: true,

0 commit comments

Comments
 (0)