Merge branch 'main' into mm-cs-networking
@@ -21,7 +21,8 @@
|
|||||||
"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.
|
||||||
|
|||||||
2
.github/CODEOWNERS
vendored
@@ -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
|
||||||
|
|||||||
63
.github/actions-scripts/compress-large-files.js
vendored
Executable 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)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
54
.github/actions-scripts/content-changes-table-comment.js
vendored
Executable 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)
|
||||||
@@ -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.
|
||||||
@@ -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
@@ -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
|
||||||
|
}
|
||||||
11
.github/actions-scripts/purge-fastly-edge-cache.js
vendored
Executable 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
|
||||||
|
}
|
||||||
@@ -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
@@ -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
@@ -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,
|
||||||
|
})
|
||||||
4
.github/allowed-actions.js
vendored
@@ -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
|
||||||
|
|||||||
2
.github/workflows/60-days-stale-check.yml
vendored
@@ -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'
|
||||||
|
|||||||
4
.github/workflows/autoupdate-branch.yml
vendored
@@ -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
|
||||||
|
|||||||
20
.github/workflows/browser-test.yml
vendored
@@ -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
|
||||||
|
|||||||
2
.github/workflows/build-docker-image.yml
vendored
@@ -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 .
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
2
.github/workflows/codeql.yml
vendored
@@ -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!)
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
4
.github/workflows/crowdin-cleanup.yml
vendored
@@ -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
|
||||||
|
|||||||
2
.github/workflows/crowdin.yml
vendored
@@ -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
|
||||||
|
|||||||
4
.github/workflows/docs-review-collect.yml
vendored
@@ -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
|
||||||
|
|||||||
4
.github/workflows/enterprise-dates.yml
vendored
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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'
|
||||||
|
|||||||
4
.github/workflows/js-lint.yml
vendored
@@ -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
|
||||||
|
|||||||
4
.github/workflows/link-check-dotcom.yml
vendored
@@ -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
|
||||||
|
|||||||
4
.github/workflows/link-check-ghae.yml
vendored
@@ -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
|
||||||
|
|||||||
4
.github/workflows/link-check-ghec.yml
vendored
@@ -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
|
||||||
|
|||||||
4
.github/workflows/link-check-ghes.yml
vendored
@@ -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
|
||||||
|
|||||||
4
.github/workflows/open-enterprise-issue.yml
vendored
@@ -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
|
||||||
|
|||||||
4
.github/workflows/openapi-decorate.yml
vendored
@@ -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
|
||||||
|
|||||||
4
.github/workflows/openapi-schema-check.yml
vendored
@@ -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
|
||||||
|
|||||||
4
.github/workflows/os-ready-for-review.yml
vendored
@@ -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
|
||||||
|
|||||||
4
.github/workflows/pa11y.yml
vendored
@@ -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
|
||||||
|
|||||||
4
.github/workflows/package-lock-lint.yml
vendored
@@ -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
|
||||||
|
|
||||||
|
|||||||
4
.github/workflows/ping-staging-apps.yml
vendored
@@ -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
|
||||||
|
|||||||
77
.github/workflows/prod-build-deploy.yml
vendored
@@ -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
|
||||||
|
|||||||
4
.github/workflows/ready-for-doc-review.yml
vendored
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
4
.github/workflows/remove-unused-assets.yml
vendored
@@ -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
|
||||||
|
|||||||
7
.github/workflows/repo-sync.yml
vendored
@@ -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
|
||||||
|
|||||||
7
.github/workflows/site-policy-sync.yml
vendored
@@ -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
|
||||||
|
|||||||
45
.github/workflows/staging-build-pr.yml
vendored
@@ -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 }}
|
||||||
|
|||||||
81
.github/workflows/staging-deploy-pr.yml
vendored
@@ -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
|
||||||
|
|||||||
48
.github/workflows/staging-undeploy-pr.yml
vendored
@@ -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
|
||||||
|
|||||||
4
.github/workflows/sync-search-indices.yml
vendored
@@ -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
@@ -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
|
||||||
4
.github/workflows/test-windows.yml
vendored
@@ -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
|
||||||
|
|||||||
26
.github/workflows/test.yml
vendored
@@ -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 }}/
|
||||||
|
|||||||
10
.github/workflows/triage-stale-check.yml
vendored
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
4
.github/workflows/update-graphql-files.yml
vendored
@@ -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
|
||||||
|
|||||||
2
.github/workflows/workflow-lint.yml
vendored
@@ -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
|
||||||
|
|||||||
37
.github/workflows/yml-lint.yml
vendored
@@ -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
@@ -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
2
.vscode/settings.json
vendored
@@ -2,4 +2,6 @@
|
|||||||
"files.exclude": {
|
"files.exclude": {
|
||||||
"**/translations": true
|
"**/translations": true
|
||||||
}
|
}
|
||||||
|
"workbench.editor.enablePreview": false,
|
||||||
|
"workbench.editor.enablePreviewFromQuickOpen": false
|
||||||
}
|
}
|
||||||
BIN
assets/images/azure/github-ae-azure-portal-add-new.png
Normal file
|
After Width: | Height: | Size: 26 KiB |
BIN
assets/images/azure/github-ae-azure-portal-all-resources.png
Normal file
|
After Width: | Height: | Size: 28 KiB |
BIN
assets/images/azure/github-ae-azure-portal-form.png
Normal file
|
After Width: | Height: | Size: 102 KiB |
BIN
assets/images/azure/github-ae-azure-portal-search.png
Normal file
|
After Width: | Height: | Size: 18 KiB |
BIN
assets/images/azure/github-ae-azure-portal-type-filter.png
Normal file
|
After Width: | Height: | Size: 66 KiB |
BIN
assets/images/enterprise/custom-footer/add-footer-links.png
Normal file
|
After Width: | Height: | Size: 157 KiB |
BIN
assets/images/enterprise/custom-footer/custom-footer-section.png
Normal file
|
After Width: | Height: | Size: 68 KiB |
|
After Width: | Height: | Size: 44 KiB |
|
After Width: | Height: | Size: 44 KiB |
BIN
assets/images/enterprise/custom-footer/octodemo-footer.png
Normal file
|
After Width: | Height: | Size: 58 KiB |
BIN
assets/images/enterprise/custom-footer/update-custom-footer.png
Normal file
|
After Width: | Height: | Size: 156 KiB |
BIN
assets/images/help/codespaces/install-custom-dotfiles.png
Normal file
|
After Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 16 KiB |
BIN
assets/images/help/codespaces/select-dotfiles-repo.png
Normal file
|
After Width: | Height: | Size: 26 KiB |
BIN
assets/images/help/codespaces/setting-default-timeout.png
Normal file
|
After Width: | Height: | Size: 82 KiB |
BIN
assets/images/help/enterprises/organization-search.png
Normal file
|
After Width: | Height: | Size: 35 KiB |
BIN
assets/images/help/enterprises/remove-organization-warning.png
Normal file
|
After Width: | Height: | Size: 37 KiB |
BIN
assets/images/help/enterprises/remove-organization.png
Normal file
|
After Width: | Height: | Size: 44 KiB |
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 47 KiB |
|
Before Width: | Height: | Size: 6.4 KiB After Width: | Height: | Size: 35 KiB |
BIN
assets/images/help/images/reusable-workflows-ci-cd.png
Normal file
|
After Width: | Height: | Size: 70 KiB |
|
After Width: | Height: | Size: 71 KiB |
BIN
assets/images/help/projects/unsaved-changes.png
Normal file
|
After Width: | Height: | Size: 23 KiB |
|
After Width: | Height: | Size: 122 KiB |
BIN
assets/images/help/repository/PR-required-check-skipped.png
Normal file
|
After Width: | Height: | Size: 110 KiB |
BIN
assets/images/help/repository/allow-disable-forking-fpt.png
Normal file
|
After Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 227 KiB |
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 114 KiB |
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 170 KiB |
|
Before Width: | Height: | Size: 70 KiB After Width: | Height: | Size: 207 KiB |
|
Before Width: | Height: | Size: 134 KiB After Width: | Height: | Size: 121 KiB |
BIN
assets/images/help/support/request-callback.png
Normal file
|
After Width: | Height: | Size: 21 KiB |
@@ -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;
|
||||||
|
|||||||
@@ -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}
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
121
components/article/ToolPicker.tsx
Normal 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
|
||||||
|
}
|
||||||
@@ -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 || [],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ export type ArticleGuide = {
|
|||||||
topics: Array<string>
|
topics: Array<string>
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ProductSubLandingContextT = {
|
export type ProductGuidesContextT = {
|
||||||
title: string
|
title: string
|
||||||
intro: string
|
intro: string
|
||||||
featuredTrack?: FeaturedTrack
|
featuredTrack?: FeaturedTrack
|
||||||
@@ -26,21 +26,21 @@ export type ProductSubLandingContextT = {
|
|||||||
allTopics?: Array<string>
|
allTopics?: Array<string>
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ProductSubLandingContext = createContext<ProductSubLandingContextT | null>(null)
|
export const ProductGuidesContext = createContext<ProductGuidesContextT | null>(null)
|
||||||
|
|
||||||
export const useProductSubLandingContext = (): ProductSubLandingContextT => {
|
export const useProductGuidesContext = (): ProductGuidesContextT => {
|
||||||
const context = useContext(ProductSubLandingContext)
|
const context = useContext(ProductGuidesContext)
|
||||||
|
|
||||||
if (!context) {
|
if (!context) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
'"useProductSubLandingContext" may only be used inside "ProductSubLandingContext.Provider"'
|
'"useProductGuidesContext" may only be used inside "ProductGuidesContext.Provider"'
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return context
|
return context
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getProductSubLandingContextFromRequest = (req: any): ProductSubLandingContextT => {
|
export const getProductGuidesContextFromRequest = (req: any): ProductGuidesContextT => {
|
||||||
const page = req.context.page
|
const page = req.context.page
|
||||||
|
|
||||||
return {
|
return {
|
||||||