1
0
mirror of synced 2025-12-23 21:07:12 -05:00

Merge branch 'desktop-configuring-git' of https://github.com/github/docs into desktop-configuring-git

This commit is contained in:
Steve Ward
2022-05-24 14:16:12 -04:00
3761 changed files with 1178244 additions and 15660 deletions

View File

@@ -13,7 +13,7 @@ module.exports = {
babelOptions: { configFile: './.babelrc' },
sourceType: 'module',
},
ignorePatterns: ['tmp/*', '!/.*', '/.next/', 'script/bookmarklets/*'],
ignorePatterns: ['tmp/*', '!/.*', '/.next/', 'script/bookmarklets/*', 'lib/sigsci.js'],
rules: {
'import/no-extraneous-dependencies': ['error', { packageDir: '.' }],
},

View File

@@ -7,6 +7,7 @@ import { getContents } from '../../script/helpers/git-utils.js'
import parse from '../../lib/read-frontmatter.js'
import getApplicableVersions from '../../lib/get-applicable-versions.js'
import nonEnterpriseDefaultVersion from '../../lib/non-enterprise-default-version.js'
import { allVersionShortnames } from '../../lib/all-versions.js'
const { GITHUB_TOKEN, APP_URL } = process.env
const context = github.context
@@ -22,6 +23,7 @@ if (!APP_URL) {
const PROD_URL = 'https://docs.github.com'
const octokit = github.getOctokit(GITHUB_TOKEN)
// get the list of file changes from the PR
const response = await octokit.rest.repos.compareCommitsWithBasehead({
owner: context.repo.owner,
repo: context.payload.repository.name,
@@ -61,36 +63,54 @@ for (const file of articleFiles) {
if (file.status === 'added') contentCell = `New file: `
contentCell += `[\`${fileName}\`](${sourceUrl})`
for (const version in data.versions) {
const currentApplicableVersions = getApplicableVersions({
[version]: data.versions[version],
})
try {
// the try/catch is needed because getApplicableVersions() returns either [] or throws an error when it can't parse the versions frontmatter
// try/catch can be removed if docs-engineering#1821 is resolved
// i.e. for feature based versioning, like ghae: 'issue-6337'
const fileVersions = getApplicableVersions(data.versions)
if (currentApplicableVersions.length === 1) {
for (const plan in allVersionShortnames) {
// plan is the shortName (i.e., fpt)
// allVersionShortNames[plan] is the planName (i.e., free-pro-team)
// walk by the plan names since we generate links differently for most plans
const versions = fileVersions.filter((fileVersion) =>
fileVersion.includes(allVersionShortnames[plan])
)
if (versions.length === 1) {
// for fpt, ghec, and ghae
if (currentApplicableVersions.toString() === nonEnterpriseDefaultVersion) {
if (versions.toString() === nonEnterpriseDefaultVersion) {
// omit version from fpt url
previewCell += `[${version}](${APP_URL}/${fileUrl})<br>`
prodCell += `[${version}](${PROD_URL}/${fileUrl})<br>`
previewCell += `[${plan}](${APP_URL}/${fileUrl})<br>`
prodCell += `[${plan}](${PROD_URL}/${fileUrl})<br>`
} else {
// for non-versioned releases (ghae, ghec) use full url
previewCell += `[${version}](${APP_URL}/${currentApplicableVersions}/${fileUrl})<br>`
prodCell += `[${version}](${PROD_URL}/${currentApplicableVersions}/${fileUrl})<br>`
}
} else {
// for ghes releases, link each version
previewCell += `${version}@ `
prodCell += `${version}@ `
currentApplicableVersions.forEach((ghesVersion) => {
previewCell += `[${ghesVersion.split('@')[1]}](${APP_URL}/${ghesVersion}/${fileUrl}) `
prodCell += `[${ghesVersion.split('@')[1]}](${PROD_URL}/${ghesVersion}/${fileUrl}) `
previewCell += `[${plan}](${APP_URL}/${versions}/${fileUrl})<br>`
prodCell += `[${plan}](${PROD_URL}/${versions}/${fileUrl})<br>`
}
} else if (versions.length) {
// for ghes releases, link each version
previewCell += `${plan}@ `
prodCell += `${plan}@ `
versions.forEach((version) => {
previewCell += `[${version.split('@')[1]}](${APP_URL}/${version}/${fileUrl}) `
prodCell += `[${version.split('@')[1]}](${PROD_URL}/${version}/${fileUrl}) `
})
previewCell += '<br>'
prodCell += '<br>'
}
}
} catch (e) {
console.error(
`Version information for ${file.filename} couldn't be determined from its frontmatter.`
)
}
markdownTable += `| ${contentCell} | ${previewCell} | ${prodCell} | |\n`
}
setOutput('changesTable', markdownTable)

View File

@@ -17,7 +17,7 @@ async function main() {
const github = getOctokit(token)
const pull = await github.rest.pulls.get({
owner: org,
repo: repo,
repo,
pull_number: parseInt(prNumber),
})

View File

@@ -110,20 +110,20 @@ This file should be automatically updated, but you can also run `script/update-e
### 🚢 🛳️ 🚢 Shipping the release branch
- [ ] The megabranch creator should push the search index LFS objects for the public `github/docs` repo. The LFS objects were already pushed for the internal repo after the `sync-english-index-for-<PLAN@RELEASE>` was added to the megabranch. To push the LFS objects to the public repo:
1. First navigate to the [sync search indices workflow](https://github.com/github/docs-internal/actions/workflows/sync-search-indices.yml).
2. Then, to run the workflow with parameters, click on `Run workflow` button.
3. A modal will pop up where you will set the following inputs:
- Branch: The new `ghes-<RELEASE>-megabranch` version megabranch you're working on
- Version: `enterprise-server@<RELEASE>`
- Language: `en`
4. Run the job. The workflow job may fail on the first run—so retry the failed job if needed.
- [ ] Remove `[DO NOT MERGE]` and other meta information from the PR title 😜.
- [ ] The `github/docs-internal` repo is frozen, and the `Repo Freeze Check / Prevent merging during deployment freezes (pull_request_target)` test is expected to fail.
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. You can monitor and check when the production deploy completed by viewing the [`docs-internal` deployments page](https://github.com/github/docs-internal/deployments).
- [ ] 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, the megabranch creator should push the search index LFS objects for the public `github/docs` repo. The LFS objects were already pushed for the internal repo after the `sync-english-index-for-<PLAN@RELEASE>` was added to the megabranch. To push the LFS objects to the public repo:
1. First navigate to the [sync search indices workflow](https://github.com/github/docs-internal/actions/workflows/sync-search-indices.yml).
2. Then, to run the workflow with parameters, click on `Run workflow` button.
3. A modal will pop up where you will set the following inputs:
- Branch: The new version megabranch you're working on
- Version: `enterprise-server@<RELEASE>`
- Language: `en`
4. Run the job. The workflow job may fail on the first run—so retry the failed job if needed.
- [ ] After unfreezing, alert the Ecosystem-API team in #ecosystem-api the docs freeze is finished/thawed and the release has shipped.
- [ ] You (or they) can now remove your blocking review on the auto-generated "Update OpenAPI Descriptions" PR in public REST API description (the `rest-api-descriptions` repo). (although it's likely newer PRs have been created since yours with the blocking review, in which case the Ecosystem-API team will close your PR and perform the next step on the most recent PR).
- [ ] The Ecosystem-API team will merge the latest auto-generated "Update OpenAPI Descriptions" PR (which will contain the OpenAPI schema config that changed `published` to `true` for the release).

View File

@@ -191,16 +191,16 @@ async function run() {
await graphql(updateProjectNextItemMutation, {
project: projectID,
statusID: statusID,
statusID,
statusValueID: readyForReviewID,
datePostedID: datePostedID,
reviewDueDateID: reviewDueDateID,
contributorTypeID: contributorTypeID,
contributorType: contributorType,
sizeTypeID: sizeTypeID,
datePostedID,
reviewDueDateID,
contributorTypeID,
contributorType,
sizeTypeID,
sizeType: '', // Although we aren't populating size, we are passing the variable so that we can use the shared mutation function
featureID: featureID,
authorID: authorID,
featureID,
authorID,
headers: {
authorization: `token ${process.env.TOKEN}`,
'GraphQL-Features': 'projects_next_graphql',

View File

@@ -0,0 +1,142 @@
#!/usr/bin/env node
import fs from 'fs'
import github from '@actions/github'
const OPTIONS = Object.fromEntries(
['BASE', 'BODY_FILE', 'GITHUB_TOKEN', 'HEAD', 'LANGUAGE', 'TITLE', 'GITHUB_REPOSITORY'].map(
(envVarName) => {
const envVarValue = process.env[envVarName]
if (!envVarValue) {
throw new Error(`You must supply a ${envVarName} environment variable`)
}
return [envVarName, envVarValue]
}
)
)
if (!process.env.GITHUB_REPOSITORY) {
throw new Error('GITHUB_REPOSITORY environment variable not set')
}
const RETRY_STATUSES = [
422, // Retry the operation if the PR already exists
502, // Retry the operation if the API responds with a `502 Bad Gateway` error.
]
const RETRY_ATTEMPTS = 3
const {
// One of the default environment variables provided by Actions.
GITHUB_REPOSITORY,
// These are passed in from the step in the workflow file.
TITLE,
BASE,
HEAD,
LANGUAGE,
BODY_FILE,
GITHUB_TOKEN,
} = OPTIONS
const [OWNER, REPO] = GITHUB_REPOSITORY.split('/')
const octokit = github.getOctokit(GITHUB_TOKEN)
/**
* @param {object} config Configuration options for finding the PR.
* @returns {Promise<number | undefined>} The PR number.
*/
async function findPullRequestNumber(config) {
// Get a list of PRs and see if one already exists.
const { data: listOfPullRequests } = await octokit.rest.pulls.list({
owner: config.owner,
repo: config.repo,
head: `${config.owner}:${config.head}`,
})
return listOfPullRequests[0]?.number
}
/**
* When this file was first created, we only introduced support for creating a pull request for some translation batch.
* However, some of our first workflow runs failed during the pull request creation due to a timeout error.
* There have been cases where, despite the timeout error, the pull request gets created _anyway_.
* To accommodate this reality, we created this function to look for an existing pull request before a new one is created.
* Although the "find" check is redundant in the first "cycle", it's designed this way to recursively call the function again via its retry mechanism should that be necessary.
*
* @param {object} config Configuration options for creating the pull request.
* @returns {Promise<number>} The PR number.
*/
async function findOrCreatePullRequest(config) {
const found = await findPullRequestNumber(config)
if (found) {
return found
}
try {
const { data: pullRequest } = await octokit.rest.pulls.create({
owner: config.owner,
repo: config.repo,
base: config.base,
head: config.head,
title: config.title,
body: config.body,
draft: false,
})
return pullRequest.number
} catch (error) {
if (!error.response || !config.retryCount) {
throw error
}
if (!config.retryStatuses.includes(error.response.status)) {
throw error
}
console.error(`Error creating pull request: ${error.message}`)
console.warn(`Retrying in 5 seconds...`)
await new Promise((resolve) => setTimeout(resolve, 5000))
config.retryCount -= 1
return findOrCreatePullRequest(config)
}
}
/**
* @param {object} config Configuration options for labeling the PR
* @returns {Promise<undefined>}
*/
// async function labelPullRequest(config) {
// await octokit.rest.issues.update({
// owner: config.owner,
// repo: config.repo,
// issue_number: config.issue_number,
// labels: config.labels,
// })
// }
async function main() {
const options = {
title: TITLE,
base: BASE,
head: HEAD,
body: fs.readFileSync(BODY_FILE, 'utf8'),
labels: ['translation-batch', `translation-batch-${LANGUAGE}`],
owner: OWNER,
repo: REPO,
retryStatuses: RETRY_STATUSES,
retryCount: RETRY_ATTEMPTS,
}
options.issue_number = await findOrCreatePullRequest(options)
const pr = `${GITHUB_REPOSITORY}#${options.issue_number}`
console.log(`Created PR ${pr}`)
// metadata parameters aren't currently available in `github.rest.pulls.create`,
// but they are in `github.rest.issues.update`.
// await labelPullRequest(options)
// console.log(`Updated ${pr} with these labels: ${options.labels.join(', ')}`)
}
main()

View File

@@ -59,7 +59,7 @@ export async function addItemsToProject(items, project) {
`
const newItems = await graphql(mutation, {
project: project,
project,
headers: {
authorization: `token ${process.env.TOKEN}`,
'GraphQL-Features': 'projects_next_graphql',
@@ -221,40 +221,40 @@ export function generateUpdateProjectNextItemFieldMutation({
$authorID: ID!
) {
${generateMutationToUpdateField({
item: item,
item,
fieldID: '$statusID',
value: '$statusValueID',
})}
${generateMutationToUpdateField({
item: item,
item,
fieldID: '$datePostedID',
value: formatDateForProject(datePosted),
literal: true,
})}
${generateMutationToUpdateField({
item: item,
item,
fieldID: '$reviewDueDateID',
value: formatDateForProject(dueDate),
literal: true,
})}
${generateMutationToUpdateField({
item: item,
item,
fieldID: '$contributorTypeID',
value: '$contributorType',
})}
${generateMutationToUpdateField({
item: item,
item,
fieldID: '$sizeTypeID',
value: '$sizeType',
})}
${generateMutationToUpdateField({
item: item,
item,
fieldID: '$featureID',
value: feature,
literal: true,
})}
${generateMutationToUpdateField({
item: item,
item,
fieldID: '$authorID',
value: author,
literal: true,

View File

@@ -171,8 +171,8 @@ async function run() {
const updateProjectNextItemMutation = generateUpdateProjectNextItemFieldMutation({
item: newItemID,
author: firstTimeContributor ? 'first time contributor' : process.env.AUTHOR_LOGIN,
turnaround: turnaround,
feature: feature,
turnaround,
feature,
})
// Determine which variable to use for the contributor type
@@ -192,16 +192,16 @@ async function run() {
await graphql(updateProjectNextItemMutation, {
project: projectID,
statusID: statusID,
statusID,
statusValueID: readyForReviewID,
datePostedID: datePostedID,
reviewDueDateID: reviewDueDateID,
contributorTypeID: contributorTypeID,
contributorType: contributorType,
sizeTypeID: sizeTypeID,
sizeType: sizeType,
featureID: featureID,
authorID: authorID,
datePostedID,
reviewDueDateID,
contributorTypeID,
contributorType,
sizeTypeID,
sizeType,
featureID,
authorID,
headers: {
authorization: `token ${process.env.TOKEN}`,
'GraphQL-Features': 'projects_next_graphql',

View File

@@ -1,7 +1,7 @@
## Author self-review
- [ ] The changes in this PR meet the user experience and goals outlined in the content design plan.
- [ ] I've compared my PR's source changes to staging and reviewed for versioning issues, redirects, the [style guide](https://github.com/github/docs/blob/main/contributing/content-style-guide.md), [content model](https://github.com/github/docs-content-strategy/blob/main/content-design/models.md), or [localization checklist](https://github.com/github/docs/blob/main/contributing/localization-checklist.md) rendering problems, typos, and wonky screenshots.
- [ ] I've compared my PR's source changes to staging and reviewed for versioning issues, redirects, the [style guide](https://github.com/github/docs/blob/main/contributing/content-style-guide.md), [content model](https://github.com/github/docs/blob/main/contributing/content-model.md), or [localization checklist](https://github.com/github/docs/blob/main/contributing/localization-checklist.md) rendering problems, typos, and wonky screenshots.
- [ ] I've worked through build failures and tests are passing.
- [ ] For REST API content, I've verified that endpoints, parameters, and responses are correct and work as expected and provided curl samples below.

View File

@@ -45,7 +45,7 @@ jobs:
- name: Setup Node
uses: actions/setup-node@1f8c6b94b26d0feae1e387ca63ccbdc44d27b561
with:
node-version: 16.14.x
node-version: 16.15.x
cache: npm
- name: Install dependencies

View File

@@ -187,6 +187,8 @@ jobs:
cache-from: type=registry,ref=${{ secrets.NONPROD_REGISTRY_SERVER }}/${{ github.repository }}:main-preview
# `main-docker-cache.yml` handles updating the remote cache so we don't pollute it with PR specific code
cache-to: ''
build-args: |
BUILD_SHA=${{ github.sha }}
# Succeed despite any non-zero exit code (e.g. if there is no deployment to cancel)
- name: 'Cancel any existing deployments for this PR'
@@ -208,6 +210,3 @@ jobs:
dockerRegistryUrl="${{ secrets.NONPROD_REGISTRY_SERVER }}"
dockerRegistryUsername="${{ env.NONPROD_REGISTRY_USERNAME }}"
dockerRegistryPassword="${{ secrets.NONPROD_REGISTRY_PASSWORD }}"
# this shows warnings in the github actions console, because the flag is passed through a validation run,
# but it *is* functional during the actual execution
additionalArguments: --no-wait

View File

@@ -62,7 +62,7 @@ jobs:
- name: Setup node
uses: actions/setup-node@1f8c6b94b26d0feae1e387ca63ccbdc44d27b561
with:
node-version: 16.14.x
node-version: 16.15.x
cache: npm
- name: Clone docs-early-access
@@ -85,17 +85,19 @@ jobs:
tags: ${{ env.DOCKER_IMAGE }}, ${{ env.DOCKER_IMAGE_CACHE_REF }}
cache-from: type=registry,ref=${{ env.DOCKER_IMAGE_CACHE_REF }}
cache-to: type=registry,mode=max,ref=${{ env.DOCKER_IMAGE_CACHE_REF }}
build-args: |
BUILD_SHA=${{ github.sha }}
- name: 'Update docker-compose.prod.yaml template file'
run: |
sed 's|#{IMAGE}#|${{ env.DOCKER_IMAGE }}|g' docker-compose.prod.tmpl.yaml > docker-compose.prod.yaml
- name: 'Apply updated docker-compose.prod.yaml config to staging slot'
- name: 'Apply updated docker-compose.prod.yaml config to canary slot'
run: |
az webapp config container set --multicontainer-config-type COMPOSE --multicontainer-config-file docker-compose.prod.yaml --slot staging -n ghdocs-prod -g docs-prod
az webapp config container set --multicontainer-config-type COMPOSE --multicontainer-config-file docker-compose.prod.yaml --slot canary -n ghdocs-prod -g docs-prod
# Watch staging slot instances to see when all the instances are ready
- name: Check that staging slot is ready
# Watch canary slot instances to see when all the instances are ready
- name: Check that canary slot is ready
uses: actions/github-script@2b34a689ec86a68d8ab9478298f91d5401337b7d
env:
CHECK_INTERVAL: 10000
@@ -115,7 +117,7 @@ jobs:
let hasStopped = false
const waitDuration = parseInt(process.env.CHECK_INTERVAL, 10) || 10000
async function doCheck() {
const states = getStatesForSlot('staging')
const states = getStatesForSlot('canary')
console.log(`Instance states:`, states)
// We must wait until at-least 1 instance has STOPPED to know we're looking at the "next" deployment and not the "previous" one
@@ -136,10 +138,10 @@ jobs:
doCheck()
# TODO - make a request to verify the staging app version aligns with *this* github action workflow commit sha
- name: 'Swap staging slot to production'
# TODO - make a request to verify the canary app version aligns with *this* github action workflow commit sha
- name: 'Swap canary slot to production'
run: |
az webapp deployment slot swap --slot staging --target-slot production -n ghdocs-prod -g docs-prod
az webapp deployment slot swap --slot canary --target-slot production -n ghdocs-prod -g docs-prod
- name: Purge Fastly edge cache
env:

View File

@@ -0,0 +1,31 @@
name: Azure Staging - Build and Deploy
# **What it does**: Builds and deploys a branch/PR to staging
# **Why we have it**: To enable us to deploy a branch/PR to staging whenever necessary
# **Who does it impact**: All contributors.
on:
workflow_dispatch:
inputs:
PR_NUMBER:
description: 'PR Number'
type: string
required: true
COMMIT_REF:
description: 'The commit SHA to build'
type: string
required: true
permissions:
contents: read
deployments: write
jobs:
azure-staging-build-and-deploy:
if: ${{ github.repository == 'github/docs-internal' }}
runs-on: ubuntu-latest
steps:
- name: 'No-op'
run: |
echo "No-op"

View File

@@ -42,7 +42,7 @@ jobs:
- name: Setup Node
uses: actions/setup-node@1f8c6b94b26d0feae1e387ca63ccbdc44d27b561
with:
node-version: 16.14.x
node-version: 16.15.x
cache: npm
- name: Install dependencies

View File

@@ -30,17 +30,34 @@ jobs:
- name: Setup Node
uses: actions/setup-node@1f8c6b94b26d0feae1e387ca63ccbdc44d27b561
with:
node-version: 16.14.x
node-version: 16.15.x
cache: npm
- name: npm ci
- name: Install dependencies
run: npm ci
- name: Cache nextjs build
uses: actions/cache@48af2dc4a9e8278b89d7fa154b955c30c6aaab09
with:
path: .next/cache
key: ${{ runner.os }}-nextjs-${{ hashFiles('package*.json') }}
- name: npm run build
- name: Build server
run: npm run build
- name: Start server in the background
env:
NODE_ENV: production
PORT: 4000
DISABLE_OVERLOAD_PROTECTION: true
DISABLE_RENDER_CACHING: true
# We don't want or need the changelog entries in this context.
CHANGELOG_DISABLED: true
run: |
node server.mjs &
sleep 5
curl --retry-connrefused --retry 3 -I http://localhost:4000/
- name: Run script
run: |
script/check-english-links.js > broken_links.md
@@ -53,6 +70,16 @@ jobs:
#
# https://docs.github.com/actions/reference/context-and-expression-syntax-for-github-actions#job-status-check-functions
- if: ${{ failure() }}
name: Debug broken_links.md
run: |
ls -lh broken_links.md
wc -l broken_links.md
- uses: actions/upload-artifact@6673cd052c4cd6fcf4b4e6e60ea986c889389535
if: ${{ failure() }}
with:
name: broken_links
path: ./broken_links.md
- if: ${{ failure() }}
name: Get title for issue
id: check
@@ -63,7 +90,6 @@ jobs:
uses: peter-evans/create-issue-from-file@b4f9ee0a9d4abbfc6986601d9b1a4f8f8e74c77e
with:
token: ${{ env.GITHUB_TOKEN }}
title: ${{ steps.check.outputs.title }}
content-filepath: ./broken_links.md
repository: ${{ env.REPORT_REPOSITORY }}

View File

@@ -44,7 +44,7 @@ jobs:
- name: Setup Node
uses: actions/setup-node@1f8c6b94b26d0feae1e387ca63ccbdc44d27b561
with:
node-version: 16.14.x
node-version: 16.15.x
cache: npm
- name: Install Node.js dependencies
@@ -57,6 +57,11 @@ jobs:
env:
NODE_ENV: production
PORT: 4000
# Overload protection is on by default (when NODE_ENV==production)
# but it would help in this context.
DISABLE_OVERLOAD_PROTECTION: true
# Render caching won't help when we visit every page exactly once.
DISABLE_RENDERING_CACHE: true
run: |
node server.mjs &

View File

@@ -39,7 +39,7 @@ jobs:
- name: Setup node
uses: actions/setup-node@1f8c6b94b26d0feae1e387ca63ccbdc44d27b561
with:
node-version: 16.14.x
node-version: 16.15.x
cache: npm
- name: Install dependencies

View File

@@ -59,7 +59,7 @@ jobs:
- name: Setup Node
uses: actions/setup-node@1f8c6b94b26d0feae1e387ca63ccbdc44d27b561
with:
node-version: 16.14.x
node-version: 16.15.x
cache: npm
- name: Install temporary dependencies

View File

@@ -118,7 +118,7 @@ jobs:
- name: 'Setup node'
uses: actions/setup-node@1f8c6b94b26d0feae1e387ca63ccbdc44d27b561
with:
node-version: 16.14.x
node-version: 16.15.x
- run: npm ci

View File

@@ -31,7 +31,7 @@ jobs:
- name: Setup Node
uses: actions/setup-node@1f8c6b94b26d0feae1e387ca63ccbdc44d27b561
with:
node-version: 16.14.x
node-version: 16.15.x
cache: npm
- name: Install dependencies

View File

@@ -25,7 +25,7 @@ jobs:
- name: Setup Node
uses: actions/setup-node@1f8c6b94b26d0feae1e387ca63ccbdc44d27b561
with:
node-version: 16.14.x
node-version: 16.15.x
cache: npm
- name: Install dependencies

View File

@@ -41,7 +41,7 @@ jobs:
- name: Setup Node
uses: actions/setup-node@1f8c6b94b26d0feae1e387ca63ccbdc44d27b561
with:
node-version: 16.14.x
node-version: 16.15.x
cache: npm
- name: Install Node.js dependencies

View File

@@ -52,7 +52,7 @@ jobs:
- name: Setup Node
uses: actions/setup-node@1f8c6b94b26d0feae1e387ca63ccbdc44d27b561
with:
node-version: 16.14.x
node-version: 16.15.x
cache: npm
- name: Install dependencies

View File

@@ -32,7 +32,7 @@ jobs:
- name: Setup node
uses: actions/setup-node@1f8c6b94b26d0feae1e387ca63ccbdc44d27b561
with:
node-version: 16.14.x
node-version: 16.15.x
cache: npm
- name: Install

View File

@@ -0,0 +1,204 @@
name: Create translation Batch Pull Request
# **What it does**:
# - Creates one pull request per language after running a series of automated checks,
# removing translations that are broken in any known way
# **Why we have it**:
# - To deploy translations
# **Who does it impact**: It automates what would otherwise be manual work,
# helping docs engineering focus on higher value work
on:
workflow_dispatch:
# TODO: bring schedule back in
# schedule:
# - cron: '02 17 * * *' # Once a day at 17:02 UTC / 9:02 PST
permissions:
contents: write
jobs:
create-translation-batch:
name: Create translation batch
if: github.repository == 'github/docs-internal'
runs-on: ubuntu-latest
# A sync's average run time is ~3.2 hours.
# This sets a maximum execution time of 300 minutes (5 hours) to prevent the workflow from running longer than necessary.
timeout-minutes: 300
strategy:
fail-fast: false
max-parallel: 1
matrix:
include:
# TODO: replace language_repos with actual repos once created
# - language: pt
# crowdin_language: pt-BR
# language_dir: translations/pt-BR
# language_repo: github/docs-translations-pt-br
- language: es
crowdin_language: es-ES
language_dir: translations/es-ES
language_repo: github/docs-localization-test-es-es
# - language: cn
# crowdin_language: zh-CN
# language_dir: translations/zh-CN
# language_repo: github/docs-translations-zh-cn
# - language: ja
# crowdin_language: ja
# language_dir: translations/ja-JP
# language_repo: github/docs-translations-ja-jp
# TODO: replace the branch name
steps:
- name: Set branch name
id: set-branch
run: |
echo "::set-output name=BRANCH_NAME::msft-translation-batch-${{ matrix.language }}-$(date +%Y-%m-%d__%H-%M)"
- run: git config --global user.name "docubot"
- run: git config --global user.email "67483024+docubot@users.noreply.github.com"
- name: Checkout the docs-internal repo
uses: actions/checkout@dcd71f646680f2efd8db4afa5ad64fdcba30e748
with:
fetch-depth: 0
lfs: true
- name: Create a branch for the current language
run: git checkout -b ${{ steps.set-branch.outputs.BRANCH_NAME }}
- name: Remove unwanted git hooks
run: rm .git/hooks/post-checkout
- name: Remove all language translations
run: |
git rm -rf --quiet ${{ matrix.language_dir }}/content
git rm -rf --quiet ${{ matrix.language_dir }}/data
- name: Checkout the language-specific repo
uses: actions/checkout@dcd71f646680f2efd8db4afa5ad64fdcba30e748
with:
repository: ${{ matrix.language_repo }}
token: ${{ secrets.DOCUBOT_READORG_REPO_WORKFLOW_SCOPES }}
path: ${{ matrix.language_dir }}
- name: Remove .git from the language-specific repo
run: rm -rf ${{ matrix.language_dir }}/.git
# TODO: Rename this step
- name: Commit crowdin sync
run: |
git add ${{ matrix.language_dir }}
git commit -m "Add crowdin translations" || echo "Nothing to commit"
- name: 'Setup node'
uses: actions/setup-node@1f8c6b94b26d0feae1e387ca63ccbdc44d27b561
with:
node-version: 16.15.x
- run: npm ci
# step 6 in docs-engineering/crowdin.md
- name: Homogenize frontmatter
run: |
node script/i18n/homogenize-frontmatter.js
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
- name: Fix translation errors
run: |
node script/i18n/fix-translation-errors.js
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
- name: Check parsing
run: |
node script/i18n/lint-translation-files.js --check parsing | tee -a /tmp/batch.log | cat
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
- name: Check rendering
run: |
node script/i18n/lint-translation-files.js --check rendering | tee -a /tmp/batch.log | cat
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: Write the reported files that were reset to /tmp/pr-body.txt
run: script/i18n/report-reset-files.js --report-type=pull-request-body --language=${{ matrix.language }} --log-file=/tmp/batch.log > /tmp/pr-body.txt
- name: Push filtered translations
run: git push origin ${{ steps.set-branch.outputs.BRANCH_NAME }}
# TODO: bring this step back
# - name: Close existing stale batches
# uses: lee-dohm/close-matching-issues@e9e43aad2fa6f06a058cedfd8fb975fd93b56d8f
# with:
# token: ${{ secrets.OCTOMERGER_PAT_WITH_REPO_AND_WORKFLOW_SCOPE }}
# query: 'type:pr label:translation-batch-${{ matrix.language }}'
# TODO: bring labels back into the PR script
- name: Create translation batch pull request
env:
GITHUB_TOKEN: ${{ secrets.DOCUBOT_REPO_PAT }}
TITLE: '[DO NOT MERGE] Msft: New translation batch for ${{ matrix.language }}'
BASE: 'main'
HEAD: ${{ steps.set-branch.outputs.BRANCH_NAME }}
LANGUAGE: ${{ matrix.language }}
BODY_FILE: '/tmp/pr-body.txt'
run: .github/actions-scripts/msft-create-translation-batch-pr.js
# TODO: bring back these steps
# - name: Approve PR
# if: github.ref_name == 'main'
# env:
# GITHUB_TOKEN: ${{ secrets.OCTOMERGER_PAT_WITH_REPO_AND_WORKFLOW_SCOPE }}
# run: gh pr review --approve || echo "Nothing to approve"
# - name: Set auto-merge
# if: github.ref_name == 'main'
# env:
# GITHUB_TOKEN: ${{ secrets.OCTOMERGER_PAT_WITH_REPO_AND_WORKFLOW_SCOPE }}
# run: gh pr merge ${{ steps.set-branch.outputs.BRANCH_NAME }} --auto --squash || echo "Nothing to merge"
# # 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.
# - name: Send Slack notification if workflow is cancelled
# uses: someimportantcompany/github-actions-slack-message@f8d28715e7b8a4717047d23f48c39827cacad340
# if: cancelled()
# with:
# channel: ${{ secrets.DOCS_ALERTS_SLACK_CHANNEL_ID }}
# bot-token: ${{ secrets.SLACK_DOCS_BOT_TOKEN }}
# color: failure
# text: 'The new translation batch for ${{ matrix.language }} was cancelled.'
# # Emit a notification for the first responder to triage if the workflow failed.
# - name: Send Slack notification if workflow failed
# uses: someimportantcompany/github-actions-slack-message@f8d28715e7b8a4717047d23f48c39827cacad340
# if: failure()
# with:
# channel: ${{ secrets.DOCS_ALERTS_SLACK_CHANNEL_ID }}
# bot-token: ${{ secrets.SLACK_DOCS_BOT_TOKEN }}
# color: failure
# text: 'The new translation batch for ${{ matrix.language }} failed.'

View File

@@ -16,7 +16,7 @@ permissions:
jobs:
add-issue-comment:
if: ${{ github.repository == 'github/docs' && (github.event.label.name == 'needs SME' && github.event_name == 'issues' || github.event_name == 'pull_request_target') }}
if: ${{ github.repository == 'github/docs' && (github.event.label.name == 'needs SME' && github.event_name == 'issues') }}
runs-on: ubuntu-latest
steps:
- uses: peter-evans/create-or-update-comment@a35cf36e5301d70b76f316e867e7788a55a31dae
@@ -26,7 +26,7 @@ jobs:
Thanks for opening an issue! We've triaged this issue for technical review by a subject matter expert :eyes:
add-pr-comment:
if: ${{ github.repository == 'github/docs' && github.event.label.name == 'needs SME' }}
if: ${{ github.repository == 'github/docs' && (github.event.label.name == 'needs SME' && github.event_name == 'pull_request_target') }}
runs-on: ubuntu-latest
steps:
- uses: peter-evans/create-or-update-comment@a35cf36e5301d70b76f316e867e7788a55a31dae

View File

@@ -24,7 +24,7 @@ jobs:
- name: Setup Node
uses: actions/setup-node@1f8c6b94b26d0feae1e387ca63ccbdc44d27b561
with:
node-version: 16.14.x
node-version: 16.15.x
cache: npm
- name: Install dependencies

View File

@@ -44,7 +44,7 @@ jobs:
- name: Setup node
uses: actions/setup-node@1f8c6b94b26d0feae1e387ca63ccbdc44d27b561
with:
node-version: 16.14.x
node-version: 16.15.x
cache: npm
- name: Install dependencies

View File

@@ -44,7 +44,7 @@ jobs:
- name: Setup node
uses: actions/setup-node@1f8c6b94b26d0feae1e387ca63ccbdc44d27b561
with:
node-version: 16.14.x
node-version: 16.15.x
cache: npm
- name: Install dependencies

View File

@@ -27,7 +27,7 @@ jobs:
- name: Setup node
uses: actions/setup-node@1f8c6b94b26d0feae1e387ca63ccbdc44d27b561
with:
node-version: 16.14.x
node-version: 16.15.x
cache: npm
- name: Install

View File

@@ -49,7 +49,7 @@ jobs:
- name: Setup Node
uses: actions/setup-node@1f8c6b94b26d0feae1e387ca63ccbdc44d27b561
with:
node-version: 16.14.x
node-version: 16.15.x
cache: npm
- name: Install dependencies

View File

@@ -23,7 +23,7 @@ jobs:
- name: Setup Node
uses: actions/setup-node@1f8c6b94b26d0feae1e387ca63ccbdc44d27b561
with:
node-version: 16.14.x
node-version: 16.15.x
cache: npm
- name: Install dependencies

View File

@@ -29,7 +29,7 @@ jobs:
- name: Setup Node
uses: actions/setup-node@1f8c6b94b26d0feae1e387ca63ccbdc44d27b561
with:
node-version: 16.14.x
node-version: 16.15.x
- name: Run check
run: |

View File

@@ -25,7 +25,7 @@ jobs:
- name: Setup Node
uses: actions/setup-node@1f8c6b94b26d0feae1e387ca63ccbdc44d27b561
with:
node-version: 16.14.x
node-version: 16.15.x
cache: npm
- name: Install dependencies

View File

@@ -29,7 +29,7 @@ jobs:
- name: Setup Node
uses: actions/setup-node@1f8c6b94b26d0feae1e387ca63ccbdc44d27b561
with:
node-version: 16.14.x
node-version: 16.15.x
cache: npm
- name: npm ci
run: npm ci

View File

@@ -104,7 +104,7 @@ jobs:
- name: Setup node
uses: actions/setup-node@1f8c6b94b26d0feae1e387ca63ccbdc44d27b561
with:
node-version: 16.14.x
node-version: 16.15.x
cache: npm
- name: Install dependencies
run: npm ci

View File

@@ -58,7 +58,7 @@ jobs:
- name: Setup Node
uses: actions/setup-node@1f8c6b94b26d0feae1e387ca63ccbdc44d27b561
with:
node-version: 16.14.x
node-version: 16.15.x
cache: npm
- name: Install dependencies
@@ -89,6 +89,12 @@ jobs:
# But that'll get fixed in the next translation pipeline. For now,
# let's just accept an empty string instead.
THROW_ON_EMPTY: false
# Because the overload protection runs in NODE_ENV==production
# and it can break the sync-search.
DISABLE_OVERLOAD_PROTECTION: true
# Render caching won't help when we visit every page exactly once.
DISABLE_RENDERING_CACHE: true
run: npm run sync-search
- name: Update private docs repository search indexes

View File

@@ -31,7 +31,7 @@ jobs:
- name: Setup node
uses: actions/setup-node@1f8c6b94b26d0feae1e387ca63ccbdc44d27b561
with:
node-version: 16.14.x
node-version: 16.15.x
cache: npm
- name: Install dependencies
@@ -51,4 +51,7 @@ jobs:
# Set filtered to only these so it doesn't run for too long.
LANGUAGE: en
VERSION: free-pro-team@latest
# Because the overload protection runs in NODE_ENV==production
# and it can break the sync-search.
DISABLE_OVERLOAD_PROTECTION: true
run: npm run sync-search

View File

@@ -125,7 +125,7 @@ jobs:
- name: Setup node
uses: actions/setup-node@1f8c6b94b26d0feae1e387ca63ccbdc44d27b561
with:
node-version: 16.14.x
node-version: 16.15.x
cache: npm
- name: Install dependencies

View File

@@ -61,7 +61,7 @@ jobs:
- name: Setup Node
uses: actions/setup-node@1f8c6b94b26d0feae1e387ca63ccbdc44d27b561
with:
node-version: 16.14.x
node-version: 16.15.x
cache: npm
- name: Install dependencies

View File

@@ -36,7 +36,7 @@ jobs:
- name: Setup Node
uses: actions/setup-node@1f8c6b94b26d0feae1e387ca63ccbdc44d27b561
with:
node-version: 16.14.x
node-version: 16.15.x
cache: npm
- name: Install Node.js dependencies
run: npm ci

View File

@@ -3,7 +3,7 @@
# --------------------------------------------------------------------------------
# BASE IMAGE
# --------------------------------------------------------------------------------
FROM node:16.13.2-alpine@sha256:f21f35732964a96306a84a8c4b5a829f6d3a0c5163237ff4b6b8b34f8d70064b as base
FROM node:16.15.0-alpine@sha256:1a9a71ea86aad332aa7740316d4111ee1bd4e890df47d3b5eff3e5bded3b3d10 as base
# This directory is owned by the node user
ARG APP_HOME=/home/node/app
@@ -78,6 +78,11 @@ ENV PORT 4000
ENV ENABLED_LANGUAGES "en"
# This makes it possible to set `--build-arg BUILD_SHA=abc123`
# and it then becomes available as an environment variable in the docker run.
ARG BUILD_SHA
ENV BUILD_SHA=$BUILD_SHA
# Copy only what's needed to run the server
COPY --chown=node:node package.json ./
COPY --chown=node:node assets ./assets

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 84 KiB

After

Width:  |  Height:  |  Size: 852 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 236 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 51 KiB

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 222 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 225 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 190 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.9 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

View File

@@ -27,6 +27,7 @@ export const DefaultLayout = (props: Props) => {
const { t } = useTranslation(['errors', 'meta', 'scroll_button'])
const router = useRouter()
const metaDescription = page.introPlainText ? page.introPlainText : t('default_description')
return (
<div className="d-lg-flex">
<Head>

View File

@@ -2,7 +2,7 @@ import React, { useState, useEffect, useRef, ReactNode, RefObject } from 'react'
import { useRouter } from 'next/router'
import useSWR from 'swr'
import cx from 'classnames'
import { ActionList, DropdownMenu, Flash, Label, Overlay } from '@primer/react'
import { ActionList, DropdownMenu, Flash, Label } from '@primer/react'
import { ItemInput } from '@primer/react/lib/ActionList/List'
import { useTranslation } from 'components/hooks/useTranslation'
@@ -287,8 +287,6 @@ function useDebounce<T>(value: T, delay?: number): [T, (value: T) => void] {
function ShowSearchError({
error,
isHeaderSearch,
isMobileSearch,
}: {
error: Error
isHeaderSearch: boolean
@@ -296,10 +294,7 @@ function ShowSearchError({
}) {
const { t } = useTranslation('search')
return (
<Flash
variant="danger"
sx={{ margin: isMobileSearch || isHeaderSearch ? '2rem 2rem 0 2em' : '1rem' }}
>
<Flash variant="danger" sx={{ margin: '2rem 2rem 0 2em' }}>
<p>{t('search_error')}</p>
{process.env.NODE_ENV === 'development' && (
<p>
@@ -313,12 +308,9 @@ function ShowSearchError({
}
function ShowSearchResults({
anchorRef,
isHeaderSearch,
isMobileSearch,
isLoading,
results,
closeSearch,
debug,
query,
}: {
@@ -490,49 +482,7 @@ function ShowSearchResults({
/>
</div>
)
// When there are search results, it doesn't matter if this is overlay or not.
return (
<div>
{!isHeaderSearch && !isMobileSearch ? (
<>
<Overlay
initialFocusRef={anchorRef}
returnFocusRef={anchorRef}
ignoreClickRefs={[anchorRef]}
onEscape={() => closeSearch()}
onClickOutside={() => closeSearch()}
aria-labelledby="title"
sx={
isHeaderSearch
? {
background: 'none',
boxShadow: 'none',
position: 'static',
overflowY: 'auto',
maxHeight: '80vh',
maxWidth: '96%',
margin: '1.5em 2em 0 0.5em',
scrollbarWidth: 'none',
}
: window.innerWidth < 1012
? {
marginTop: '28rem',
marginLeft: '5rem',
}
: {
marginTop: '15rem',
marginLeft: '5rem',
}
}
>
{ActionListResults}
</Overlay>
</>
) : (
ActionListResults
)}
</div>
)
return <div>{ActionListResults}</div>
}
// We have no results at all, but perhaps we're waiting.

View File

@@ -62,9 +62,9 @@ const SidebarContent = styled(Box)`
@media (min-width: ${themeGet('breakpoints.3')}) {
position: sticky;
padding-top: ${themeGet('space.4')};
top: 4em;
max-height: 75vh;
top: 5em;
max-height: calc(100vh - 5em);
overflow-y: auto;
padding-bottom: ${themeGet('space.4')};
padding-bottom: ${themeGet('space.6')} !important;
}
`

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