1
0
mirror of synced 2025-12-21 19:06:49 -05:00

Merge branch 'main' into mm-cs-networking

This commit is contained in:
Mike McDonald
2021-12-07 15:15:59 -07:00
committed by GitHub
2586 changed files with 93134 additions and 78108 deletions

View File

@@ -21,15 +21,16 @@
"davidanson.vscode-markdownlint", "davidanson.vscode-markdownlint",
"bierner.markdown-preview-github-styles", "bierner.markdown-preview-github-styles",
"yzhang.markdown-all-in-one", "yzhang.markdown-all-in-one",
"streetsidesoftware.code-spell-checker" "streetsidesoftware.code-spell-checker",
"hubwriter.open-reusable"
], ],
// Use 'forwardPorts' to make a list of ports inside the container available locally. // Use 'forwardPorts' to make a list of ports inside the container available locally.
"forwardPorts": [4000], "forwardPorts": [4000],
// Use 'postCreateCommand' to run commands after the container is created. // Use 'postCreateCommand' to run commands after the container is created.
"postCreateCommand": "npm ci && npm run build", "postCreateCommand": "npm ci && npm run build",
// Comment out connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root. // Comment out connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root.
"remoteUser": "node" "remoteUser": "node"
} }

2
.github/CODEOWNERS vendored
View File

@@ -16,9 +16,11 @@ package-lock.json @github/docs-engineering
package.json @github/docs-engineering package.json @github/docs-engineering
# Localization # Localization
/.github/workflows/create-translation-batch-pr.yml @github/docs-localization
/.github/workflows/crowdin.yml @github/docs-localization /.github/workflows/crowdin.yml @github/docs-localization
/crowdin*.yml @github/docs-engineering @github/docs-localization /crowdin*.yml @github/docs-engineering @github/docs-localization
/translations/ @github/docs-engineering @github/docs-localization @github-actions /translations/ @github/docs-engineering @github/docs-localization @github-actions
/translations/log/ @github/docs-localization
# Site Policy # Site Policy
/content/github/site-policy/ @github/site-policy-admins /content/github/site-policy/ @github/site-policy-admins

View File

@@ -0,0 +1,63 @@
#!/usr/bin/env node
import path from 'path'
import fs from 'fs'
import zlib from 'zlib'
import walk from 'walk-sync'
const DRY_RUN = Boolean(JSON.parse(process.env.DRY_RUN || 'false'))
// Roughly 100KiB means about 25 files at the moment.
// Set this too low and the overheads will be more than the disk and
// network I/O that this intends to serve.
const MIN_GZIP_SIZE = Number(process.env.MIN_GZIP_SIZE || 1024 * 100)
const BROTLI_OPTIONS = {
params: {
[zlib.constants.BROTLI_PARAM_MODE]: zlib.constants.BROTLI_MODE_TEXT,
[zlib.constants.BROTLI_PARAM_QUALITY]: 6,
},
}
main()
async function main() {
compressFromPattern('lib/**/static/**/*.json')
}
async function compressFromPattern(pattern) {
const glob = pattern.includes('*') ? pattern.split(path.sep).slice(1).join(path.sep) : undefined
const walkOptions = {
globs: glob ? [glob] : undefined,
directories: false,
includeBasePath: true,
}
const root = path.resolve(pattern.includes('*') ? pattern.split(path.sep)[0] : pattern)
const filePaths = walk(root, walkOptions).filter((filePath) => {
return fs.statSync(filePath).size > MIN_GZIP_SIZE
})
if (!DRY_RUN) {
console.time(`Compress ${filePaths.length} files`)
const compressed = await Promise.all(filePaths.map(compressFile))
console.timeEnd(`Compress ${filePaths.length} files`)
console.time(`Delete ${compressed.length} files`)
compressed.forEach((filePath) => fs.unlinkSync(filePath))
console.timeEnd(`Delete ${compressed.length} files`)
}
}
function compressFile(filePath) {
return new Promise((resolve, reject) => {
const contentStream = fs.createReadStream(filePath)
const newFilePath = `${filePath}.br`
const writeStream = fs.createWriteStream(newFilePath)
const compressor = zlib.createBrotliCompress(BROTLI_OPTIONS)
contentStream
.pipe(compressor)
.pipe(writeStream)
.on('finish', (err) => {
if (err) return reject(err)
resolve(filePath)
})
})
}

View File

@@ -0,0 +1,54 @@
#!/usr/bin/env node
import createStagingAppName from '../../script/deployment/create-staging-app-name.js'
import * as github from '@actions/github'
import { setOutput } from '@actions/core'
const context = github.context
const githubToken = process.env.GITHUB_TOKEN
if (!githubToken) {
throw new Error(`GITHUB_TOKEN environment variable not set`)
}
const stagingPrefix = createStagingAppName({
repo: context.payload.repository.name,
pullNumber: context.payload.number,
branch: context.payload.pull_request.head.ref,
})
const octokit = github.getOctokit(githubToken)
const response = await octokit.rest.repos.compareCommits({
owner: context.repo.owner,
repo: context.payload.repository.name,
base: context.payload.pull_request.base.sha,
head: context.payload.pull_request.head.sha,
})
const { files } = response.data
let markdownTable =
'| **Source** | **Staging** | **Production** | **What Changed** |\n|:----------- |:----------- |:----------- |:----------- |\n'
const pathPrefix = 'content/'
const articleFiles = files.filter(
({ filename }) => filename.startsWith(pathPrefix) && !filename.endsWith('/index.md')
)
for (const file of articleFiles) {
const sourceUrl = file.blob_url
const fileName = file.filename.slice(pathPrefix.length)
const fileUrl = fileName.slice(0, fileName.lastIndexOf('.'))
const stagingLink = `https://${stagingPrefix}.herokuapp.com/${fileUrl}`
const productionLink = `https://docs.github.com/${fileUrl}`
let markdownLine = ''
if (file.status === 'modified') {
markdownLine = `| [content/${fileName}](${sourceUrl}) | [Modified](${stagingLink}) | [Original](${productionLink}) | |\n`
} else if (file.status === 'added') {
markdownLine = `| New file: [content/${fileName}](${sourceUrl}) | [Modified](${stagingLink}) | | |\n`
}
markdownTable += markdownLine
}
setOutput('changesTable', markdownTable)

View File

@@ -12,13 +12,13 @@ If you aren't comfortable going through the steps alone, sync up with a docs eng
- [ ] Increment the `next` variable above the `supported` array (e.g., new release number + `.1`). - [ ] Increment the `next` variable above the `supported` array (e.g., new release number + `.1`).
- [ ] Increment the `nextNext` variable above the `supported` array (e.g., new release number + `.2`). - [ ] Increment the `nextNext` variable above the `supported` array (e.g., new release number + `.2`).
- [ ] Update the GHES dates file: - [ ] Update the GHES dates file:
- [ ] Make sure you have a `.env` file at the root directory of your local checkout, and that it contains a PAT in the format of `GITHUB_TOKEN=<token>`. - [ ] Make sure you have a `.env` file at the root directory of your local checkout, and that it contains a PAT in the format of `GITHUB_TOKEN=<token>` with `repo` scope. Ensure the PAT is SSO-enabled for the `github` org.
- [ ] Run the script to update the dates file: - [ ] Run the script to update the dates file:
``` ```
script/update-enterprise-dates.js script/update-enterprise-dates.js
``` ```
- [ ] Create REST files based on previous version: - [ ] Create REST files based on previous version. For example `script/enterprise-server-releases/create-rest-files.js --oldVersion enterprise-server@3.2 --newVersion enterprise-server@3.3`:
``` ```
script/enterprise-server-releases/create-rest-files.js --oldVersion <PLAN@RELEASE> --newVersion <PLAN@RELEASE> script/enterprise-server-releases/create-rest-files.js --oldVersion <PLAN@RELEASE> --newVersion <PLAN@RELEASE>
@@ -33,7 +33,7 @@ If you aren't comfortable going through the steps alone, sync up with a docs eng
``` ```
script/enterprise-server-releases/create-webhook-files.js --oldVersion <PLAN@RELEASE> --newVersion <PLAN@RELEASE> script/enterprise-server-releases/create-webhook-files.js --oldVersion <PLAN@RELEASE> --newVersion <PLAN@RELEASE>
``` ```
- [ ] Create a placeholder release notes file called `data/release-notes/<PRODUCT>/<RELEASE NUMBER>/PLACEHOLDER.yml`. For example `data/release-notes/3-1/PLACEHOLDER.yml`. Add the following placeholder content to the file: - [ ] Create a placeholder release notes file called `data/release-notes/<PRODUCT>/<RELEASE NUMBER>/PLACEHOLDER.yml`. For example `data/release-notes/enterprise-server/3-1/PLACEHOLDER.yml`. Add the following placeholder content to the file:
``` ```
date: '2021-05-04' date: '2021-05-04'
@@ -55,6 +55,8 @@ If you aren't comfortable going through the steps alone, sync up with a docs eng
script/enterprise-server-releases/release-banner.js --action create --version <PLAN@RELEASE> script/enterprise-server-releases/release-banner.js --action create --version <PLAN@RELEASE>
``` ```
- [ ] Create a PR with the above changes. This PR is used to track all docs changes and smoke tests associated with the release. For example https://github.com/github/docs-internal/pull/22286.
### When the `docs-internal` release branch is open ### When the `docs-internal` release branch is open
- [ ] Add a label to the PR in this format: - [ ] Add a label to the PR in this format:
@@ -102,7 +104,7 @@ This file should be automatically updated, but you can also run `script/update-e
Usually, we should smoke test any new GHES admin guides, any large features landing in this GHES version for the first time, and the REST and GraphQL API references. Usually, we should smoke test any new GHES admin guides, any large features landing in this GHES version for the first time, and the REST and GraphQL API references.
- [ ] Alert the Neon Squad (formally docs-ecosystem team) 1-2 days before the release to deploy to `github/github`. A PR should already be open in `github/github`, to change `published` to `true` in `app/api/description/config/releases/ghes-<NEXT RELEASE NUMBER>.yaml`. They will need to: - [ ] Alert the Neon Squad (formally docs-ecosystem team) 1-2 days before the release to deploy to `github/github`. A PR should already be open in `github/github`, to change `published` to `true` in `app/api/description/config/releases/ghes-<NEXT RELEASE NUMBER>.yaml`. They will need to:
- [ ] Get the required approval from `@github/ecosystem-api-reviewers` then deploy the PR to dotcom. This process generally takes 30-90 minutes. - [ ] Get the required approval from `@github/ecosystem-api-reviewers` then deploy the PR to dotcom. This process generally takes 30-90 minutes.
- [ ] Once the PR merges, make sure that the auto-generated PR titled "Update OpenAPI Descriptions" in doc-internal contains both the derefrenced and decorated JSON files for the new GHES release. If everything looks good, merge the "Update OpenAPI Description" PR into the GHES release megabranch. - [ ] Once the PR merges, make sure that the auto-generated PR titled "Update OpenAPI Descriptions" in doc-internal contains both the derefrenced and decorated JSON files for the new GHES release. If everything looks good, merge the "Update OpenAPI Description" PR into the GHES release megabranch. **Note:** Be careful about resolving the conflicts correctly—you may wish to delete the existing OpenAPI files for the release version from the megabranch, so there are no conflicts to resolve and to ensure that the incoming artifacts are the correct ones.
- [ ] Add a blocking review to the auto-generated "Update OpenAPI Descriptions" PR in the public REST API description. (Remove this blocking review once the GHES release ships.) - [ ] Add a blocking review to the auto-generated "Update OpenAPI Descriptions" PR in the public REST API description. (Remove this blocking review once the GHES release ships.)
- [ ] [Freeze the repos](https://github.com/github/docs-content/blob/main/docs-content-docs/docs-content-workflows/freezing.md) at least 1-2 days before the release, and post an announcement in Slack so everybody knows. - [ ] [Freeze the repos](https://github.com/github/docs-content/blob/main/docs-content-docs/docs-content-workflows/freezing.md) at least 1-2 days before the release, and post an announcement in Slack so everybody knows.
@@ -113,8 +115,9 @@ This file should be automatically updated, but you can also run `script/update-e
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. 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.
- [ ] Do any required smoke tests listed in the opening post in the megabranch PR. - [ ] Do any required smoke tests listed in the opening post in the megabranch PR.
- [ ] Push the search index LFS objects for the public `github/docs` repo. The LFS objects were already being pushed for the internal repo after the `sync-english-index-for-<PLAN@RELEASE>` was added to the megabranch. To push the LFS objects, run the [search sync workflow](https://github.com/github/docs-internal/actions/workflows/sync-search-indices.yml) with the following inputs: - [ ] 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.
- [ ] After unfreezing, push the search index LFS objects for the public `github/docs` repo. The LFS objects were already being pushed for the internal repo after the `sync-english-index-for-<PLAN@RELEASE>` was added to the megabranch. To push the LFS objects, run the [search sync workflow](https://github.com/github/docs-internal/actions/workflows/sync-search-indices.yml) with the following inputs:
version: `enterprise-server@<RELEASE>` version: `enterprise-server@<RELEASE>`
language: `en` language: `en`
- [ ] 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. - [ ] After unfreezing, if there were significant or highlighted GraphQL changes in the release, consider manually running the [GraphQL update workflow](https://github.com/github/docs-internal/actions/workflows/update-graphql-files.yml) to update our GraphQL schemas. By default this workflow only runs once every 24 hours.
- [ ] After the release, in the `docs-content` repo, add the now live version number to the "Specific GHES version(s)" section in the following files: [`.github/ISSUE_TEMPLATE/release-tier-1-or-2-tracking.yml`](https://github.com/github/docs-content/blob/main/.github/ISSUE_TEMPLATE/release-tier-1-or-2-tracking.yml) and [`.github/ISSUE_TEMPLATE/release-tier-3-or-tier-4.yml`](https://github.com/github/docs-content/blob/main/.github/ISSUE_TEMPLATE/release-tier-3-or-tier-4.yml). When the PR is approved, merge it in. - [ ] After the release, in the `docs-content` repo, add the now live version number to the "Specific GHES version(s)" section in the following files: [`.github/ISSUE_TEMPLATE/release-tier-1-or-2-tracking.yml`](https://github.com/github/docs-content/blob/main/.github/ISSUE_TEMPLATE/release-tier-1-or-2-tracking.yml) and [`.github/ISSUE_TEMPLATE/release-tier-3-or-tier-4.yml`](https://github.com/github/docs-content/blob/main/.github/ISSUE_TEMPLATE/release-tier-3-or-tier-4.yml). When the PR is approved, merge it in.

View File

@@ -120,7 +120,7 @@ async function run() {
const featureID = findFieldID('Feature', data) const featureID = findFieldID('Feature', data)
const contributorTypeID = findFieldID('Contributor type', data) const contributorTypeID = findFieldID('Contributor type', data)
const sizeTypeID = findFieldID('Size', data) const sizeTypeID = findFieldID('Size', data)
const authorID = findFieldID('Author', data) const authorID = findFieldID('Contributor', data)
// Get the ID of the single select values that we want to set // Get the ID of the single select values that we want to set
const readyForReviewID = findSingleSelectID('Ready for review', 'Status', data) const readyForReviewID = findSingleSelectID('Ready for review', 'Status', data)

51
.github/actions-scripts/prod-deploy.js vendored Executable file
View File

@@ -0,0 +1,51 @@
#!/usr/bin/env node
import getOctokit from '../../script/helpers/github.js'
import deployToProduction from '../../script/deployment/deploy-to-production.js'
const {
GITHUB_TOKEN,
HEROKU_API_TOKEN,
HEROKU_PRODUCTION_APP_NAME,
SOURCE_BLOB_URL,
DELAY_FOR_PREBOOT,
RUN_ID,
} = process.env
// Exit if GitHub Actions PAT is not found
if (!GITHUB_TOKEN) {
throw new Error('You must supply a GITHUB_TOKEN environment variable!')
}
// Exit if Heroku API token is not found
if (!HEROKU_API_TOKEN) {
throw new Error('You must supply a HEROKU_API_TOKEN environment variable!')
}
// Exit if Heroku App name is not found
if (!HEROKU_PRODUCTION_APP_NAME) {
throw new Error('You must supply a HEROKU_PRODUCTION_APP_NAME environment variable!')
}
if (!RUN_ID) {
throw new Error('$RUN_ID not set')
}
// This helper uses the `GITHUB_TOKEN` implicitly!
// We're using our usual version of Octokit vs. the provided `github`
// instance to avoid versioning discrepancies.
const octokit = getOctokit()
try {
await deployToProduction({
octokit,
includeDelayForPreboot: DELAY_FOR_PREBOOT !== 'false',
// These parameters will ONLY be set by Actions
sourceBlobUrl: SOURCE_BLOB_URL,
runId: RUN_ID,
})
} catch (error) {
console.error(`Failed to deploy to production: ${error.message}`)
console.error(error)
throw error
}

View File

@@ -0,0 +1,11 @@
#!/usr/bin/env node
import purgeEdgeCache from '../../script/deployment/purge-edge-cache.js'
try {
await purgeEdgeCache()
} catch (error) {
console.error(`Failed to purge the edge cache: ${error.message}`)
console.error(error)
throw error
}

View File

@@ -60,7 +60,7 @@ async function run() {
const featureID = findFieldID('Feature', data) const featureID = findFieldID('Feature', data)
const contributorTypeID = findFieldID('Contributor type', data) const contributorTypeID = findFieldID('Contributor type', data)
const sizeTypeID = findFieldID('Size', data) const sizeTypeID = findFieldID('Size', data)
const authorID = findFieldID('Author', data) const authorID = findFieldID('Contributor', data)
// Get the ID of the single select values that we want to set // Get the ID of the single select values that we want to set
const readyForReviewID = findSingleSelectID('Ready for review', 'Status', data) const readyForReviewID = findSingleSelectID('Ready for review', 'Status', data)

74
.github/actions-scripts/staging-deploy.js vendored Executable file
View File

@@ -0,0 +1,74 @@
#!/usr/bin/env node
import parsePrUrl from '../../script/deployment/parse-pr-url.js'
import getOctokit from '../../script/helpers/github.js'
import deployToStaging from '../../script/deployment/deploy-to-staging.js'
const { GITHUB_TOKEN, HEROKU_API_TOKEN } = process.env
// Exit if GitHub Actions PAT is not found
if (!GITHUB_TOKEN) {
throw new Error('You must supply a GITHUB_TOKEN environment variable!')
}
// Exit if Heroku API token is not found
if (!HEROKU_API_TOKEN) {
throw new Error('You must supply a HEROKU_API_TOKEN environment variable!')
}
// This helper uses the `GITHUB_TOKEN` implicitly!
// We're using our usual version of Octokit vs. the provided `github`
// instance to avoid versioning discrepancies.
const octokit = getOctokit()
const { RUN_ID, PR_URL, SOURCE_BLOB_URL, CONTEXT_NAME, ACTIONS_RUN_LOG, HEAD_SHA } = process.env
if (!RUN_ID) {
throw new Error('$RUN_ID not set')
}
if (!PR_URL) {
throw new Error('$PR_URL not set')
}
if (!SOURCE_BLOB_URL) {
throw new Error('$SOURCE_BLOB_URL not set')
}
if (!CONTEXT_NAME) {
throw new Error('$CONTEXT_NAME not set')
}
if (!ACTIONS_RUN_LOG) {
throw new Error('$ACTIONS_RUN_LOG not set')
}
if (!HEAD_SHA) {
throw new Error('$HEAD_SHA not set')
}
const { owner, repo, pullNumber } = parsePrUrl(PR_URL)
if (!owner || !repo || !pullNumber) {
throw new Error(
`'pullRequestUrl' input must match URL format 'https://github.com/github/(docs|docs-internal)/pull/123' but was '${PR_URL}'`
)
}
const { data: pullRequest } = await octokit.pulls.get({
owner,
repo,
pull_number: pullNumber,
})
await deployToStaging({
octokit,
pullRequest,
forceRebuild: false,
// These parameters will ONLY be set by Actions
sourceBlobUrl: SOURCE_BLOB_URL,
runId: RUN_ID,
})
await octokit.repos.createCommitStatus({
owner,
repo,
sha: HEAD_SHA,
context: CONTEXT_NAME,
state: 'success',
description: 'Successfully deployed! See logs.',
target_url: ACTIONS_RUN_LOG,
})

50
.github/actions-scripts/staging-undeploy.js vendored Executable file
View File

@@ -0,0 +1,50 @@
#!/usr/bin/env node
import parsePrUrl from '../../script/deployment/parse-pr-url.js'
import getOctokit from '../../script/helpers/github.js'
import undeployFromStaging from '../../script/deployment/undeploy-from-staging.js'
const { GITHUB_TOKEN, HEROKU_API_TOKEN } = process.env
// Exit if GitHub Actions PAT is not found
if (!GITHUB_TOKEN) {
throw new Error('You must supply a GITHUB_TOKEN environment variable!')
}
// Exit if Heroku API token is not found
if (!HEROKU_API_TOKEN) {
throw new Error('You must supply a HEROKU_API_TOKEN environment variable!')
}
// This helper uses the `GITHUB_TOKEN` implicitly!
// We're using our usual version of Octokit vs. the provided `github`
// instance to avoid versioning discrepancies.
const octokit = getOctokit()
const { RUN_ID, PR_URL } = process.env
if (!RUN_ID) {
throw new Error('$RUN_ID not set')
}
if (!PR_URL) {
throw new Error('$PR_URL not set')
}
const { owner, repo, pullNumber } = parsePrUrl(PR_URL)
if (!owner || !repo || !pullNumber) {
throw new Error(
`'pullRequestUrl' input must match URL format 'https://github.com/github/(docs|docs-internal)/pull/123' but was '${PR_URL}'`
)
}
const { data: pullRequest } = await octokit.pulls.get({
owner,
repo,
pull_number: pullNumber,
})
await undeployFromStaging({
octokit,
pullRequest: pullRequest,
runId: RUN_ID,
})

View File

@@ -5,10 +5,10 @@
export default [ export default [
'actions/cache@c64c572235d810460d0d6876e9c705ad5002b353', // v2.1.6 'actions/cache@c64c572235d810460d0d6876e9c705ad5002b353', // v2.1.6
'actions/checkout@1e204e9a9253d643386038d443f96446fa156a97', // v2.3.5 'actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579', // v2.4.0
'actions/github-script@2b34a689ec86a68d8ab9478298f91d5401337b7d', // v4.0.2 'actions/github-script@2b34a689ec86a68d8ab9478298f91d5401337b7d', // v4.0.2
'actions/labeler@5f867a63be70efff62b767459b009290364495eb', // v2.2.0 'actions/labeler@5f867a63be70efff62b767459b009290364495eb', // v2.2.0
'actions/setup-node@270253e841af726300e85d718a5f606959b2903c', // v2.4.1 'actions/setup-node@04c56d2f954f1e4c69436aa54cfef261a018f458', // v2.5.0
'actions/stale@cdf15f641adb27a71842045a94023bef6945e3aa', // v4.0.0 'actions/stale@cdf15f641adb27a71842045a94023bef6945e3aa', // v4.0.0
'actions/upload-artifact@27121b0bdffd731efa15d66772be8dc71245d074', // v2.2.4 'actions/upload-artifact@27121b0bdffd731efa15d66772be8dc71245d074', // v2.2.4
'alex-page/github-project-automation-plus@bb266ff4dde9242060e2d5418e120a133586d488', // v0.8.1 'alex-page/github-project-automation-plus@bb266ff4dde9242060e2d5418e120a133586d488', // v0.8.1

View File

@@ -23,5 +23,5 @@ jobs:
only-labels: 'engineering,Triaged,Improve existing docs,Core,Ecosystem' only-labels: 'engineering,Triaged,Improve existing docs,Core,Ecosystem'
stale-issue-label: 'stale' stale-issue-label: 'stale'
stale-pr-label: 'stale' stale-pr-label: 'stale'
exempt-pr-labels: 'never-stale' exempt-pr-labels: 'never-stale,waiting for review'
exempt-issue-labels: 'never-stale,help wanted,waiting for review' exempt-issue-labels: 'never-stale,help wanted,waiting for review'

View File

@@ -31,10 +31,10 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Check out repo content - name: Check out repo content
uses: actions/checkout@1e204e9a9253d643386038d443f96446fa156a97 uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
- name: Setup Node - name: Setup Node
uses: actions/setup-node@270253e841af726300e85d718a5f606959b2903c uses: actions/setup-node@04c56d2f954f1e4c69436aa54cfef261a018f458
with: with:
node-version: 16.13.x node-version: 16.13.x
cache: npm cache: npm

View File

@@ -10,6 +10,17 @@ on:
branches: branches:
- main - main
pull_request: pull_request:
paths:
- '**.js'
- '**.mjs'
- '**.ts'
- '**.tsx'
- jest.config.js
- package.json
# In case something like eslint or tsc or prettier upgrades
- package-lock.json
# Ultimately, for debugging this workflow itself
- .github/workflows/browser-test.yml
jobs: jobs:
build: build:
@@ -18,19 +29,24 @@ jobs:
# Each of these ifs needs to be repeated at each step to make sure the required check still runs # Each of these ifs needs to be repeated at each step to make sure the required check still runs
# Even if if doesn't do anything # Even if if doesn't do anything
- name: Checkout - name: Checkout
uses: actions/checkout@1e204e9a9253d643386038d443f96446fa156a97 uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
with: with:
lfs: true lfs: true
- name: Checkout LFS objects - name: Checkout LFS objects
run: git lfs checkout run: git lfs checkout
- name: Setup Node - name: Setup Node
uses: actions/setup-node@270253e841af726300e85d718a5f606959b2903c uses: actions/setup-node@04c56d2f954f1e4c69436aa54cfef261a018f458
with: with:
node-version: 16.13.x node-version: 16.13.x
cache: npm cache: npm
- name: Install dependencies - name: Install dependencies
env:
# This makes it so the puppeteer npm package doesn't bother
# to download a copy of chromium because it can use
# `$PUPPETEER_EXECUTABLE_PATH` from the ubuntu Action container.
PUPPETEER_SKIP_CHROMIUM_DOWNLOAD: true
run: npm ci --include=optional run: npm ci --include=optional
- name: Run browser-test - name: Run browser-test

View File

@@ -30,6 +30,6 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Check out repo - name: Check out repo
uses: actions/checkout@1e204e9a9253d643386038d443f96446fa156a97 uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
- name: Build the container - name: Build the container
run: docker build --target production . run: docker build --target production .

View File

@@ -22,9 +22,9 @@ jobs:
REPORT_REPOSITORY: github/docs-content REPORT_REPOSITORY: github/docs-content
steps: steps:
- name: Check out repo's default branch - name: Check out repo's default branch
uses: actions/checkout@1e204e9a9253d643386038d443f96446fa156a97 uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
- name: Setup Node - name: Setup Node
uses: actions/setup-node@270253e841af726300e85d718a5f606959b2903c uses: actions/setup-node@04c56d2f954f1e4c69436aa54cfef261a018f458
with: with:
node-version: 16.13.x node-version: 16.13.x
cache: npm cache: npm

View File

@@ -36,10 +36,10 @@ jobs:
exit 1 # prevents further steps from running exit 1 # prevents further steps from running
- name: Checkout - name: Checkout
uses: actions/checkout@1e204e9a9253d643386038d443f96446fa156a97 uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
- name: Setup Node - name: Setup Node
uses: actions/setup-node@270253e841af726300e85d718a5f606959b2903c uses: actions/setup-node@04c56d2f954f1e4c69436aa54cfef261a018f458
with: with:
node-version: 16.13.x node-version: 16.13.x
cache: npm cache: npm

View File

@@ -20,7 +20,7 @@ jobs:
if: github.repository == 'github/docs-internal' || github.repository == 'github/docs' if: github.repository == 'github/docs-internal' || github.repository == 'github/docs'
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@1e204e9a9253d643386038d443f96446fa156a97 - uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
- uses: github/codeql-action/init@v1 - uses: github/codeql-action/init@v1
with: with:
languages: javascript # comma separated list of values from {go, python, javascript, java, cpp, csharp} (not YET ruby, sorry!) languages: javascript # comma separated list of values from {go, python, javascript, java, cpp, csharp} (not YET ruby, sorry!)

View File

@@ -11,6 +11,7 @@ on:
jobs: jobs:
PR-Preview-Links: PR-Preview-Links:
if: github.event.pull_request.user.login != 'Octomerger'
name: Add staging/live links to PR name: Add staging/live links to PR
runs-on: ubuntu-latest runs-on: ubuntu-latest
outputs: outputs:
@@ -38,10 +39,10 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: check out repo content - name: check out repo content
uses: actions/checkout@1e204e9a9253d643386038d443f96446fa156a97 uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
- name: Setup Node - name: Setup Node
uses: actions/setup-node@270253e841af726300e85d718a5f606959b2903c uses: actions/setup-node@04c56d2f954f1e4c69436aa54cfef261a018f458
with: with:
node-version: 16.13.x node-version: 16.13.x
cache: npm cache: npm
@@ -49,57 +50,12 @@ jobs:
- name: Install temporary dependencies - name: Install temporary dependencies
run: | run: |
npm install --no-save github-slugger npm install --no-save github-slugger
npm install --no-save --include=optional esm
- name: Get changes table - name: Get changes table
uses: actions/github-script@2b34a689ec86a68d8ab9478298f91d5401337b7d
id: changes id: changes
env: env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with: run: .github/actions-scripts/content-changes-table-comment.js
script: |
// Workaround to allow us to load ESM files with `require(...)`
const esm = require('esm')
require = esm({})
const { default: createStagingAppName } = require('./script/deployment/create-staging-app-name')
const stagingPrefix = createStagingAppName({
repo: context.payload.repository.name,
pullNumber: context.payload.number,
branch: context.payload.pull_request.head.ref,
})
const response = await github.repos.compareCommits({
owner: context.repo.owner,
repo: context.repo.repo,
base: context.payload.pull_request.base.sha,
head: context.payload.pull_request.head.sha
})
const files = response.data.files
let markdownTable = '| **Source** | **Staging** | **Production** | **What Changed** |\n|:----------- |:----------- |:----------- |:----------- |\n'
const pathPrefix = 'content/'
const articleFiles = files.filter(({ filename }) => filename.startsWith(pathPrefix) && !filename.endsWith('/index.md'))
for (const file of articleFiles) {
const sourceUrl = file.blob_url
const fileName = file.filename.slice(pathPrefix.length)
const fileUrl = fileName.slice(0, fileName.lastIndexOf('.'))
const stagingLink = `https://${stagingPrefix}.herokuapp.com/${fileUrl}`
const productionLink = `https://docs.github.com/${fileUrl}`
let markdownLine = ''
if (file.status === 'modified') {
markdownLine = `| [content/${fileName}](${sourceUrl}) | [Modified](${stagingLink}) | [Original](${productionLink}) | |\n`
} else if (file.status === 'added') {
markdownLine = `| New file: [content/${fileName}](${sourceUrl}) | [Modified](${stagingLink}) | | |\n`
}
markdownTable += markdownLine
}
core.setOutput('changesTable', markdownTable)
- name: Find content directory changes comment - name: Find content directory changes comment
uses: peter-evans/find-comment@d2dae40ed151c634e4189471272b57e76ec19ba8 uses: peter-evans/find-comment@d2dae40ed151c634e4189471272b57e76ec19ba8

View File

@@ -25,14 +25,22 @@ jobs:
max-parallel: 1 max-parallel: 1
matrix: matrix:
include: include:
- language: pt-BR - language: pt
language_code: pt crowdin_language: pt-BR
# - language: zh-CN language_dir: translations/pt-BR
# language_code: cn
# - language: ja-JP - language: es
# language_code: ja crowdin_language: es-ES
# - language: es-ES language_dir: translations/es-ES
# language_code: es
- language: cn
crowdin_language: zh-CN
language_dir: translations/zh-CN
- language_dir: translations/ja-JP
crowdin_language: ja
language: ja
steps: steps:
- name: Set branch name - name: Set branch name
id: set-branch id: set-branch
@@ -43,7 +51,7 @@ jobs:
- run: git config --global user.email "67483024+docubot@users.noreply.github.com" - run: git config --global user.email "67483024+docubot@users.noreply.github.com"
- name: Checkout - name: Checkout
uses: actions/checkout@1e204e9a9253d643386038d443f96446fa156a97 uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
with: with:
fetch-depth: 0 fetch-depth: 0
lfs: true lfs: true
@@ -72,11 +80,11 @@ jobs:
- name: Remove all language translations - name: Remove all language translations
run: | run: |
git rm -rf --quiet translations/${{ matrix.language }}/content git rm -rf --quiet ${{ matrix.language_dir }}/content
git rm -rf --quiet translations/${{ matrix.language }}/data git rm -rf --quiet ${{ matrix.language_dir }}/data
- name: Download crowdin translations - name: Download crowdin translations
run: crowdin download --no-progress --no-colors --verbose --debug '--branch=main' '--config=crowdin.yml' --language=${{ matrix.language }} run: crowdin download --no-progress --no-colors --verbose --debug '--branch=main' '--config=crowdin.yml' --language=${{ matrix.crowdin_language }}
env: env:
# This is a numeric id, not to be confused with Crowdin API v1 "project identifier" string # This is a numeric id, not to be confused with Crowdin API v1 "project identifier" string
# See "API v2" on https://crowdin.com/project/<your-project>/settings#api # See "API v2" on https://crowdin.com/project/<your-project>/settings#api
@@ -89,52 +97,59 @@ jobs:
- name: Commit crowdin sync - name: Commit crowdin sync
run: | run: |
git add . git add ${{ matrix.language_dir }}
git commit -m "Add crowdin translations" || echo "Nothing to commit" git commit -m "Add crowdin translations" || echo "Nothing to commit"
- name: 'Setup node' - name: 'Setup node'
uses: actions/setup-node@270253e841af726300e85d718a5f606959b2903c uses: actions/setup-node@04c56d2f954f1e4c69436aa54cfef261a018f458
with: with:
node-version: '16' node-version: '16'
- run: npm ci - run: npm ci
- name: Reset files with broken liquid tags
run: |
node script/i18n/reset-files-with-broken-liquid-tags.js --language=${{ matrix.language_code }}
git add . && git commit -m "run script/i18n/reset-files-with-broken-liquid-tags.js --language=${{ matrix.language_code }}" || echo "Nothing to commit"
# step 5 in docs-engineering/crowdin.md using script from docs-internal#22709
- name: Reset known broken files
run: |
node script/i18n/reset-known-broken-translation-files.js
git add . && git commit -m "run script/i18n/reset-known-broken-translation-files.js" || echo "Nothing to commit"
env:
GITHUB_TOKEN: ${{ secrets.DOCUBOT_REPO_PAT }}
# step 6 in docs-engineering/crowdin.md # step 6 in docs-engineering/crowdin.md
- name: Homogenize frontmatter - name: Homogenize frontmatter
run: | run: |
node script/i18n/homogenize-frontmatter.js node script/i18n/homogenize-frontmatter.js
git add . && git commit -m "Run script/i18n/homogenize-frontmatter.js" || echo "Nothing to commit" git add ${{ matrix.language_dir }} && git commit -m "Run script/i18n/homogenize-frontmatter.js" || echo "Nothing to commit"
# step 7 in docs-engineering/crowdin.md # step 7 in docs-engineering/crowdin.md
- name: Fix translation errors - name: Fix translation errors
run: | run: |
node script/i18n/fix-translation-errors.js node script/i18n/fix-translation-errors.js
git add . && git commit -m "Run script/i18n/fix-translation-errors.js" || echo "Nothing to commit" git add ${{ matrix.language_dir }} && git commit -m "Run script/i18n/fix-translation-errors.js" || echo "Nothing to commit"
# step 8a in docs-engineering/crowdin.md # step 8a in docs-engineering/crowdin.md
- name: Check parsing - name: Check parsing
run: | run: |
node script/i18n/lint-translation-files.js --check parsing node script/i18n/lint-translation-files.js --check parsing | tee -a /tmp/batch.log | cat
git add . && git commit -m "Run script/i18n/lint-translation-files.js --check parsing" || echo "Nothing to commit" git add ${{ matrix.language_dir }} && git commit -m "Run script/i18n/lint-translation-files.js --check parsing" || echo "Nothing to commit"
# step 8b in docs-engineering/crowdin.md # step 8b in docs-engineering/crowdin.md
- name: Check rendering - name: Check rendering
run: | run: |
node script/i18n/lint-translation-files.js --check rendering node script/i18n/lint-translation-files.js --check rendering | tee -a /tmp/batch.log | cat
git add . && git commit -m "Run script/i18n/lint-translation-files.js --check rendering" || echo "Nothing to commit" git add ${{ matrix.language_dir }} && git commit -m "Run script/i18n/lint-translation-files.js --check rendering" || echo "Nothing to commit"
- name: Reset files with broken liquid tags
run: |
node script/i18n/reset-files-with-broken-liquid-tags.js --language=${{ matrix.language }} | tee -a /tmp/batch.log | cat
git add ${{ matrix.language_dir }} && git commit -m "run script/i18n/reset-files-with-broken-liquid-tags.js --language=${{ matrix.language }}" || echo "Nothing to commit"
# step 5 in docs-engineering/crowdin.md using script from docs-internal#22709
- name: Reset known broken files
run: |
node script/i18n/reset-known-broken-translation-files.js | tee -a /tmp/batch.log | cat
git add ${{ matrix.language_dir }} && git commit -m "run script/i18n/reset-known-broken-translation-files.js" || echo "Nothing to commit"
env:
GITHUB_TOKEN: ${{ secrets.DOCUBOT_REPO_PAT }}
- name: Check in CSV report
run: |
mkdir -p translations/log
csvFile=translations/log/${{ matrix.language }}-resets.csv
script/i18n/report-reset-files.js --report-type=csv --language=${{ matrix.language }} --log-file=/tmp/batch.log > $csvFile
git add -f $csvFile && git commit -m "Check in ${{ matrix.language }} CSV report" || echo "Nothing to commit"
- name: Create Pull Request - name: Create Pull Request
env: env:
@@ -142,11 +157,13 @@ jobs:
# We'll try to create the pull request based on the changes we pushed up in the branch. # We'll try to create the pull request based on the changes we pushed up in the branch.
# If there are actually no differences between the branch and `main`, we'll delete it. # If there are actually no differences between the branch and `main`, we'll delete it.
run: | run: |
script/i18n/report-reset-files.js --report-type=pull-request-body --language=${{ matrix.language }} --log-file=/tmp/batch.log > /tmp/pr-body.txt
git push origin ${{ steps.set-branch.outputs.BRANCH_NAME }} git push origin ${{ steps.set-branch.outputs.BRANCH_NAME }}
gh pr create -t "New translation batch for ${{ matrix.language }}" \ gh pr create --title "New translation batch for ${{ matrix.language }}" \
--base=main \ --base=main \
--head=${{ steps.set-branch.outputs.BRANCH_NAME }} \ --head=${{ steps.set-branch.outputs.BRANCH_NAME }} \
-b "New batch for ${{ matrix.language }} created by [this workflow]($GITHUB_SERVER_URL/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID)" || git push origin :${{ steps.set-branch.outputs.BRANCH_NAME }} --body-file /tmp/pr-body.txt || git push origin :${{ steps.set-branch.outputs.BRANCH_NAME }} \
--label "translation-batch"
# When the maximum execution time is reached for this job, Actions cancels the workflow run. # When the maximum execution time is reached for this job, Actions cancels the workflow run.
# This emits a notification for the first responder to triage. # This emits a notification for the first responder to triage.

View File

@@ -18,10 +18,10 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@1e204e9a9253d643386038d443f96446fa156a97 uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
- name: Setup Node - name: Setup Node
uses: actions/setup-node@270253e841af726300e85d718a5f606959b2903c uses: actions/setup-node@04c56d2f954f1e4c69436aa54cfef261a018f458
with: with:
node-version: 16.13.x node-version: 16.13.x
cache: npm cache: npm

View File

@@ -19,7 +19,7 @@ jobs:
timeout-minutes: 300 timeout-minutes: 300
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@1e204e9a9253d643386038d443f96446fa156a97 uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
with: with:
fetch-depth: 0 fetch-depth: 0
lfs: true lfs: true

View File

@@ -20,10 +20,10 @@ jobs:
steps: steps:
- name: Check out repo content - name: Check out repo content
uses: actions/checkout@1e204e9a9253d643386038d443f96446fa156a97 uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
- name: Setup Node - name: Setup Node
uses: actions/setup-node@270253e841af726300e85d718a5f606959b2903c uses: actions/setup-node@04c56d2f954f1e4c69436aa54cfef261a018f458
with: with:
node-version: 16.13.x node-version: 16.13.x
cache: npm cache: npm

View File

@@ -32,10 +32,10 @@ jobs:
exit 1 # prevents further steps from running exit 1 # prevents further steps from running
- name: Checkout repository code - name: Checkout repository code
uses: actions/checkout@1e204e9a9253d643386038d443f96446fa156a97 uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
- name: Setup Node - name: Setup Node
uses: actions/setup-node@270253e841af726300e85d718a5f606959b2903c uses: actions/setup-node@04c56d2f954f1e4c69436aa54cfef261a018f458
with: with:
node-version: 16.13.x node-version: 16.13.x
cache: npm cache: npm

View File

@@ -36,13 +36,13 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: checkout - name: checkout
uses: actions/checkout@1e204e9a9253d643386038d443f96446fa156a97 uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
with: with:
ref: ${{ github.head_ref }} ref: ${{ github.head_ref }}
token: ${{ secrets.DOCUBOT_REPO_PAT }} token: ${{ secrets.DOCUBOT_REPO_PAT }}
- name: Setup Node - name: Setup Node
uses: actions/setup-node@270253e841af726300e85d718a5f606959b2903c uses: actions/setup-node@04c56d2f954f1e4c69436aa54cfef261a018f458
with: with:
node-version: 16.13.x node-version: 16.13.x
cache: npm cache: npm

View File

@@ -40,7 +40,7 @@ jobs:
) )
const logins = teamMembers.data.map(member => member.login) const logins = teamMembers.data.map(member => member.login)
// ignore PRs opened by docs bot accounts // ignore PRs opened by docs bot accounts
logins.push('Octomerger', 'octoglot') logins.push('Octomerger', 'octoglot', 'docubot')
if (logins.some(login => login === updatedIssueInformation.data.user.login)) { if (logins.some(login => login === updatedIssueInformation.data.user.login)) {
console.log(`This issue or pull request was authored by a member of the github/docs team.`) console.log(`This issue or pull request was authored by a member of the github/docs team.`)
return 'true' return 'true'

View File

@@ -25,10 +25,10 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Check out repo - name: Check out repo
uses: actions/checkout@1e204e9a9253d643386038d443f96446fa156a97 uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
- name: Setup node - name: Setup node
uses: actions/setup-node@270253e841af726300e85d718a5f606959b2903c uses: actions/setup-node@04c56d2f954f1e4c69436aa54cfef261a018f458
with: with:
node-version: 16.13.x node-version: 16.13.x
cache: npm cache: npm

View File

@@ -18,10 +18,10 @@ jobs:
# Each of these ifs needs to be repeated at each step to make sure the required check still runs # Each of these ifs needs to be repeated at each step to make sure the required check still runs
# Even if if doesn't do anything # Even if if doesn't do anything
- name: Checkout - name: Checkout
uses: actions/checkout@1e204e9a9253d643386038d443f96446fa156a97 uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
- name: Setup node - name: Setup node
uses: actions/setup-node@270253e841af726300e85d718a5f606959b2903c uses: actions/setup-node@04c56d2f954f1e4c69436aa54cfef261a018f458
with: with:
node-version: 16.13.x node-version: 16.13.x
cache: npm cache: npm

View File

@@ -18,10 +18,10 @@ jobs:
# Each of these ifs needs to be repeated at each step to make sure the required check still runs # Each of these ifs needs to be repeated at each step to make sure the required check still runs
# Even if if doesn't do anything # Even if if doesn't do anything
- name: Checkout - name: Checkout
uses: actions/checkout@1e204e9a9253d643386038d443f96446fa156a97 uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
- name: Setup node - name: Setup node
uses: actions/setup-node@270253e841af726300e85d718a5f606959b2903c uses: actions/setup-node@04c56d2f954f1e4c69436aa54cfef261a018f458
with: with:
node-version: 16.13.x node-version: 16.13.x
cache: npm cache: npm

View File

@@ -16,10 +16,10 @@ jobs:
runs-on: ${{ fromJSON('["ubuntu-latest", "self-hosted"]')[github.repository == 'github/docs-internal'] }} runs-on: ${{ fromJSON('["ubuntu-latest", "self-hosted"]')[github.repository == 'github/docs-internal'] }}
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@1e204e9a9253d643386038d443f96446fa156a97 uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
- name: Setup node - name: Setup node
uses: actions/setup-node@270253e841af726300e85d718a5f606959b2903c uses: actions/setup-node@04c56d2f954f1e4c69436aa54cfef261a018f458
with: with:
node-version: 16.13.x node-version: 16.13.x
cache: npm cache: npm

View File

@@ -18,10 +18,10 @@ jobs:
# Each of these ifs needs to be repeated at each step to make sure the required check still runs # Each of these ifs needs to be repeated at each step to make sure the required check still runs
# Even if if doesn't do anything # Even if if doesn't do anything
- name: Checkout - name: Checkout
uses: actions/checkout@1e204e9a9253d643386038d443f96446fa156a97 uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
- name: Setup node - name: Setup node
uses: actions/setup-node@270253e841af726300e85d718a5f606959b2903c uses: actions/setup-node@04c56d2f954f1e4c69436aa54cfef261a018f458
with: with:
node-version: 16.13.x node-version: 16.13.x
cache: npm cache: npm

View File

@@ -16,10 +16,10 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout repository code - name: Checkout repository code
uses: actions/checkout@1e204e9a9253d643386038d443f96446fa156a97 uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
- name: Setup Node - name: Setup Node
uses: actions/setup-node@270253e841af726300e85d718a5f606959b2903c uses: actions/setup-node@04c56d2f954f1e4c69436aa54cfef261a018f458
with: with:
node-version: 16.13.x node-version: 16.13.x
cache: npm cache: npm

View File

@@ -26,10 +26,10 @@ jobs:
add-labels: 'github-openapi-bot' add-labels: 'github-openapi-bot'
- name: Checkout repository code - name: Checkout repository code
uses: actions/checkout@1e204e9a9253d643386038d443f96446fa156a97 uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
- name: Setup node - name: Setup node
uses: actions/setup-node@270253e841af726300e85d718a5f606959b2903c uses: actions/setup-node@04c56d2f954f1e4c69436aa54cfef261a018f458
with: with:
node-version: 16.13.x node-version: 16.13.x
cache: npm cache: npm

View File

@@ -29,10 +29,10 @@ jobs:
runs-on: ${{ fromJSON('["ubuntu-latest", "self-hosted"]')[github.repository == 'github/docs-internal'] }} runs-on: ${{ fromJSON('["ubuntu-latest", "self-hosted"]')[github.repository == 'github/docs-internal'] }}
steps: steps:
- name: Checkout repository code - name: Checkout repository code
uses: actions/checkout@1e204e9a9253d643386038d443f96446fa156a97 uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
- name: Setup node - name: Setup node
uses: actions/setup-node@270253e841af726300e85d718a5f606959b2903c uses: actions/setup-node@04c56d2f954f1e4c69436aa54cfef261a018f458
with: with:
node-version: 16.13.x node-version: 16.13.x
cache: npm cache: npm

View File

@@ -44,10 +44,10 @@ jobs:
exit 1 exit 1
- name: Check out repo content - name: Check out repo content
uses: actions/checkout@1e204e9a9253d643386038d443f96446fa156a97 uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
- name: Setup Node - name: Setup Node
uses: actions/setup-node@270253e841af726300e85d718a5f606959b2903c uses: actions/setup-node@04c56d2f954f1e4c69436aa54cfef261a018f458
with: with:
node-version: 16.x node-version: 16.x
cache: npm cache: npm

View File

@@ -14,10 +14,10 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Check out repo - name: Check out repo
uses: actions/checkout@1e204e9a9253d643386038d443f96446fa156a97 uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
- name: Setup Node - name: Setup Node
uses: actions/setup-node@270253e841af726300e85d718a5f606959b2903c uses: actions/setup-node@04c56d2f954f1e4c69436aa54cfef261a018f458
with: with:
node-version: 16.13.x node-version: 16.13.x
cache: npm cache: npm

View File

@@ -19,10 +19,10 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Check out repo - name: Check out repo
uses: actions/checkout@1e204e9a9253d643386038d443f96446fa156a97 uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
- name: Setup Node - name: Setup Node
uses: actions/setup-node@270253e841af726300e85d718a5f606959b2903c uses: actions/setup-node@04c56d2f954f1e4c69436aa54cfef261a018f458
with: with:
node-version: 16.x node-version: 16.x

View File

@@ -16,9 +16,9 @@ jobs:
env: env:
HEROKU_API_TOKEN: ${{ secrets.HEROKU_API_TOKEN }} HEROKU_API_TOKEN: ${{ secrets.HEROKU_API_TOKEN }}
steps: steps:
- uses: actions/checkout@1e204e9a9253d643386038d443f96446fa156a97 - uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
- name: Setup node - name: Setup node
uses: actions/setup-node@270253e841af726300e85d718a5f606959b2903c uses: actions/setup-node@04c56d2f954f1e4c69436aa54cfef261a018f458
with: with:
node-version: 16.13.x node-version: 16.13.x
cache: npm cache: npm

View File

@@ -25,7 +25,7 @@ jobs:
timeout-minutes: 15 timeout-minutes: 15
steps: steps:
- name: Check out repo - name: Check out repo
uses: actions/checkout@1e204e9a9253d643386038d443f96446fa156a97 uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
with: with:
persist-credentials: 'false' persist-credentials: 'false'
lfs: 'true' lfs: 'true'
@@ -34,7 +34,7 @@ jobs:
run: git lfs checkout run: git lfs checkout
- name: Setup node - name: Setup node
uses: actions/setup-node@270253e841af726300e85d718a5f606959b2903c uses: actions/setup-node@04c56d2f954f1e4c69436aa54cfef261a018f458
with: with:
node-version: 16.13.x node-version: 16.13.x
cache: npm cache: npm
@@ -129,12 +129,8 @@ jobs:
-H 'Content-Type:' \ -H 'Content-Type:' \
--data-binary @app.tar.gz --data-binary @app.tar.gz
- name: Install one-off development-only dependencies
run: npm install --no-save --include=optional esm
- name: Deploy - name: Deploy
id: deploy id: deploy
uses: actions/github-script@2b34a689ec86a68d8ab9478298f91d5401337b7d
env: env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
HEROKU_API_TOKEN: ${{ secrets.HEROKU_API_TOKEN }} HEROKU_API_TOKEN: ${{ secrets.HEROKU_API_TOKEN }}
@@ -144,56 +140,8 @@ jobs:
SOURCE_BLOB_URL: ${{ steps.build-source.outputs.download_url }} SOURCE_BLOB_URL: ${{ steps.build-source.outputs.download_url }}
DELAY_FOR_PREBOOT: 'true' DELAY_FOR_PREBOOT: 'true'
ALLOWED_POLLING_FAILURES_PER_PHASE: '15' ALLOWED_POLLING_FAILURES_PER_PHASE: '15'
with: RUN_ID: ${{ github.run_id }}
script: | run: .github/actions-scripts/prod-deploy.js
const {
GITHUB_TOKEN,
HEROKU_API_TOKEN,
HEROKU_PRODUCTION_APP_NAME,
SOURCE_BLOB_URL,
DELAY_FOR_PREBOOT
} = process.env
// Exit if GitHub Actions PAT is not found
if (!GITHUB_TOKEN) {
throw new Error('You must supply a GITHUB_TOKEN environment variable!')
}
// Exit if Heroku API token is not found
if (!HEROKU_API_TOKEN) {
throw new Error('You must supply a HEROKU_API_TOKEN environment variable!')
}
// Exit if Heroku App name is not found
if (!HEROKU_PRODUCTION_APP_NAME) {
throw new Error('You must supply a HEROKU_PRODUCTION_APP_NAME environment variable!')
}
// Workaround to allow us to load ESM files with `require(...)`
const esm = require('esm')
require = esm({})
const { default: getOctokit } = require('./script/helpers/github')
const { default: deployToProduction } = require('./script/deployment/deploy-to-production')
// This helper uses the `GITHUB_TOKEN` implicitly!
// We're using our usual version of Octokit vs. the provided `github`
// instance to avoid versioning discrepancies.
const octokit = getOctokit()
try {
await deployToProduction({
octokit,
includeDelayForPreboot: DELAY_FOR_PREBOOT !== 'false',
// These parameters will ONLY be set by Actions
sourceBlobUrl: SOURCE_BLOB_URL,
runId: context.runId
})
} catch (error) {
console.error(`Failed to deploy to production: ${error.message}`)
console.error(error)
throw error
}
- name: Mark the deployment as inactive if timed out - name: Mark the deployment as inactive if timed out
uses: actions/github-script@2b34a689ec86a68d8ab9478298f91d5401337b7d uses: actions/github-script@2b34a689ec86a68d8ab9478298f91d5401337b7d
@@ -227,26 +175,11 @@ jobs:
console.log('⏲️ Deployment status: error - The deployment timed out...') console.log('⏲️ Deployment status: error - The deployment timed out...')
- name: Purge Fastly edge cache - name: Purge Fastly edge cache
uses: actions/github-script@2b34a689ec86a68d8ab9478298f91d5401337b7d
env: env:
FASTLY_TOKEN: ${{ secrets.FASTLY_TOKEN }} FASTLY_TOKEN: ${{ secrets.FASTLY_TOKEN }}
FASTLY_SERVICE_ID: ${{ secrets.FASTLY_SERVICE_ID }} FASTLY_SERVICE_ID: ${{ secrets.FASTLY_SERVICE_ID }}
FASTLY_SURROGATE_KEY: 'all-the-things' FASTLY_SURROGATE_KEY: 'all-the-things'
with: run: .github/actions-scripts/purge-fastly-edge-cache.js
script: |
// Workaround to allow us to load ESM files with `require(...)`
const esm = require('esm')
require = esm({})
const { default: purgeEdgeCache } = require('./script/deployment/purge-edge-cache')
try {
await purgeEdgeCache()
} catch (error) {
console.error(`Failed to purge the edge cache: ${error.message}`)
console.error(error)
throw error
}
- name: Send Slack notification if workflow failed - name: Send Slack notification if workflow failed
uses: someimportantcompany/github-actions-slack-message@f8d28715e7b8a4717047d23f48c39827cacad340 uses: someimportantcompany/github-actions-slack-message@f8d28715e7b8a4717047d23f48c39827cacad340

View File

@@ -15,10 +15,10 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Check out repo content - name: Check out repo content
uses: actions/checkout@1e204e9a9253d643386038d443f96446fa156a97 uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
- name: Setup Node - name: Setup Node
uses: actions/setup-node@270253e841af726300e85d718a5f606959b2903c uses: actions/setup-node@04c56d2f954f1e4c69436aa54cfef261a018f458
with: with:
node-version: 16.13.x node-version: 16.13.x
cache: npm cache: npm

View File

@@ -24,10 +24,10 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Check out repo's default branch - name: Check out repo's default branch
uses: actions/checkout@1e204e9a9253d643386038d443f96446fa156a97 uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
- name: Setup Node - name: Setup Node
uses: actions/setup-node@270253e841af726300e85d718a5f606959b2903c uses: actions/setup-node@04c56d2f954f1e4c69436aa54cfef261a018f458
with: with:
node-version: 16.13.x node-version: 16.13.x
cache: npm cache: npm
@@ -46,10 +46,10 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Check out repo's default branch - name: Check out repo's default branch
uses: actions/checkout@1e204e9a9253d643386038d443f96446fa156a97 uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
- name: Setup Node - name: Setup Node
uses: actions/setup-node@270253e841af726300e85d718a5f606959b2903c uses: actions/setup-node@04c56d2f954f1e4c69436aa54cfef261a018f458
with: with:
node-version: 16.13.x node-version: 16.13.x
cache: npm cache: npm

View File

@@ -22,9 +22,9 @@ jobs:
echo 'The repo is currently frozen! Exiting this workflow.' echo 'The repo is currently frozen! Exiting this workflow.'
exit 1 # prevents further steps from running exit 1 # prevents further steps from running
- name: Checkout - name: Checkout
uses: actions/checkout@1e204e9a9253d643386038d443f96446fa156a97 uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
- name: Setup Node - name: Setup Node
uses: actions/setup-node@270253e841af726300e85d718a5f606959b2903c uses: actions/setup-node@04c56d2f954f1e4c69436aa54cfef261a018f458
with: with:
node-version: 16.13.x node-version: 16.13.x
cache: npm cache: npm

View File

@@ -94,11 +94,11 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Check out repo - name: Check out repo
uses: actions/checkout@1e204e9a9253d643386038d443f96446fa156a97 uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
# Set up npm and run npm ci to run husky to get githooks for LFS # Set up npm and run npm ci to run husky to get githooks for LFS
- name: Setup node - name: Setup node
uses: actions/setup-node@270253e841af726300e85d718a5f606959b2903c uses: actions/setup-node@04c56d2f954f1e4c69436aa54cfef261a018f458
with: with:
node-version: 16.13.x node-version: 16.13.x
cache: npm cache: npm
@@ -128,6 +128,9 @@ jobs:
pr_body: "This is an automated pull request to sync changes between the public and private repos.\n\n:robot: This pull request should be merged (not squashed) to preserve continuity across repos, so please let a bot do the merging!" pr_body: "This is an automated pull request to sync changes between the public and private repos.\n\n:robot: This pull request should be merged (not squashed) to preserve continuity across repos, so please let a bot do the merging!"
pr_label: automated-reposync-pr pr_label: automated-reposync-pr
github_token: ${{ secrets.OCTOMERGER_PAT_WITH_REPO_AND_WORKFLOW_SCOPE }} github_token: ${{ secrets.OCTOMERGER_PAT_WITH_REPO_AND_WORKFLOW_SCOPE }}
# This will exit 0 if there's no difference between `repo-sync`
# and `main`. And if so, no PR will be created.
pr_allow_empty: false
- name: Find pull request - name: Find pull request
uses: juliangruber/find-pull-request-action@db875662766249c049b2dcd85293892d61cb0b51 uses: juliangruber/find-pull-request-action@db875662766249c049b2dcd85293892d61cb0b51

View File

@@ -26,10 +26,10 @@ jobs:
pull-requests: write pull-requests: write
steps: steps:
- name: checkout docs-internal - name: checkout docs-internal
uses: actions/checkout@1e204e9a9253d643386038d443f96446fa156a97 uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
- name: checkout public site-policy - name: checkout public site-policy
uses: actions/checkout@1e204e9a9253d643386038d443f96446fa156a97 uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
with: with:
repository: github/site-policy repository: github/site-policy
token: ${{ secrets.API_TOKEN_SITEPOLICY }} token: ${{ secrets.API_TOKEN_SITEPOLICY }}
@@ -37,6 +37,8 @@ jobs:
path: public-repo path: public-repo
- name: Commits internal policies to copy of public repo with descriptive message from triggering PR title - name: Commits internal policies to copy of public repo with descriptive message from triggering PR title
env:
PR_TITLE: ${{ github.event.pull_request.title }}
run: | run: |
cd public-repo cd public-repo
git config --local user.name 'site-policy-bot' git config --local user.name 'site-policy-bot'
@@ -46,7 +48,6 @@ jobs:
git status git status
git checkout -b automated-sync-$GITHUB_RUN_ID git checkout -b automated-sync-$GITHUB_RUN_ID
git add . git add .
PR_TITLE=${{ github.event.pull_request.title }}
echo PR_TITLE: $PR_TITLE echo PR_TITLE: $PR_TITLE
[[ ! -z $PR_TITLE ]] && DESCRIPTION="${PR_TITLE}" || DESCRIPTION="Update manually triggered by workflow" [[ ! -z $PR_TITLE ]] && DESCRIPTION="${PR_TITLE}" || DESCRIPTION="Update manually triggered by workflow"
echo "DESCRIPTION=$DESCRIPTION" >> $GITHUB_ENV echo "DESCRIPTION=$DESCRIPTION" >> $GITHUB_ENV

View File

@@ -30,15 +30,6 @@ concurrency:
cancel-in-progress: true cancel-in-progress: true
jobs: jobs:
debug:
runs-on: ubuntu-latest
steps:
- name: Dump full context for debugging
run: |
cat << EOF
${{ toJSON(github) }}
EOF
build-pr: build-pr:
if: ${{ github.repository == 'github/docs-internal' || github.repository == 'github/docs' }} if: ${{ github.repository == 'github/docs-internal' || github.repository == 'github/docs' }}
runs-on: ${{ fromJSON('["ubuntu-latest", "self-hosted"]')[github.repository == 'github/docs-internal'] }} runs-on: ${{ fromJSON('["ubuntu-latest", "self-hosted"]')[github.repository == 'github/docs-internal'] }}
@@ -50,7 +41,7 @@ jobs:
cancel-in-progress: true cancel-in-progress: true
steps: steps:
- name: Check out repo - name: Check out repo
uses: actions/checkout@1e204e9a9253d643386038d443f96446fa156a97 uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
# Make sure only approved files are changed if it's in github/docs # Make sure only approved files are changed if it's in github/docs
- name: Check changed files - name: Check changed files
@@ -86,7 +77,7 @@ jobs:
run: exit 1 run: exit 1
- name: Setup node - name: Setup node
uses: actions/setup-node@270253e841af726300e85d718a5f606959b2903c uses: actions/setup-node@04c56d2f954f1e4c69436aa54cfef261a018f458
with: with:
node-version: 16.13.x node-version: 16.13.x
cache: npm cache: npm
@@ -117,11 +108,43 @@ jobs:
run: npm set-script heroku-postbuild "echo 'Application was pre-built!'" run: npm set-script heroku-postbuild "echo 'Application was pre-built!'"
- name: Delete heavy things we won't need deployed - name: Delete heavy things we won't need deployed
if: ${{ github.repository == 'github/docs-internal' }}
run: | run: |
# The dereferenced file is not used in runtime once the # The dereferenced file is not used in runtime once the
# decorated file has been created from it. # decorated file has been created from it.
rm -fr lib/rest/static/dereferenced rm -fr lib/rest/static/dereferenced
# Translations are never tested in Staging builds
# but let's keep the empty directory.
rm -fr translations
mkdir translations
# Delete all the big search indexes that are NOT English (`*-en-*`)
pushd lib/search/indexes
ls | grep -v '\-en\-' | xargs rm
popd
# Note! Some day it would be nice to be able to delete
# all the heavy assets because they bloat the tarball.
# But it's not obvious how to test it then. For now, we'll have
# to accept that every staging build has a copy of the images.
# The assumption here is that a staging build will not
# need these legacy redirects. Only the redirects from
# front-matter will be at play.
# These static redirects json files are notoriously large
# and they make the tarball unnecessarily large.
echo '[]' > lib/redirects/static/archived-frontmatter-fallbacks.json
echo '{}' > lib/redirects/static/developer.json
echo '{}' > lib/redirects/static/archived-redirects-from-213-to-217.json
# This will turn every `lib/**/static/*.json` into
# an equivalent `lib/**/static/*.json.br` file.
# Once the server starts, it'll know to fall back to reading
# the `.br` equivalent if the `.json` file isn't present.
node .github/actions-scripts/compress-large-files.js
- name: Create an archive - name: Create an archive
# Only bother if this is actually a pull request # Only bother if this is actually a pull request
if: ${{ github.event.pull_request.number }} if: ${{ github.event.pull_request.number }}

View File

@@ -67,6 +67,10 @@ jobs:
BUILD_ACTIONS_RUN_ID: ${{ env.BUILD_ACTIONS_RUN_ID }} BUILD_ACTIONS_RUN_ID: ${{ env.BUILD_ACTIONS_RUN_ID }}
with: with:
script: | script: |
// Curious about what version of node you get
console.log('Node version:', process.version)
// In order to find out the PR info for a forked repo, we must query // In order to find out the PR info for a forked repo, we must query
// the API for more info based on the originating workflow run // the API for more info based on the originating workflow run
const { BUILD_ACTIONS_RUN_ID } = process.env const { BUILD_ACTIONS_RUN_ID } = process.env
@@ -289,7 +293,7 @@ jobs:
}) })
- name: Check out repo's default branch - name: Check out repo's default branch
uses: actions/checkout@1e204e9a9253d643386038d443f96446fa156a97 uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
with: with:
# To prevent issues with cloning early access content later # To prevent issues with cloning early access content later
persist-credentials: 'false' persist-credentials: 'false'
@@ -299,7 +303,7 @@ jobs:
run: git lfs checkout run: git lfs checkout
- name: Setup node - name: Setup node
uses: actions/setup-node@270253e841af726300e85d718a5f606959b2903c uses: actions/setup-node@04c56d2f954f1e4c69436aa54cfef261a018f458
with: with:
node-version: 16.13.x node-version: 16.13.x
cache: npm cache: npm
@@ -471,10 +475,10 @@ jobs:
cancel-in-progress: true cancel-in-progress: true
steps: steps:
- name: Check out repo's default branch - name: Check out repo's default branch
uses: actions/checkout@1e204e9a9253d643386038d443f96446fa156a97 uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
- name: Setup node - name: Setup node
uses: actions/setup-node@270253e841af726300e85d718a5f606959b2903c uses: actions/setup-node@04c56d2f954f1e4c69436aa54cfef261a018f458
with: with:
node-version: 16.13.x node-version: 16.13.x
cache: npm cache: npm
@@ -482,12 +486,8 @@ jobs:
- name: Install dependencies - name: Install dependencies
run: npm ci run: npm ci
- name: Install one-off development-only dependencies
run: npm install --no-save --include=optional esm
- name: Deploy - name: Deploy
id: deploy id: deploy
uses: actions/github-script@2b34a689ec86a68d8ab9478298f91d5401337b7d
env: env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
HEROKU_API_TOKEN: ${{ secrets.HEROKU_API_TOKEN }} HEROKU_API_TOKEN: ${{ secrets.HEROKU_API_TOKEN }}
@@ -499,69 +499,8 @@ jobs:
ACTIONS_RUN_LOG: ${{ env.ACTIONS_RUN_LOG }} ACTIONS_RUN_LOG: ${{ env.ACTIONS_RUN_LOG }}
HEAD_SHA: ${{ needs.pr-metadata.outputs.head_sha }} HEAD_SHA: ${{ needs.pr-metadata.outputs.head_sha }}
ALLOWED_POLLING_FAILURES_PER_PHASE: '15' ALLOWED_POLLING_FAILURES_PER_PHASE: '15'
with: RUN_ID: ${{ github.run_id }}
script: | run: .github/actions-scripts/staging-deploy.js
const { GITHUB_TOKEN, HEROKU_API_TOKEN } = process.env
// Exit if GitHub Actions PAT is not found
if (!GITHUB_TOKEN) {
throw new Error('You must supply a GITHUB_TOKEN environment variable!')
}
// Exit if Heroku API token is not found
if (!HEROKU_API_TOKEN) {
throw new Error('You must supply a HEROKU_API_TOKEN environment variable!')
}
// Workaround to allow us to load ESM files with `require(...)`
const esm = require('esm')
require = esm({})
const { default: parsePrUrl } = require('./script/deployment/parse-pr-url')
const { default: getOctokit } = require('./script/helpers/github')
const { default: deployToStaging } = require('./script/deployment/deploy-to-staging')
// This helper uses the `GITHUB_TOKEN` implicitly!
// We're using our usual version of Octokit vs. the provided `github`
// instance to avoid versioning discrepancies.
const octokit = getOctokit()
try {
const { PR_URL, SOURCE_BLOB_URL, CONTEXT_NAME, ACTIONS_RUN_LOG, HEAD_SHA } = process.env
const { owner, repo, pullNumber } = parsePrUrl(PR_URL)
if (!owner || !repo || !pullNumber) {
throw new Error(`'pullRequestUrl' input must match URL format 'https://github.com/github/(docs|docs-internal)/pull/123' but was '${PR_URL}'`)
}
const { data: pullRequest } = await octokit.pulls.get({
owner,
repo,
pull_number: pullNumber
})
await deployToStaging({
octokit,
pullRequest,
forceRebuild: false,
// These parameters will ONLY be set by Actions
sourceBlobUrl: SOURCE_BLOB_URL,
runId: context.runId
})
await github.repos.createCommitStatus({
owner,
repo,
sha: HEAD_SHA,
context: CONTEXT_NAME,
state: 'success',
description: 'Successfully deployed! See logs.',
target_url: ACTIONS_RUN_LOG
})
} catch (error) {
console.error(`Failed to deploy to staging: ${error.message}`)
console.error(error)
throw error
}
- name: Mark the deployment as inactive if timed out - name: Mark the deployment as inactive if timed out
uses: actions/github-script@2b34a689ec86a68d8ab9478298f91d5401337b7d uses: actions/github-script@2b34a689ec86a68d8ab9478298f91d5401337b7d

View File

@@ -55,13 +55,13 @@ jobs:
add-labels: 'automated-block-deploy' add-labels: 'automated-block-deploy'
- name: Check out repo's default branch - name: Check out repo's default branch
uses: actions/checkout@1e204e9a9253d643386038d443f96446fa156a97 uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
with: with:
# For enhanced security: https://securitylab.github.com/research/github-actions-preventing-pwn-requests/ # For enhanced security: https://securitylab.github.com/research/github-actions-preventing-pwn-requests/
persist-credentials: 'false' persist-credentials: 'false'
- name: Setup node - name: Setup node
uses: actions/setup-node@270253e841af726300e85d718a5f606959b2903c uses: actions/setup-node@04c56d2f954f1e4c69436aa54cfef261a018f458
with: with:
node-version: 16.13.x node-version: 16.13.x
cache: npm cache: npm
@@ -69,51 +69,13 @@ jobs:
- name: Install dependencies - name: Install dependencies
run: npm ci run: npm ci
- name: Install one-off development-only dependencies
run: npm install --no-save --include=optional esm
- name: Undeploy - name: Undeploy
uses: actions/github-script@2b34a689ec86a68d8ab9478298f91d5401337b7d
env: env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
HEROKU_API_TOKEN: ${{ secrets.HEROKU_API_TOKEN }} HEROKU_API_TOKEN: ${{ secrets.HEROKU_API_TOKEN }}
with: RUN_ID: ${{ github.run_id }}
script: | PR_URL: ${{ github.event.pull_request.html_url }}
const { GITHUB_TOKEN, HEROKU_API_TOKEN } = process.env run: .github/actions-scripts/staging-undeploy.js
// Exit if GitHub Actions PAT is not found
if (!GITHUB_TOKEN) {
throw new Error('You must supply a GITHUB_TOKEN environment variable!')
}
// Exit if Heroku API token is not found
if (!HEROKU_API_TOKEN) {
throw new Error('You must supply a HEROKU_API_TOKEN environment variable!')
}
// Workaround to allow us to load ESM files with `require(...)`
const esm = require('esm')
require = esm({})
const { default: getOctokit } = require('./script/helpers/github')
const { default: undeployFromStaging } = require('./script/deployment/undeploy-from-staging')
// This helper uses the `GITHUB_TOKEN` implicitly!
// We're using our usual version of Octokit vs. the provided `github`
// instance to avoid versioning discrepancies.
const octokit = getOctokit()
try {
await undeployFromStaging({
octokit,
pullRequest: context.payload.pull_request,
runId: context.runId
})
} catch (error) {
console.error(`Failed to undeploy from staging: ${error.message}`)
console.error(error)
throw error
}
- if: ${{ always() }} - if: ${{ always() }}
name: Remove the label from the PR to unblock deployment name: Remove the label from the PR to unblock deployment

View File

@@ -48,12 +48,12 @@ jobs:
exit 1 # prevents further steps from running exit 1 # prevents further steps from running
# Check out internal docs repository # Check out internal docs repository
- name: checkout - name: checkout
uses: actions/checkout@1e204e9a9253d643386038d443f96446fa156a97 uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
with: with:
token: ${{ secrets.DOCS_BOT_FR }} token: ${{ secrets.DOCS_BOT_FR }}
- name: Setup Node - name: Setup Node
uses: actions/setup-node@270253e841af726300e85d718a5f606959b2903c uses: actions/setup-node@04c56d2f954f1e4c69436aa54cfef261a018f458
with: with:
node-version: 16.13.x node-version: 16.13.x
cache: npm cache: npm

40
.github/workflows/sync-search-pr.yml vendored Normal file
View File

@@ -0,0 +1,40 @@
name: Sync search - PR
# **What it does**: Tries running the sync-search when relevant files change.
# **Why we have it**: To test that the script works and the popular pages json is valid.
# **Who does it impact**: Docs engineering.
on:
pull_request:
paths:
- script/search/parse-page-sections-into-records.js
- script/search/popular-pages.js
- lib/search/popular-pages.json
# Ultimately, for debugging this workflow itself
- .github/workflows/sync-search-pr.yml
jobs:
lint:
runs-on: ubuntu-latest
steps:
- name: Check out repo
uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
- name: Setup node
uses: actions/setup-node@04c56d2f954f1e4c69436aa54cfef261a018f458
with:
node-version: 16.13.x
cache: npm
- name: Install dependencies
run: npm ci
- name: Build
run: npm run build
- name: Run sync-search
env:
# Set filtered to only these so it doesn't run for too long.
LANGUAGE: en
VERSION: free-pro-team@latest
run: npm run sync-search

View File

@@ -36,13 +36,13 @@ jobs:
] ]
steps: steps:
- name: Check out repo - name: Check out repo
uses: actions/checkout@1e204e9a9253d643386038d443f96446fa156a97 uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
with: with:
# Enables cloning the Early Access repo later with the relevant PAT # Enables cloning the Early Access repo later with the relevant PAT
persist-credentials: 'false' persist-credentials: 'false'
- name: Setup node - name: Setup node
uses: actions/setup-node@270253e841af726300e85d718a5f606959b2903c uses: actions/setup-node@04c56d2f954f1e4c69436aa54cfef261a018f458
with: with:
node-version: 16.13.x node-version: 16.13.x
cache: npm cache: npm

View File

@@ -41,7 +41,7 @@ jobs:
# Each of these ifs needs to be repeated at each step to make sure the required check still runs # Each of these ifs needs to be repeated at each step to make sure the required check still runs
# Even if if doesn't do anything # Even if if doesn't do anything
- name: Check out repo - name: Check out repo
uses: actions/checkout@1e204e9a9253d643386038d443f96446fa156a97 uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
with: with:
# Enables cloning the Early Access repo later with the relevant PAT # Enables cloning the Early Access repo later with the relevant PAT
persist-credentials: 'false' persist-credentials: 'false'
@@ -56,10 +56,13 @@ jobs:
- name: Insight into changed files - name: Insight into changed files
run: | run: |
echo ${{ steps.get_diff_files.outputs.files }}
# Must to do this because the list of files can be HUGE. Especially
# in a repo-sync when there are lots of translation files involved.
echo "${{ steps.get_diff_files.outputs.files }}" > get_diff_files.txt
- name: Setup node - name: Setup node
uses: actions/setup-node@270253e841af726300e85d718a5f606959b2903c uses: actions/setup-node@04c56d2f954f1e4c69436aa54cfef261a018f458
with: with:
node-version: 16.13.x node-version: 16.13.x
cache: npm cache: npm
@@ -67,18 +70,23 @@ jobs:
- name: Install dependencies - name: Install dependencies
run: npm ci run: npm ci
- if: ${{ github.repository == 'github/docs-internal' }} - name: Clone early access
name: Clone early access if: ${{ github.repository == 'github/docs-internal' }}
run: npm run heroku-postbuild run: script/early-access/clone-for-build.js
env: env:
DOCUBOT_REPO_PAT: ${{ secrets.DOCUBOT_REPO_PAT }} DOCUBOT_REPO_PAT: ${{ secrets.DOCUBOT_REPO_PAT }}
GIT_BRANCH: ${{ github.head_ref || github.ref }} GIT_BRANCH: ${{ github.head_ref || github.ref }}
- if: ${{ github.repository != 'github/docs-internal' }} - name: Cache nextjs build
name: Run build script uses: actions/cache@c64c572235d810460d0d6876e9c705ad5002b353
with:
path: .next/cache
key: ${{ runner.os }}-nextjs-${{ hashFiles('package*.json') }}-${{ hashFiles('.github/workflows/test.yml') }}
- name: Run build script
run: npm run build run: npm run build
- name: Run tests - name: Run tests
env: env:
DIFF_FILES: ${{ steps.get_diff_files.outputs.files }} DIFF_FILE: get_diff_files.txt
run: npm run test tests/${{ matrix.test-group }}/ run: npm run test tests/${{ matrix.test-group }}/

View File

@@ -8,6 +8,10 @@ on:
schedule: schedule:
- cron: '45 16 * * *' # Run each day at 16:45 UTC / 8:45 PST - cron: '45 16 * * *' # Run each day at 16:45 UTC / 8:45 PST
permissions:
issues: write
pull-requests: write
jobs: jobs:
stale_contributor: stale_contributor:
if: github.repository == 'github/docs' if: github.repository == 'github/docs'
@@ -17,11 +21,15 @@ jobs:
- uses: actions/stale@cdf15f641adb27a71842045a94023bef6945e3aa - uses: actions/stale@cdf15f641adb27a71842045a94023bef6945e3aa
with: with:
repo-token: ${{ secrets.GITHUB_TOKEN }} repo-token: ${{ secrets.GITHUB_TOKEN }}
stale-issue-message: 'A stale label has been added to this issue becuase it has been open for 60 days with no activity. To keep this issue open, add a comment within 3 days.'
days-before-issue-stale: 60
days-before-issue-close: 3
exempt-issue-labels: 'help wanted,waiting for review'
stale-pr-message: 'A stale label has been added to this pull request because it has been open 7 days with no activity. To keep this PR open, add a comment or push a commit within 3 days.' stale-pr-message: 'A stale label has been added to this pull request because it has been open 7 days with no activity. To keep this PR open, add a comment or push a commit within 3 days.'
days-before-pr-stale: 7 days-before-pr-stale: 7
days-before-pr-close: 3 days-before-pr-close: 3
stale-pr-label: 'stale' stale-pr-label: 'stale'
exempt-pr-labels: 'waiting for review,never-stale, ready to merge' exempt-pr-labels: 'waiting for review,never-stale,ready to merge'
stale_staff: stale_staff:
if: github.repository == 'github/docs' if: github.repository == 'github/docs'
runs-on: ubuntu-latest runs-on: ubuntu-latest

View File

@@ -54,13 +54,13 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@1e204e9a9253d643386038d443f96446fa156a97 uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
with: with:
ref: ${{ github.head_ref }} ref: ${{ github.head_ref }}
token: ${{ secrets.DOCUBOT_REPO_PAT }} token: ${{ secrets.DOCUBOT_REPO_PAT }}
- name: Setup Node - name: Setup Node
uses: actions/setup-node@270253e841af726300e85d718a5f606959b2903c uses: actions/setup-node@04c56d2f954f1e4c69436aa54cfef261a018f458
with: with:
node-version: 16.13.x node-version: 16.13.x
cache: npm cache: npm

View File

@@ -28,9 +28,9 @@ jobs:
echo 'The repo is currently frozen! Exiting this workflow.' echo 'The repo is currently frozen! Exiting this workflow.'
exit 1 # prevents further steps from running exit 1 # prevents further steps from running
- name: Checkout - name: Checkout
uses: actions/checkout@1e204e9a9253d643386038d443f96446fa156a97 uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
- name: Setup Node - name: Setup Node
uses: actions/setup-node@270253e841af726300e85d718a5f606959b2903c uses: actions/setup-node@04c56d2f954f1e4c69436aa54cfef261a018f458
with: with:
node-version: 16.13.x node-version: 16.13.x
cache: npm cache: npm

View File

@@ -23,7 +23,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Check out repo - name: Check out repo
uses: actions/checkout@1e204e9a9253d643386038d443f96446fa156a97 uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
- name: Run linter - name: Run linter
uses: cschleiden/actions-linter@caffd707beda4fc6083926a3dff48444bc7c24aa uses: cschleiden/actions-linter@caffd707beda4fc6083926a3dff48444bc7c24aa

View File

@@ -1,37 +0,0 @@
name: Lint Yaml
# **What it does**: This lints our yaml files in the docs repository.
# **Why we have it**: We want some level of consistent formatting for YAML files.
# **Who does it impact**: Docs engineering, docs content.
on:
workflow_dispatch:
push:
branches:
- main
paths:
- '**/*.yml'
- '**/*.yaml'
pull_request:
paths:
- '**/*.yml'
- '**/*.yaml'
jobs:
lint:
runs-on: ubuntu-latest
steps:
- name: Check out repo
uses: actions/checkout@1e204e9a9253d643386038d443f96446fa156a97
- name: Setup node
uses: actions/setup-node@270253e841af726300e85d718a5f606959b2903c
with:
node-version: 16.13.x
cache: npm
- name: Install dependencies
run: npm ci
- name: Run linter
run: npx prettier -c "**/*.{yml,yaml}"

1
.gitignore vendored
View File

@@ -10,6 +10,7 @@ coverage/
/data/early-access /data/early-access
.next .next
.eslintcache .eslintcache
*.tsbuildinfo
# blc: broken link checker # blc: broken link checker
blc_output.log blc_output.log

BIN
.vscode/open-reusable-1.3.0.vsix vendored Normal file

Binary file not shown.

View File

@@ -2,4 +2,6 @@
"files.exclude": { "files.exclude": {
"**/translations": true "**/translations": true
} }
} "workbench.editor.enablePreview": false,
"workbench.editor.enablePreviewFromQuickOpen": false
}

View File

@@ -1,4 +1,4 @@
# GitHub Docs <!-- omit in toc --> # GitHub Docs <!-- omit in toc -->
This repository contains the documentation website code and Markdown source files for [docs.github.com](https://docs.github.com). This repository contains the documentation website code and Markdown source files for [docs.github.com](https://docs.github.com).

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 157 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 156 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 122 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 227 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 170 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 70 KiB

After

Width:  |  Height:  |  Size: 207 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 134 KiB

After

Width:  |  Height:  |  Size: 121 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

View File

@@ -1,14 +1,12 @@
/* TODO remove mark styling if https://github.com/primer/css/pull/1756 ships */
.resultsContainer mark { .resultsContainer mark {
font-weight: bolder;
background: none; background: none;
color: inherit; color: inherit;
} }
.searchResultContent mark { .searchResultContent mark {
color: var(--color-fg-default); font-weight: bolder;
background-color: var(--color-attention-subtle);
} }
/* end TODO */
.searchResultContent { .searchResultContent {
max-height: 4rem; max-height: 4rem;

View File

@@ -436,7 +436,7 @@ function ShowSearchResults({
onClickOutside={() => closeSearch()} onClickOutside={() => closeSearch()}
aria-labelledby="title" aria-labelledby="title"
sx={ sx={
isHeaderSearch && { (isHeaderSearch && {
background: 'none', background: 'none',
boxShadow: 'none', boxShadow: 'none',
position: 'static', position: 'static',
@@ -445,7 +445,8 @@ function ShowSearchResults({
maxWidth: '96%', maxWidth: '96%',
margin: '1.5em 2em 0 0.5em', margin: '1.5em 2em 0 0.5em',
scrollbarWidth: 'none', scrollbarWidth: 'none',
} }) ||
{}
} }
> >
{ActionListResults} {ActionListResults}

View File

@@ -15,6 +15,7 @@ import { MarkdownContent } from 'components/ui/MarkdownContent'
import { Lead } from 'components/ui/Lead' import { Lead } from 'components/ui/Lead'
import { ArticleGridLayout } from './ArticleGridLayout' import { ArticleGridLayout } from './ArticleGridLayout'
import { PlatformPicker } from 'components/article/PlatformPicker' import { PlatformPicker } from 'components/article/PlatformPicker'
import { ToolPicker } from 'components/article/ToolPicker'
// Mapping of a "normal" article to it's interactive counterpart // Mapping of a "normal" article to it's interactive counterpart
const interactiveAlternatives: Record<string, { href: string }> = { const interactiveAlternatives: Record<string, { href: string }> = {
@@ -24,6 +25,22 @@ const interactiveAlternatives: Record<string, { href: string }> = {
'/actions/automating-builds-and-tests/building-and-testing-python': { '/actions/automating-builds-and-tests/building-and-testing-python': {
href: '/actions/automating-builds-and-tests/building-and-testing-nodejs-or-python?langId=python', href: '/actions/automating-builds-and-tests/building-and-testing-nodejs-or-python?langId=python',
}, },
'/codespaces/setting-up-your-project-for-codespaces/setting-up-your-nodejs-project-for-codespaces':
{
href: '/codespaces/setting-up-your-project-for-codespaces/setting-up-your-project-for-codespaces?langId=nodejs',
},
'/codespaces/setting-up-your-project-for-codespaces/setting-up-your-dotnet-project-for-codespaces':
{
href: '/codespaces/setting-up-your-project-for-codespaces/setting-up-your-project-for-codespaces?langId=dotnet',
},
'/codespaces/setting-up-your-project-for-codespaces/setting-up-your-java-project-for-codespaces':
{
href: '/codespaces/setting-up-your-project-for-codespaces/setting-up-your-project-for-codespaces?langId=java',
},
'/codespaces/setting-up-your-project-for-codespaces/setting-up-your-python-project-for-codespaces':
{
href: '/codespaces/setting-up-your-project-for-codespaces/setting-up-your-project-for-codespaces?langId=py',
},
} }
export const ArticlePage = () => { export const ArticlePage = () => {
@@ -36,6 +53,7 @@ export const ArticlePage = () => {
contributor, contributor,
permissions, permissions,
includesPlatformSpecificContent, includesPlatformSpecificContent,
includesToolSpecificContent,
product, product,
miniTocItems, miniTocItems,
currentLearningTrack, currentLearningTrack,
@@ -51,7 +69,7 @@ export const ArticlePage = () => {
className={item.platform} className={item.platform}
sx={{ listStyle: 'none', padding: '2px' }} sx={{ listStyle: 'none', padding: '2px' }}
> >
<div className={cx('lh-condensed')}> <div className={cx('lh-condensed d-block width-full')}>
<div dangerouslySetInnerHTML={{ __html: item.contents }} /> <div dangerouslySetInnerHTML={{ __html: item.contents }} />
{item.items && item.items.length > 0 ? ( {item.items && item.items.length > 0 ? (
<ul className="ml-3">{item.items.map(renderTocItem)}</ul> <ul className="ml-3">{item.items.map(renderTocItem)}</ul>
@@ -95,6 +113,7 @@ export const ArticlePage = () => {
)} )}
{includesPlatformSpecificContent && <PlatformPicker variant="underlinenav" />} {includesPlatformSpecificContent && <PlatformPicker variant="underlinenav" />}
{includesToolSpecificContent && <ToolPicker variant="underlinenav" />}
{product && ( {product && (
<Callout <Callout

View File

@@ -12,9 +12,11 @@ const platforms = [
{ id: 'linux', label: 'Linux' }, { id: 'linux', label: 'Linux' },
] ]
// Nota bene: platform === os
// Imperatively modify article content to show only the selected platform // Imperatively modify article content to show only the selected platform
// find all platform-specific *block* elements and hide or show as appropriate // find all platform-specific *block* elements and hide or show as appropriate
// example: {% mac } block content {% mac %} // example: {% mac %} block content {% endmac %}
function showPlatformSpecificContent(platform: string) { function showPlatformSpecificContent(platform: string) {
const markdowns = Array.from(document.querySelectorAll<HTMLElement>('.extended-markdown')) const markdowns = Array.from(document.querySelectorAll<HTMLElement>('.extended-markdown'))
markdowns markdowns

View File

@@ -0,0 +1,121 @@
import { useEffect, useState } from 'react'
import Cookies from 'js-cookie'
import { UnderlineNav } from '@primer/components'
import { sendEvent, EventType } from 'components/lib/events'
import { preserveAnchorNodePosition } from 'scroll-anchoring'
import { useArticleContext } from 'components/context/ArticleContext'
// example: http://localhost:4000/en/codespaces/developing-in-codespaces/creating-a-codespace
// Nota bene: tool === application
// Nota bene: picker === switcher
const supportedTools = ['cli', 'desktop', 'webui', 'curl', 'codespaces', 'vscode']
const toolTitles = {
webui: 'Web browser',
cli: 'GitHub CLI',
curl: 'cURL',
desktop: 'Desktop',
codespaces: 'Codespaces',
vscode: 'Visual Studio Code',
} as Record<string, string>
// Imperatively modify article content to show only the selected tool
// find all platform-specific *block* elements and hide or show as appropriate
// example: {% webui %} block content {% endwebui %}
function showToolSpecificContent(tool: string) {
const markdowns = Array.from(document.querySelectorAll<HTMLElement>('.extended-markdown'))
markdowns
.filter((el) => supportedTools.some((tool) => el.classList.contains(tool)))
.forEach((el) => {
el.style.display = el.classList.contains(tool) ? '' : 'none'
})
// find all tool-specific *inline* elements and hide or show as appropriate
// example: <span class="tool-webui">inline content</span>
const toolEls = Array.from(
document.querySelectorAll<HTMLElement>(supportedTools.map((tool) => `.tool-${tool}`).join(', '))
)
toolEls.forEach((el) => {
el.style.display = el.classList.contains(`tool-${tool}`) ? '' : 'none'
})
}
function getDefaultTool(defaultTool: string | undefined, detectedTools: Array<string>): string {
// If there is a default tool and the tool is present on this page
if (defaultTool && detectedTools.includes(defaultTool)) return defaultTool
// Default to webui if present (this is generally the case where we show UI/CLI/Desktop info)
if (detectedTools.includes('webui')) return 'webui'
// Default to cli if present (this is generally the case where we show curl/CLI info)
if (detectedTools.includes('cli')) return 'cli'
// Otherwise, just choose the first detected tool
return detectedTools[0]
}
type Props = {
variant?: 'subnav' | 'tabnav' | 'underlinenav'
}
export const ToolPicker = ({ variant = 'subnav' }: Props) => {
const { defaultTool, detectedTools } = useArticleContext()
const [currentTool, setCurrentTool] = useState(getDefaultTool(defaultTool, detectedTools))
const sharedContainerProps = {
'data-testid': 'tool-picker',
'aria-label': 'Tool picker',
'data-default-tool': defaultTool,
className: 'mb-4',
}
// Run on mount for client-side only features
useEffect(() => {
// If the user selected a tool preference and the tool is present on this page
// Has to be client-side only for cookie reading
const cookieValue = Cookies.get('toolPreferred')
if (cookieValue && detectedTools.includes(cookieValue)) {
setCurrentTool(cookieValue)
}
}, [])
// Whenever the currentTool is changed, update the article content
useEffect(() => {
preserveAnchorNodePosition(document, () => {
showToolSpecificContent(currentTool)
})
}, [currentTool])
function onClickTool(tool: string) {
setCurrentTool(tool)
sendEvent({
type: EventType.preference,
preference_name: 'application',
preference_value: tool,
})
Cookies.set('toolPreferred', tool, { sameSite: 'strict', secure: true })
}
if (variant === 'underlinenav') {
return (
<UnderlineNav {...sharedContainerProps}>
{detectedTools.map((tool) => (
<UnderlineNav.Link
key={tool}
data-tool={tool}
as="button"
selected={tool === currentTool}
onClick={() => {
onClickTool(tool)
}}
>
{toolTitles[tool]}
</UnderlineNav.Link>
))}
</UnderlineNav>
)
}
return null
}

View File

@@ -22,10 +22,13 @@ export type ArticleContextT = {
contributor: { name: string; URL: string } | null contributor: { name: string; URL: string } | null
permissions?: string permissions?: string
includesPlatformSpecificContent: boolean includesPlatformSpecificContent: boolean
includesToolSpecificContent: boolean
defaultPlatform?: string defaultPlatform?: string
defaultTool?: string
product?: string product?: string
currentLearningTrack?: LearningTrack currentLearningTrack?: LearningTrack
detectedPlatforms: Array<string> detectedPlatforms: Array<string>
detectedTools: Array<string>
} }
export const ArticleContext = createContext<ArticleContextT | null>(null) export const ArticleContext = createContext<ArticleContextT | null>(null)
@@ -60,9 +63,12 @@ export const getArticleContextFromRequest = (req: any): ArticleContextT => {
contributor: page.contributor || null, contributor: page.contributor || null,
permissions: page.permissions || '', permissions: page.permissions || '',
includesPlatformSpecificContent: page.includesPlatformSpecificContent || false, includesPlatformSpecificContent: page.includesPlatformSpecificContent || false,
includesToolSpecificContent: page.includesToolSpecificContent || false,
defaultPlatform: page.defaultPlatform || '', defaultPlatform: page.defaultPlatform || '',
defaultTool: page.defaultTool || '',
product: page.product || '', product: page.product || '',
currentLearningTrack: req.context.currentLearningTrack, currentLearningTrack: req.context.currentLearningTrack,
detectedPlatforms: page.detectedPlatforms || [], detectedPlatforms: page.detectedPlatforms || [],
detectedTools: page.detectedTools || [],
} }
} }

View File

@@ -2,14 +2,21 @@ import React, { createContext, useContext, useState } from 'react'
import { CodeLanguage, PlaygroundArticleT } from 'components/playground/types' import { CodeLanguage, PlaygroundArticleT } from 'components/playground/types'
import { useRouter } from 'next/router' import { useRouter } from 'next/router'
import jsArticle from 'components/playground/content/building-and-testing/nodejs' import actionsJsArticle from 'components/playground/content/actions/guides/building-and-testing-nodejs-or-python/nodejs'
import pyArticle from 'components/playground/content/building-and-testing/python' import actionsPyArticle from 'components/playground/content/actions/guides/building-and-testing-nodejs-or-python/python'
import codespacesJsArticle from 'components/playground/content/codespaces/setting-up-your-project-for-codespaces/setting-up-your-project-for-codespaces/nodejs'
import codespacesPyArticle from 'components/playground/content/codespaces/setting-up-your-project-for-codespaces/setting-up-your-project-for-codespaces/python'
import codespacesNetArticle from 'components/playground/content/codespaces/setting-up-your-project-for-codespaces/setting-up-your-project-for-codespaces/dotnet'
import codespacesJavaArticle from 'components/playground/content/codespaces/setting-up-your-project-for-codespaces/setting-up-your-project-for-codespaces/java'
const articles = [jsArticle, pyArticle] const articles = [
const articlesByLangId = articles.reduce((obj, item) => { actionsJsArticle,
obj[item.codeLanguageId] = item actionsPyArticle,
return obj codespacesJsArticle,
}, {} as Record<string, PlaygroundArticleT | undefined>) codespacesPyArticle,
codespacesJavaArticle,
codespacesNetArticle,
]
const codeLanguages: Array<CodeLanguage> = [ const codeLanguages: Array<CodeLanguage> = [
{ {
@@ -20,6 +27,14 @@ const codeLanguages: Array<CodeLanguage> = [
id: 'py', id: 'py',
label: 'Python', label: 'Python',
}, },
{
id: 'dotnet',
label: 'C#',
},
{
id: 'java',
label: 'Java',
},
] ]
type PlaygroundContextT = { type PlaygroundContextT = {
@@ -48,11 +63,18 @@ export const PlaygroundContextProvider = (props: { children: React.ReactNode })
const router = useRouter() const router = useRouter()
const [activeSectionIndex, setActiveSectionIndex] = useState(0) const [activeSectionIndex, setActiveSectionIndex] = useState(0)
const [scrollToSection, setScrollToSection] = useState<number>() const [scrollToSection, setScrollToSection] = useState<number>()
const { langId } = router.query const path = router.asPath.split('?')[0]
const currentLanguage = codeLanguages.find(({ id }) => id === langId) || codeLanguages[0] const relevantArticles = articles.filter(({ slug }) => slug === path)
const availableLanguages = codeLanguages.filter(({ id }) => !!articlesByLangId[id])
const article = articlesByLangId[currentLanguage.id] const { langId } = router.query
const availableLanguageIds = relevantArticles.map(({ codeLanguageId }) => codeLanguageId)
const currentLanguage =
codeLanguages.find(({ id }) => id === langId) ||
(codeLanguages.find(({ id }) => id === availableLanguageIds[0]) as CodeLanguage)
const article = relevantArticles.find(
({ codeLanguageId }) => codeLanguageId === currentLanguage?.id
)
const context = { const context = {
activeSectionIndex, activeSectionIndex,
@@ -60,7 +82,7 @@ export const PlaygroundContextProvider = (props: { children: React.ReactNode })
scrollToSection, scrollToSection,
setScrollToSection, setScrollToSection,
currentLanguage, currentLanguage,
codeLanguages: availableLanguages, codeLanguages: codeLanguages.filter(({ id }) => availableLanguageIds.includes(id)),
article, article,
} }

Some files were not shown because too many files have changed in this diff Show More