1
0
mirror of synced 2026-01-03 15:05:54 -05:00

Merge branch 'main' into open-palette

This commit is contained in:
Ramya Parimi
2022-01-13 08:29:21 -06:00
committed by GitHub
3879 changed files with 96199 additions and 94169 deletions

1
.github/CODEOWNERS vendored
View File

@@ -17,6 +17,7 @@ package-lock.json @github/docs-engineering
package.json @github/docs-engineering
# Localization
/.github/actions-scripts/create-translation-batch-pr.js @github/docs-localization
/.github/workflows/create-translation-batch-pr.yml @github/docs-localization
/.github/workflows/crowdin.yml @github/docs-localization
/crowdin*.yml @github/docs-engineering @github/docs-localization

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

@@ -43,7 +43,7 @@ jobs:
uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
- name: Setup Node
uses: actions/setup-node@04c56d2f954f1e4c69436aa54cfef261a018f458
uses: actions/setup-node@1f8c6b94b26d0feae1e387ca63ccbdc44d27b561
with:
node-version: 16.13.x
cache: npm

View File

@@ -40,7 +40,7 @@ jobs:
run: git lfs checkout
- name: Setup Node
uses: actions/setup-node@04c56d2f954f1e4c69436aa54cfef261a018f458
uses: actions/setup-node@1f8c6b94b26d0feae1e387ca63ccbdc44d27b561
with:
node-version: 16.13.x
cache: npm
@@ -54,13 +54,13 @@ jobs:
run: npm ci --include=optional
- name: Cache nextjs build
uses: actions/cache@c64c572235d810460d0d6876e9c705ad5002b353
uses: actions/cache@937d24475381cd9c75ae6db12cb4e79714b926ed
with:
path: .next/cache
key: ${{ runner.os }}-nextjs-${{ hashFiles('package*.json') }}
- name: Cache lib/redirects/.redirects-cache_en_ja.json
uses: actions/cache@c64c572235d810460d0d6876e9c705ad5002b353
uses: actions/cache@937d24475381cd9c75ae6db12cb4e79714b926ed
with:
path: lib/redirects/.redirects-cache_en_ja.json
key: ${{ runner.os }}-redirects-cache-${{ hashFiles('.github/workflows/browser-test.yml') }}

View File

@@ -28,14 +28,14 @@ jobs:
- name: Check out repo's default branch
uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
- name: Setup Node
uses: actions/setup-node@04c56d2f954f1e4c69436aa54cfef261a018f458
uses: actions/setup-node@1f8c6b94b26d0feae1e387ca63ccbdc44d27b561
with:
node-version: 16.13.x
cache: npm
- name: npm ci
run: npm ci
- name: Cache nextjs build
uses: actions/cache@c64c572235d810460d0d6876e9c705ad5002b353
uses: actions/cache@937d24475381cd9c75ae6db12cb4e79714b926ed
with:
path: .next/cache
key: ${{ runner.os }}-nextjs-${{ hashFiles('package*.json') }}

View File

@@ -42,7 +42,7 @@ jobs:
uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
- name: Setup Node
uses: actions/setup-node@04c56d2f954f1e4c69436aa54cfef261a018f458
uses: actions/setup-node@1f8c6b94b26d0feae1e387ca63ccbdc44d27b561
with:
node-version: 16.13.x
cache: npm

View File

@@ -37,7 +37,7 @@ jobs:
uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
- name: Setup node
uses: actions/setup-node@04c56d2f954f1e4c69436aa54cfef261a018f458
uses: actions/setup-node@1f8c6b94b26d0feae1e387ca63ccbdc44d27b561
with:
node-version: 16.13.x
cache: npm

View File

@@ -0,0 +1,30 @@
name: Prebuild Codespaces
# **What it does**: Prebuild the Codespaces image using powerful machines.
# See https://github.com/github/codespaces-precache#readme for more details.
# IMPORTANT: Requires we set a `EXPERIMENTAL_CODESPACE_CACHE_TOKEN` Codespaces
# Secret (NOT an Actions Secret) in the repository.
# **Why we have it**: Reduces startup time when booting Codespaces.
# **Who does it impact**: Any Docs contributors who want to use Codespaces.
on:
push:
branches:
- main
workflow_dispatch:
# Currently requires write, but in the future will only require read
permissions:
contents: write
jobs:
createPrebuild:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
- uses: github/codespaces-precache@2ad40630d7e3e45e8725d6a74656cb6dd17363dc
with:
regions: WestUs2 EastUs WestEurope SouthEastAsia
sku_name: basicLinux32gb
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -50,7 +50,7 @@ jobs:
uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
- name: Setup Node
uses: actions/setup-node@04c56d2f954f1e4c69436aa54cfef261a018f458
uses: actions/setup-node@1f8c6b94b26d0feae1e387ca63ccbdc44d27b561
with:
node-version: 16.13.x
cache: npm

View File

@@ -116,7 +116,7 @@ jobs:
git commit -m "Add crowdin translations" || echo "Nothing to commit"
- name: 'Setup node'
uses: actions/setup-node@04c56d2f954f1e4c69436aa54cfef261a018f458
uses: actions/setup-node@1f8c6b94b26d0feae1e387ca63ccbdc44d27b561
with:
node-version: '16'
@@ -166,26 +166,27 @@ jobs:
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 }}
- 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 }}'
- name: Create Pull Request
- name: Create translation batch pull request
env:
GITHUB_TOKEN: ${{ secrets.DOCUBOT_REPO_PAT }}
# 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.
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 }}
gh pr create --title "New translation batch for ${{ matrix.language }}" \
--base=main \
--head=${{ steps.set-branch.outputs.BRANCH_NAME }} \
--label "translation-batch-${{ matrix.language }}" \
--label "translation-batch" \
--body-file /tmp/pr-body.txt || git push origin :${{ steps.set-branch.outputs.BRANCH_NAME }}
TITLE: '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/create-translation-batch-pr.js
- name: Approve PR
if: github.ref_name == 'main'

View File

@@ -29,7 +29,7 @@ jobs:
uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
- name: Setup Node
uses: actions/setup-node@04c56d2f954f1e4c69436aa54cfef261a018f458
uses: actions/setup-node@1f8c6b94b26d0feae1e387ca63ccbdc44d27b561
with:
node-version: 16.13.x
cache: npm
@@ -41,7 +41,7 @@ jobs:
run: script/i18n/homogenize-frontmatter.js
- name: Check in homogenized files
uses: EndBug/add-and-commit@2bdc0a61a03738a1d1bda24d566ad0dbe3083d87
uses: EndBug/add-and-commit@8c12ff729a98cfbcd3fe38b49f55eceb98a5ec02
with:
# The arguments for the `git add` command
add: 'translations'

View File

@@ -23,7 +23,7 @@ jobs:
uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
- name: Setup Node
uses: actions/setup-node@04c56d2f954f1e4c69436aa54cfef261a018f458
uses: actions/setup-node@1f8c6b94b26d0feae1e387ca63ccbdc44d27b561
with:
node-version: 16.13.x
cache: npm

View File

@@ -39,7 +39,7 @@ jobs:
uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
- name: Setup Node
uses: actions/setup-node@04c56d2f954f1e4c69436aa54cfef261a018f458
uses: actions/setup-node@1f8c6b94b26d0feae1e387ca63ccbdc44d27b561
with:
node-version: 16.13.x
cache: npm
@@ -55,7 +55,7 @@ jobs:
- name: Create pull request
id: create-pull-request
uses: peter-evans/create-pull-request@7380612b49221684fefa025244f2ef4008ae50ad
uses: peter-evans/create-pull-request@dcd5fd746d53dd8de555c0f10bca6c35628be47a
env:
# Disable pre-commit hooks; they don't play nicely here
HUSKY: '0'

View File

@@ -50,7 +50,7 @@ jobs:
token: ${{ secrets.DOCUBOT_REPO_PAT }}
- name: Setup Node
uses: actions/setup-node@04c56d2f954f1e4c69436aa54cfef261a018f458
uses: actions/setup-node@1f8c6b94b26d0feae1e387ca63ccbdc44d27b561
with:
node-version: 16.13.x
cache: npm
@@ -63,7 +63,7 @@ jobs:
run: $GITHUB_WORKSPACE/.github/actions-scripts/enterprise-search-label.js
- name: Cache nextjs build
uses: actions/cache@c64c572235d810460d0d6876e9c705ad5002b353
uses: actions/cache@937d24475381cd9c75ae6db12cb4e79714b926ed
with:
path: .next/cache
key: ${{ runner.os }}-nextjs-${{ hashFiles('package*.json') }}

View File

@@ -22,14 +22,14 @@ concurrency:
cancel-in-progress: true
jobs:
build:
check-links:
runs-on: ${{ fromJSON('["ubuntu-latest", "self-hosted"]')[github.repository == 'github/docs-internal'] }}
steps:
- name: Checkout
uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
- name: Setup node
uses: actions/setup-node@04c56d2f954f1e4c69436aa54cfef261a018f458
uses: actions/setup-node@1f8c6b94b26d0feae1e387ca63ccbdc44d27b561
with:
node-version: 16.13.x
cache: npm
@@ -37,16 +37,15 @@ jobs:
- name: Install
run: npm ci
# Creates file "${{ env.HOME }}/files.json", among others
- name: Gather files changed
uses: trilom/file-changes-action@a6ca26c14274c33b15e6499323aac178af06ad4b
id: get_diff_files
with:
# So that `steps.get_diff_files.outputs.files` becomes
# a string like `foo.js path/bar.md`
output: ' '
- name: Insight into changed files
run: |
echo "${{ steps.get_diff_files.outputs.files }}"
fileOutput: 'json'
# For verification
- name: Show files changed
run: cat $HOME/files.json
- name: Link check (warnings, changed files)
run: |
@@ -56,7 +55,7 @@ jobs:
--check-anchors \
--check-images \
--verbose \
"${{ steps.get_diff_files.outputs.files }}"
--list $HOME/files.json
- name: Link check (critical, all files)
run: |

View File

@@ -26,7 +26,7 @@ jobs:
uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
- name: Setup node
uses: actions/setup-node@04c56d2f954f1e4c69436aa54cfef261a018f458
uses: actions/setup-node@1f8c6b94b26d0feae1e387ca63ccbdc44d27b561
with:
node-version: 16.13.x
cache: npm
@@ -35,7 +35,7 @@ jobs:
run: npm ci
- name: Cache nextjs build
uses: actions/cache@c64c572235d810460d0d6876e9c705ad5002b353
uses: actions/cache@937d24475381cd9c75ae6db12cb4e79714b926ed
with:
path: .next/cache
key: ${{ runner.os }}-nextjs-${{ hashFiles('package*.json') }}

View File

@@ -26,7 +26,7 @@ jobs:
uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
- name: Setup node
uses: actions/setup-node@04c56d2f954f1e4c69436aa54cfef261a018f458
uses: actions/setup-node@1f8c6b94b26d0feae1e387ca63ccbdc44d27b561
with:
node-version: 16.13.x
cache: npm
@@ -35,7 +35,7 @@ jobs:
run: npm ci
- name: Cache nextjs build
uses: actions/cache@c64c572235d810460d0d6876e9c705ad5002b353
uses: actions/cache@937d24475381cd9c75ae6db12cb4e79714b926ed
with:
path: .next/cache
key: ${{ runner.os }}-nextjs-${{ hashFiles('package*.json') }}

View File

@@ -24,7 +24,7 @@ jobs:
uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
- name: Setup node
uses: actions/setup-node@04c56d2f954f1e4c69436aa54cfef261a018f458
uses: actions/setup-node@1f8c6b94b26d0feae1e387ca63ccbdc44d27b561
with:
node-version: 16.13.x
cache: npm
@@ -33,7 +33,7 @@ jobs:
run: npm ci
- name: Cache nextjs build
uses: actions/cache@c64c572235d810460d0d6876e9c705ad5002b353
uses: actions/cache@937d24475381cd9c75ae6db12cb4e79714b926ed
with:
path: .next/cache
key: ${{ runner.os }}-nextjs-${{ hashFiles('package*.json') }}

View File

@@ -26,7 +26,7 @@ jobs:
uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
- name: Setup node
uses: actions/setup-node@04c56d2f954f1e4c69436aa54cfef261a018f458
uses: actions/setup-node@1f8c6b94b26d0feae1e387ca63ccbdc44d27b561
with:
node-version: 16.13.x
cache: npm
@@ -35,7 +35,7 @@ jobs:
run: npm ci
- name: Cache nextjs build
uses: actions/cache@c64c572235d810460d0d6876e9c705ad5002b353
uses: actions/cache@937d24475381cd9c75ae6db12cb4e79714b926ed
with:
path: .next/cache
key: ${{ runner.os }}-nextjs-${{ hashFiles('package*.json') }}

View File

@@ -22,7 +22,7 @@ jobs:
uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
- name: Setup Node
uses: actions/setup-node@04c56d2f954f1e4c69436aa54cfef261a018f458
uses: actions/setup-node@1f8c6b94b26d0feae1e387ca63ccbdc44d27b561
with:
node-version: 16.13.x
cache: npm

View File

@@ -34,7 +34,7 @@ jobs:
uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
- name: Setup node
uses: actions/setup-node@04c56d2f954f1e4c69436aa54cfef261a018f458
uses: actions/setup-node@1f8c6b94b26d0feae1e387ca63ccbdc44d27b561
with:
node-version: 16.13.x
cache: npm
@@ -46,7 +46,7 @@ jobs:
run: script/rest/update-files.js --decorate-only
- name: Check in the decorated files
uses: EndBug/add-and-commit@2bdc0a61a03738a1d1bda24d566ad0dbe3083d87
uses: EndBug/add-and-commit@8c12ff729a98cfbcd3fe38b49f55eceb98a5ec02
with:
# The arguments for the `git add` command
add: 'lib/rest/static/decorated'

View File

@@ -40,7 +40,7 @@ jobs:
uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
- name: Setup node
uses: actions/setup-node@04c56d2f954f1e4c69436aa54cfef261a018f458
uses: actions/setup-node@1f8c6b94b26d0feae1e387ca63ccbdc44d27b561
with:
node-version: 16.13.x
cache: npm

View File

@@ -18,7 +18,7 @@ jobs:
uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
- name: Setup node
uses: actions/setup-node@04c56d2f954f1e4c69436aa54cfef261a018f458
uses: actions/setup-node@1f8c6b94b26d0feae1e387ca63ccbdc44d27b561
with:
node-version: 16.13.x
cache: npm

View File

@@ -47,7 +47,7 @@ jobs:
uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
- name: Setup Node
uses: actions/setup-node@04c56d2f954f1e4c69436aa54cfef261a018f458
uses: actions/setup-node@1f8c6b94b26d0feae1e387ca63ccbdc44d27b561
with:
node-version: 16.x
cache: npm

View File

@@ -21,7 +21,7 @@ jobs:
uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
- name: Setup Node
uses: actions/setup-node@04c56d2f954f1e4c69436aa54cfef261a018f458
uses: actions/setup-node@1f8c6b94b26d0feae1e387ca63ccbdc44d27b561
with:
node-version: 16.13.x
cache: npm
@@ -30,7 +30,7 @@ jobs:
run: npm ci --include=optional
- name: Cache nextjs build
uses: actions/cache@c64c572235d810460d0d6876e9c705ad5002b353
uses: actions/cache@937d24475381cd9c75ae6db12cb4e79714b926ed
with:
path: .next/cache
key: ${{ runner.os }}-nextjs-${{ hashFiles('package*.json') }}

View File

@@ -27,7 +27,7 @@ jobs:
uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
- name: Setup Node
uses: actions/setup-node@04c56d2f954f1e4c69436aa54cfef261a018f458
uses: actions/setup-node@1f8c6b94b26d0feae1e387ca63ccbdc44d27b561
with:
node-version: 16.x

View File

@@ -21,7 +21,7 @@ jobs:
steps:
- uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
- name: Setup node
uses: actions/setup-node@04c56d2f954f1e4c69436aa54cfef261a018f458
uses: actions/setup-node@1f8c6b94b26d0feae1e387ca63ccbdc44d27b561
with:
node-version: 16.13.x
cache: npm

View File

@@ -51,7 +51,7 @@ jobs:
run: git lfs checkout
- name: Setup node
uses: actions/setup-node@04c56d2f954f1e4c69436aa54cfef261a018f458
uses: actions/setup-node@1f8c6b94b26d0feae1e387ca63ccbdc44d27b561
with:
node-version: 16.13.x
cache: npm

View File

@@ -36,7 +36,7 @@ jobs:
run: git lfs checkout
- name: Setup node
uses: actions/setup-node@04c56d2f954f1e4c69436aa54cfef261a018f458
uses: actions/setup-node@1f8c6b94b26d0feae1e387ca63ccbdc44d27b561
with:
node-version: 16.13.x
cache: npm
@@ -55,7 +55,7 @@ jobs:
GIT_BRANCH: main
- name: Cache nextjs build
uses: actions/cache@c64c572235d810460d0d6876e9c705ad5002b353
uses: actions/cache@937d24475381cd9c75ae6db12cb4e79714b926ed
with:
path: .next/cache
key: ${{ runner.os }}-nextjs-${{ hashFiles('package*.json') }}

View File

@@ -21,7 +21,7 @@ jobs:
uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
- name: Setup Node
uses: actions/setup-node@04c56d2f954f1e4c69436aa54cfef261a018f458
uses: actions/setup-node@1f8c6b94b26d0feae1e387ca63ccbdc44d27b561
with:
node-version: 16.13.x
cache: npm

View File

@@ -30,7 +30,7 @@ jobs:
uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
- name: Setup Node
uses: actions/setup-node@04c56d2f954f1e4c69436aa54cfef261a018f458
uses: actions/setup-node@1f8c6b94b26d0feae1e387ca63ccbdc44d27b561
with:
node-version: 16.13.x
cache: npm
@@ -52,7 +52,7 @@ jobs:
uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
- name: Setup Node
uses: actions/setup-node@04c56d2f954f1e4c69436aa54cfef261a018f458
uses: actions/setup-node@1f8c6b94b26d0feae1e387ca63ccbdc44d27b561
with:
node-version: 16.13.x
cache: npm

View File

@@ -27,7 +27,7 @@ jobs:
- name: Checkout
uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
- name: Setup Node
uses: actions/setup-node@04c56d2f954f1e4c69436aa54cfef261a018f458
uses: actions/setup-node@1f8c6b94b26d0feae1e387ca63ccbdc44d27b561
with:
node-version: 16.13.x
cache: npm
@@ -44,7 +44,7 @@ jobs:
- name: Remove script results file
run: rm ./results.md
- name: Create pull request
uses: peter-evans/create-pull-request@7380612b49221684fefa025244f2ef4008ae50ad
uses: peter-evans/create-pull-request@dcd5fd746d53dd8de555c0f10bca6c35628be47a
env:
# Disable pre-commit hooks; they don't play nicely here
HUSKY: '0'

View File

@@ -102,7 +102,7 @@ jobs:
# Set up npm and run npm ci to run husky to get githooks for LFS
- name: Setup node
uses: actions/setup-node@04c56d2f954f1e4c69436aa54cfef261a018f458
uses: actions/setup-node@1f8c6b94b26d0feae1e387ca63ccbdc44d27b561
with:
node-version: 16.13.x
cache: npm

View File

@@ -55,7 +55,7 @@ jobs:
run: git lfs checkout
- name: Setup node
uses: actions/setup-node@04c56d2f954f1e4c69436aa54cfef261a018f458
uses: actions/setup-node@1f8c6b94b26d0feae1e387ca63ccbdc44d27b561
with:
node-version: 16.13.x
cache: npm
@@ -64,7 +64,7 @@ jobs:
run: npm ci
- name: Cache nextjs build
uses: actions/cache@c64c572235d810460d0d6876e9c705ad5002b353
uses: actions/cache@937d24475381cd9c75ae6db12cb4e79714b926ed
with:
path: .next/cache
key: ${{ runner.os }}-nextjs-${{ hashFiles('package*.json') }}
@@ -76,7 +76,7 @@ jobs:
run: node script/early-access/clone-for-build.js
env:
DOCUBOT_REPO_PAT: ${{ secrets.DOCUBOT_REPO_PAT }}
GIT_BRANCH: ${{ github.event.pull_request.head.sha }}
GIT_BRANCH: ${{ github.head_ref || github.ref }}
- name: Create a Heroku build source
id: build-source

View File

@@ -69,7 +69,7 @@ jobs:
run: exit 1
- name: Setup node
uses: actions/setup-node@04c56d2f954f1e4c69436aa54cfef261a018f458
uses: actions/setup-node@1f8c6b94b26d0feae1e387ca63ccbdc44d27b561
with:
node-version: 16.13.x
cache: npm
@@ -82,7 +82,7 @@ jobs:
run: npm ci
- name: Cache nextjs build
uses: actions/cache@c64c572235d810460d0d6876e9c705ad5002b353
uses: actions/cache@937d24475381cd9c75ae6db12cb4e79714b926ed
with:
path: .next/cache
key: ${{ runner.os }}-nextjs-${{ hashFiles('package*.json') }}
@@ -129,7 +129,7 @@ jobs:
# We are not willing to trust the rest (e.g. script/) for the remainder
# of the deployment process.
- name: Upload build artifact
uses: actions/upload-artifact@27121b0bdffd731efa15d66772be8dc71245d074
uses: actions/upload-artifact@82c141cc518b40d92cc801eee768e7aafc9c2fa2
with:
name: pr_build
path: app.tar

View File

@@ -241,7 +241,7 @@ jobs:
run: git lfs checkout
- name: Setup node
uses: actions/setup-node@04c56d2f954f1e4c69436aa54cfef261a018f458
uses: actions/setup-node@1f8c6b94b26d0feae1e387ca63ccbdc44d27b561
with:
node-version: 16.13.x
cache: npm
@@ -375,7 +375,7 @@ jobs:
uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
- name: Setup node
uses: actions/setup-node@04c56d2f954f1e4c69436aa54cfef261a018f458
uses: actions/setup-node@1f8c6b94b26d0feae1e387ca63ccbdc44d27b561
with:
node-version: 16.13.x
cache: npm

View File

@@ -56,7 +56,7 @@ jobs:
token: ${{ secrets.DOCS_BOT_FR }}
- name: Setup Node
uses: actions/setup-node@04c56d2f954f1e4c69436aa54cfef261a018f458
uses: actions/setup-node@1f8c6b94b26d0feae1e387ca63ccbdc44d27b561
with:
node-version: 16.13.x
cache: npm
@@ -65,7 +65,7 @@ jobs:
run: npm ci
- name: Cache nextjs build
uses: actions/cache@c64c572235d810460d0d6876e9c705ad5002b353
uses: actions/cache@937d24475381cd9c75ae6db12cb4e79714b926ed
with:
path: .next/cache
key: ${{ runner.os }}-nextjs-${{ hashFiles('package*.json') }}

View File

@@ -29,7 +29,7 @@ jobs:
uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
- name: Setup node
uses: actions/setup-node@04c56d2f954f1e4c69436aa54cfef261a018f458
uses: actions/setup-node@1f8c6b94b26d0feae1e387ca63ccbdc44d27b561
with:
node-version: 16.13.x
cache: npm
@@ -38,7 +38,7 @@ jobs:
run: npm ci
- name: Cache nextjs build
uses: actions/cache@c64c572235d810460d0d6876e9c705ad5002b353
uses: actions/cache@937d24475381cd9c75ae6db12cb4e79714b926ed
with:
path: .next/cache
key: ${{ runner.os }}-nextjs-${{ hashFiles('package*.json') }}

View File

@@ -47,7 +47,7 @@ jobs:
persist-credentials: 'false'
- name: Setup node
uses: actions/setup-node@04c56d2f954f1e4c69436aa54cfef261a018f458
uses: actions/setup-node@1f8c6b94b26d0feae1e387ca63ccbdc44d27b561
with:
node-version: 16.13.x
cache: npm
@@ -56,7 +56,7 @@ jobs:
run: npm ci
- name: Cache nextjs build
uses: actions/cache@c64c572235d810460d0d6876e9c705ad5002b353
uses: actions/cache@937d24475381cd9c75ae6db12cb4e79714b926ed
with:
path: .next/cache
key: ${{ runner.os }}-nextjs-${{ hashFiles('package*.json') }}
@@ -73,4 +73,4 @@ jobs:
run: npm run build
- name: Run tests
run: npm run test tests/${{ matrix.test-group }}/
run: npm test -- tests/${{ matrix.test-group }}/

View File

@@ -66,7 +66,7 @@ jobs:
echo "${{ steps.get_diff_files.outputs.files }}" > get_diff_files.txt
- name: Setup node
uses: actions/setup-node@04c56d2f954f1e4c69436aa54cfef261a018f458
uses: actions/setup-node@1f8c6b94b26d0feae1e387ca63ccbdc44d27b561
with:
node-version: 16.13.x
cache: npm
@@ -82,7 +82,7 @@ jobs:
GIT_BRANCH: ${{ github.head_ref || github.ref }}
- name: Cache nextjs build
uses: actions/cache@c64c572235d810460d0d6876e9c705ad5002b353
uses: actions/cache@937d24475381cd9c75ae6db12cb4e79714b926ed
with:
path: .next/cache
key: ${{ runner.os }}-nextjs-${{ hashFiles('package*.json') }}
@@ -93,4 +93,4 @@ jobs:
- name: Run tests
env:
DIFF_FILE: get_diff_files.txt
run: npm run test tests/${{ matrix.test-group }}/
run: npm test -- tests/${{ matrix.test-group }}/

View File

@@ -69,7 +69,7 @@ jobs:
token: ${{ secrets.DOCUBOT_REPO_PAT }}
- name: Setup Node
uses: actions/setup-node@04c56d2f954f1e4c69436aa54cfef261a018f458
uses: actions/setup-node@1f8c6b94b26d0feae1e387ca63ccbdc44d27b561
with:
node-version: 16.13.x
cache: npm

View File

@@ -34,7 +34,7 @@ jobs:
- name: Checkout
uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
- name: Setup Node
uses: actions/setup-node@04c56d2f954f1e4c69436aa54cfef261a018f458
uses: actions/setup-node@1f8c6b94b26d0feae1e387ca63ccbdc44d27b561
with:
node-version: 16.13.x
cache: npm
@@ -48,7 +48,7 @@ jobs:
script/graphql/update-files.js
- name: Create pull request
id: create-pull-request
uses: peter-evans/create-pull-request@7380612b49221684fefa025244f2ef4008ae50ad
uses: peter-evans/create-pull-request@dcd5fd746d53dd8de555c0f10bca6c35628be47a
env:
# Disable pre-commit hooks; they don't play nicely here
HUSKY: '0'

View File

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

View File

@@ -5,7 +5,7 @@
# --------------------------------------------------------------------------------
# BASE IMAGE
# --------------------------------------------------------------------------------
FROM node:16.2.0-alpine as base
FROM node:16-alpine as base
RUN apk add --no-cache make g++ git
@@ -22,6 +22,11 @@ COPY package*.json ./
RUN npm ci
# For Next.js v12+
# This the appropriate necessary extra for node:16-alpine
# Other options are https://www.npmjs.com/search?q=%40next%2Fswc
# RUN npm i @next/swc-linux-x64-musl --no-save
# ---------------
# PROD DEPS
@@ -54,7 +59,7 @@ RUN npm run build
# MAIN IMAGE
# --------------------------------------------------------------------------------
FROM node:16.2.0-alpine as production
FROM node:16-alpine as production
# Let's make our home
WORKDIR /usr/src/docs

View File

@@ -12,11 +12,11 @@ See [the contributing guide](CONTRIBUTING.md) for detailed instructions on how t
We accept different [types of contributions](https://github.com/github/docs/blob/main/contributing/types-of-contributions.md), including some that don't require you to write a single line of code.
On the GitHub Docs site, you can click the make a contribution button to open a PR(Pull Request) for quick fixes like typos, updates, or link fixes.
On the GitHub Docs site, you can click the make a contribution button to open a pull request for quick fixes like typos, updates, or link fixes.
<img src="./assets/images/contribution_cta.png" width="400">
For more complex contributions, you can open an issue using the most appropriate [issue template](https://github.com/github/docs/issues/new/choose) to describe the changes you'd like to see. By this way you can also be a part of Open source contributor's community without even writing a single line of code.
For more complex contributions, you can open an issue using the most appropriate [issue template](https://github.com/github/docs/issues/new/choose) to describe the changes you'd like to see.
If you're looking for a way to contribute, you can scan through our [existing issues](https://github.com/github/docs/issues) for something to work on. When ready, check out [Getting Started with Contributing](/CONTRIBUTING.md) for detailed instructions.
@@ -33,7 +33,6 @@ That's how you can easily become a member of the GitHub Documentation community.
## READMEs
In addition to the README you're reading right now, this repo includes other READMEs that describe the purpose of each subdirectory in more detail:
You can go through among them for specified details regarding the topics listed below.
- [content/README.md](content/README.md)
- [content/graphql/README.md](content/graphql/README.md)
@@ -57,7 +56,7 @@ The GitHub product documentation in the assets, content, and data folders are li
All other code in this repository is licensed under the [MIT license](LICENSE-CODE).
When you are using the GitHub logos, be sure to follow the [GitHub logo guidelines](https://github.com/logos).
When using the GitHub logos, be sure to follow the [GitHub logo guidelines](https://github.com/logos).
## Thanks :purple_heart:

Binary file not shown.

Before

Width:  |  Height:  |  Size: 75 KiB

After

Width:  |  Height:  |  Size: 202 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 112 KiB

After

Width:  |  Height:  |  Size: 297 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 113 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 97 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 152 KiB

After

Width:  |  Height:  |  Size: 239 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 286 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.9 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 51 KiB

View File

@@ -51,3 +51,7 @@
.selectWording {
margin: 0.64rem 0.5rem 0 0;
}
.versionSearchContainer {
overflow: hidden;
}

View File

@@ -206,7 +206,7 @@ export function Search({
)
const SearchInput = (
<div data-testid="search" aria-hidden="true">
<div data-testid="search">
<div className="position-relative z-2">
<form role="search" className="width-full d-flex" noValidate onSubmit={onFormSubmit}>
<label className="text-normal width-full">
@@ -347,23 +347,6 @@ function ShowSearchResults({
}, [selectedVersion])
if (results) {
if (results.length === 0) {
// When there results, but exactly 0, it matters if this is the overlay or not.
if (isHeaderSearch) {
return (
<div className="mt-5 px-6">
{isLoading ? <span>{t('loading')}...</span> : <span>{t('no_results')}.</span>}
</div>
)
} else {
return (
<p data-testid="no-search-results" className="d-block mt-4">
{t('no_results')}.
</p>
)
}
}
const ActionListResults = (
<div
data-testid="search-results"
@@ -373,7 +356,7 @@ function ShowSearchResults({
isHeaderSearch && 'overflow-auto'
)}
>
<div className="mt-4 pb-4 width-full border-bottom">
<div className={cx(styles.versionSearchContainer, 'mt-4 pb-4 width-full border-bottom')}>
<p className={cx(styles.searchWording, 'f6 ml-4 d-inline-block')}>
You're searching the <strong>{searchVersion}</strong> version.
</p>
@@ -389,8 +372,16 @@ function ShowSearchResults({
</div>
{/* We might have results AND isLoading. For example, the user typed
a first word, and is now typing more. */}
<p className="d-block ml-4 mt-4">
{isLoading ? <span>{t('loading')}...</span> : <span>&nbsp;</span>}
{isLoading && (
<p className="d-block ml-4 mt-4">
<span>{t('loading')}...</span>
</p>
)}
<h1 className="ml-4 f2 mt-4">
{t('search_results_for')}: {query}
</h1>
<p className="ml-4 mb-4 text-normal f5">
{t('matches_displayed')}: {results.length === 0 ? t('no_results') : results.length}
</p>
<ActionList
@@ -421,8 +412,8 @@ function ShowSearchResults({
score: {score.toFixed(4)} popularity: {popularity.toFixed(4)}
</small>
)}
<div
className={cx('mt-2 d-block f4 text-semibold')}
<h2
className={cx('mt-2 text-normal f3 d-block')}
dangerouslySetInnerHTML={{
__html: title,
}}
@@ -433,7 +424,7 @@ function ShowSearchResults({
dangerouslySetInnerHTML={{ __html: content }}
/>
<div
className={'d-block mt-2 opacity-60 text-small'}
className={'d-block mt-2 opacity-70 text-small'}
dangerouslySetInnerHTML={
breadcrumbs.length === 0
? { __html: `${title}`.replace(/<\/?[^>]+(>|$)|(\/)/g, '') }

View File

@@ -63,7 +63,7 @@ const SidebarContent = styled(Box)`
position: sticky;
padding-top: ${themeGet('space.4')};
top: 4em;
max-height: calc(100vh - ${themeGet('space.4')});
max-height: 75vh;
overflow-y: auto;
padding-bottom: ${themeGet('space.4')};
}

View File

@@ -1,4 +1,6 @@
import { useState, useEffect } from 'react'
import { useRouter } from 'next/router'
import dynamic from 'next/dynamic'
import cx from 'classnames'
import { ActionList, Heading } from '@primer/components'
@@ -17,6 +19,10 @@ import { ArticleGridLayout } from './ArticleGridLayout'
import { PlatformPicker } from 'components/article/PlatformPicker'
import { ToolPicker } from 'components/article/ToolPicker'
const ClientSideRedirectExceptions = dynamic(() => import('./ClientsideRedirectExceptions'), {
ssr: false,
})
// Mapping of a "normal" article to it's interactive counterpart
const interactiveAlternatives: Record<string, { href: string }> = {
'/actions/automating-builds-and-tests/building-and-testing-nodejs': {
@@ -79,8 +85,38 @@ export const ArticlePage = () => {
)
}
// We have some one-off redirects for rest api docs
// currently those are limited to the repos page, but
// that will grow soon as we restructure the rest api docs.
// This is a workaround to updating the hardcoded links
// directly in the REST API code in a separate repo, which
// requires many file changes and teams to sign off.
// While the organization is turbulent, we can do this.
// Once it's more settled, we can refactor the rest api code
// to leverage the OpenAPI urls rather than hardcoded urls.
// The code below determines if we should bother loading this redirecting
// component at all.
// The reason this isn't done at the server-level is because there you
// can't possibly access the URL hash. That's only known in client-side
// code.
const [loadClientsideRedirectExceptions, setLoadClientsideRedirectExceptions] = useState(false)
useEffect(() => {
const { hash, pathname } = window.location
// Today, Jan 2022, it's known explicitly what the pathname.
// In the future there might be more.
// Hopefully, we can some day delete all of this and no longer
// be dependent on the URL hash to do the redirect.
if (hash && pathname.endsWith('/rest/reference/repos')) {
setLoadClientsideRedirectExceptions(true)
}
}, [])
return (
<DefaultLayout>
{/* Doesn't matter *where* this is included because it will
never render anything. It always just return null. */}
{loadClientsideRedirectExceptions && <ClientSideRedirectExceptions />}
<div className="container-xl px-3 px-md-6 my-4">
<ArticleGridLayout
topper={<ArticleTitle>{title}</ArticleTitle>}
@@ -136,7 +172,7 @@ export const ArticlePage = () => {
)}
{miniTocItems.length > 1 && (
<>
<Heading as="h2" fontSize={1} id="in-this-article" className="mb-1">
<Heading as="h2" id="in-this-article" className="mb-1" sx={{ fontSize: 1 }}>
<Link href="#in-this-article">{t('miniToc')}</Link>
</Heading>

View File

@@ -0,0 +1,35 @@
import { useEffect } from 'react'
import { useRouter } from 'next/router'
import overrides from '../../lib/redirects/static/rest-api-redirect-exceptions.json'
const overrideRedirects: Record<string, string> = overrides
export default function ClientSideRedirectExceptions() {
const router = useRouter()
useEffect(() => {
// We have some one-off redirects for rest api docs
// currently those are limited to the repos page, but
// that will grow soon as we restructure the rest api docs.
// This is a workaround to updating the hardcoded links
// directly in the REST API code in a separate repo, which
// requires many file changes and teams to sign off.
// While the organization is turbulent, we can do this.
// Once it's more settled, we can refactor the rest api code
// to leverage the OpenAPI urls rather than hardcoded urls.
const { hash, pathname } = window.location
// The `hash` will start with a `#` but all the keys in
// `overrideRedirects` do not. Hence, this slice.
const combined = pathname + hash
const overrideKey = combined
.replace(`/${router.locale}`, '')
.replace(`/${router.query.versionId || ''}`, '')
const redirectToName = overrideRedirects[overrideKey]
if (redirectToName) {
const newPathname = combined.replace(overrideKey, redirectToName)
router.replace(newPathname)
}
}, [])
return null
}

View File

@@ -51,6 +51,7 @@ export type ProductLandingContextT = {
featuredArticles: Array<{
label: string // Guides
viewAllHref?: string // If provided, adds a "View All ->" to the header
viewAllTitleText?: string // Adds 'title' attribute text for the "View All" href
articles: Array<FeaturedLink>
}>
changelogUrl?: string

View File

@@ -4,11 +4,16 @@ import { Label } from '@primer/components'
type Props = {
card: ArticleGuide
typeLabel: string
tabIndex?: number
}
export const ArticleCard = ({ card, typeLabel }: Props) => {
export const ArticleCard = ({ tabIndex, card, typeLabel }: Props) => {
return (
<div data-testid="article-card" className="d-flex col-12 col-md-4 pr-0 pr-md-6 pr-lg-8">
<li
tabIndex={tabIndex}
data-testid="article-card"
className="d-flex col-12 col-md-4 pr-0 pr-md-6 pr-lg-8"
>
<a className="no-underline d-flex flex-column py-3 border-bottom" href={card.href}>
<h4 className="h4 color-fg-default mb-1" dangerouslySetInnerHTML={{ __html: card.title }} />
<div className="h6 text-uppercase" data-testid="article-card-type">
@@ -33,6 +38,6 @@ export const ArticleCard = ({ card, typeLabel }: Props) => {
</ul>
)}
</a>
</div>
</li>
)
}

View File

@@ -1,4 +1,4 @@
import React, { useEffect, useState } from 'react'
import React, { useEffect, useRef, useState } from 'react'
import { ArticleGuide, useProductGuidesContext } from 'components/context/ProductGuidesContext'
import { useTranslation } from 'components/hooks/useTranslation'
@@ -15,6 +15,9 @@ export const ArticleCards = () => {
const [typeFilter, setTypeFilter] = useState<ItemInput | undefined>()
const [topicFilter, setTopicFilter] = useState<ItemInput | undefined>()
const [filteredResults, setFilteredResults] = useState<Array<ArticleGuide>>([])
const typesRef = useRef<HTMLDivElement>(null)
const topicsRef = useRef<HTMLDivElement>(null)
const articleCardRef = useRef<HTMLUListElement>(null)
useEffect(() => {
setNumVisible(PAGE_SIZE)
@@ -27,6 +30,21 @@ export const ArticleCards = () => {
)
}, [typeFilter, topicFilter])
const clickDropdown = (e: React.RefObject<HTMLDivElement>) => {
if (e === typesRef && typesRef.current) typesRef.current.focus()
if (e === topicsRef && topicsRef.current) topicsRef.current.focus()
}
const loadMore = () => {
if (articleCardRef.current) {
const childListLength = articleCardRef.current.childElementCount
// Leading semi-colon due to prettier to prevent possible ASI failures
// Need to explicitly type assert as HTMLDivElement as focus property missing from dom type definitions for Element.
;(articleCardRef.current.childNodes.item(childListLength - 1) as HTMLDivElement).focus()
}
setNumVisible(numVisible + PAGE_SIZE)
}
const isUserFiltering = typeFilter !== undefined || topicFilter !== undefined
const guides = isUserFiltering ? filteredResults : includeGuides || []
@@ -48,11 +66,18 @@ export const ArticleCards = () => {
<label htmlFor="guide-filter-form">{t('filter_instructions')}</label>
<form name="guide-filter-form" className="mt-2 mb-5 d-flex d-flex">
<div data-testid="card-filter-types">
<label htmlFor="type" className="text-uppercase f6 color-fg-muted d-block">
<div
onClick={() => clickDropdown(typesRef)}
onKeyDown={() => clickDropdown(typesRef)}
role="button"
tabIndex={-1}
className="text-uppercase f6 color-fg-muted d-block"
>
{t('filters.type')}
</label>
</div>
<DropdownMenu
aria-label="guide types"
anchorRef={typesRef}
aria-label="types"
data-testid="types-dropdown"
placeholder={t('filters.all')}
items={types}
@@ -62,11 +87,18 @@ export const ArticleCards = () => {
</div>
<div data-testid="card-filter-topics" className="mx-4">
<label htmlFor="topic" className="text-uppercase f6 color-fg-muted d-block">
<div
onClick={() => clickDropdown(topicsRef)}
onKeyDown={() => clickDropdown(topicsRef)}
role="button"
tabIndex={-1}
className="text-uppercase f6 color-fg-muted d-block"
>
{t('filters.topic')}
</label>
</div>
<DropdownMenu
aria-label="guide topics"
anchorRef={topicsRef}
aria-label="topics"
data-testid="topics-dropdown"
placeholder={t('filters.all')}
items={topics}
@@ -84,16 +116,23 @@ export const ArticleCards = () => {
: t('guides_found.multiple').replace('{n}', guides.length)}
</div>
<div className="d-flex flex-wrap mr-0 mr-md-n6 mr-lg-n8">
<ul ref={articleCardRef} className="d-flex flex-wrap mr-0 mr-md-n6 mr-lg-n8">
{guides.slice(0, numVisible).map((card) => {
return <ArticleCard key={card.href} card={card} typeLabel={guideTypes[card.type]} />
return (
<ArticleCard
tabIndex={-1}
key={card.href}
card={card}
typeLabel={guideTypes[card.type]}
/>
)
})}
</div>
</ul>
{guides.length > numVisible && (
<button
className="col-12 mt-5 text-center text-bold color-fg-accent btn-link"
onClick={() => setNumVisible(numVisible + PAGE_SIZE)}
onClick={loadMore}
>
{t('load_more')}
</button>

View File

@@ -2,7 +2,7 @@ import cx from 'classnames'
import { useTranslation } from 'components/hooks/useTranslation'
import { ArrowRightIcon } from '@primer/octicons-react'
import { ActionList } from '@primer/components'
import { useState } from 'react'
import { useEffect, useRef, useState } from 'react'
import { FeaturedTrack } from 'components/context/ProductGuidesContext'
import { TruncateLines } from 'components/ui/TruncateLines'
import slugger from 'github-slugger'
@@ -15,11 +15,16 @@ type Props = {
const DEFAULT_VISIBLE_GUIDES = 4
export const LearningTrack = ({ track }: Props) => {
const [numVisible, setNumVisible] = useState(DEFAULT_VISIBLE_GUIDES)
const { t } = useTranslation('product_guides')
const slug = track?.title ? slugger.slug(track?.title) : ''
const listRef = useRef<HTMLLIElement>(null)
const showAll = () => {
setNumVisible(track?.guides?.length || 0)
}
const { t } = useTranslation('product_guides')
const slug = track?.title ? slugger.slug(track?.title) : ''
useEffect(() => {
if (listRef.current) listRef.current.focus()
})
return (
<div data-testid="learning-track" className="my-3 px-4 col-12 col-md-6">
@@ -57,6 +62,7 @@ export const LearningTrack = ({ track }: Props) => {
return {
renderItem: () => (
<ActionList.Item
ref={listRef}
as="li"
key={guide.href + track?.trackName}
sx={{

View File

@@ -1,6 +1,6 @@
import React from 'react'
import { DefaultLayout } from 'components/DefaultLayout'
import { useProductGuidesContext } from 'components/context/ProductGuidesContext'
import React from 'react'
import { LandingSection } from 'components/landing/LandingSection'
import { GuidesHero } from 'components/guides/GuidesHero'
import { LearningTracks } from 'components/guides/LearningTracks'

View File

@@ -11,17 +11,27 @@ import { BumpLink } from 'components/ui/BumpLink'
export type ArticleListPropsT = {
title?: string
viewAllHref?: string
viewAllTitleText?: string
articles: Array<FeaturedLink>
}
export const ArticleList = ({ title, viewAllHref, articles }: ArticleListPropsT) => {
export const ArticleList = ({
title,
viewAllHref,
viewAllTitleText,
articles,
}: ArticleListPropsT) => {
return (
<>
{title && (
<div className="mb-4 d-flex flex-items-baseline">
<h3 className={cx('f4 text-semibold')}>{title}</h3>
{viewAllHref && (
<Link href={viewAllHref} className="ml-4">
<Link
href={viewAllHref}
className="ml-4"
{...(viewAllTitleText ? { title: viewAllTitleText } : {})}
>
View all <ArrowRightIcon size={14} className="v-align-middle" />
</Link>
)}

View File

@@ -20,6 +20,7 @@ export const FeaturedArticles = () => {
<ArticleList
title={section.label}
viewAllHref={section.viewAllHref}
{...(section.viewAllHref ? { viewAllTitleText: `All ${section.label}` } : {})}
articles={section.articles}
/>
</div>
@@ -31,6 +32,7 @@ export const FeaturedArticles = () => {
<ArticleList
title={t('whats_new')}
viewAllHref={changelogUrl}
viewAllTitleText="All ChangeLog posts"
articles={(whatsNewChangelog || []).map((link) => {
return {
title: link.title,

View File

@@ -1,3 +1,4 @@
import { LinkIcon } from '@primer/octicons-react'
import cx from 'classnames'
type Props = {
@@ -14,6 +15,7 @@ export const LandingSection = ({ title, children, className, sectionLink, descri
<h2 className={cx('h1 color-fg-default', !description ? 'mb-3' : 'mb-4')}>
{sectionLink ? (
<a className="color-unset" href={`#${sectionLink}`}>
<LinkIcon size={24} className="m-1" />
{title}
</a>
) : (

View File

@@ -32,7 +32,7 @@ export const TableOfContents = (props: Props) => {
renderItem: () => (
<ActionList.Item>
<li key={href} className="f4 d-list-item width-full list-style-none">
<Link className="d-block width-full" href={href}>
<Link className="d-block width-full text-underline" href={href}>
{title}
</Link>
{(childTocItems || []).length > 0 && (
@@ -49,7 +49,10 @@ export const TableOfContents = (props: Props) => {
}
return (
<li key={childItem.fullPath} className="f4 d-block width-full m-2">
<Link className="d-block width-full" href={childItem.fullPath}>
<Link
className="d-block width-full text-underline"
href={childItem.fullPath}
>
{childItem.title}
</Link>
</li>

View File

@@ -14,7 +14,7 @@ export const Contribution = () => {
<div className="f5 contribution">
<h2 className="f4 mb-3">{t`title`}</h2>
<p className="max-w-xs color-fg-muted mb-3">{t`body`}</p>
<a className="btn" href={contributionHref}>
<a className="btn color-border-accent-emphasis" href={contributionHref}>
<GitPullRequestIcon size="small" className="octicon mr-1" />
{t`button`}
</a>

View File

@@ -17,6 +17,7 @@ export const Survey = () => {
const { asPath } = useRouter()
const { t } = useTranslation('survey')
const [state, setState] = useState<ViewState>(ViewState.START)
const [isEmailError, setIsEmailError] = useState(false)
const formRef = useRef<HTMLFormElement>(null)
useEffect(() => {
@@ -33,10 +34,28 @@ export const Survey = () => {
}
}
// Though we set `type="email"` on the email address input which gives us browser
// validation of the field, that has accessibility issues (e.g. some screen
// readers won't read the error message) so we need to do manual validation
// ourselves.
function handleEmailInputChange() {
const emailRegex = /[^@\s.][^@\s]*@\[?[a-z0-9.-]+\]?/i
const surveyEmail = getFormData()?.get('survey-email')?.toString()
if (surveyEmail?.length === 0 || surveyEmail?.match(emailRegex)) {
setIsEmailError(false)
} else {
setIsEmailError(true)
}
}
function submit(evt: React.FormEvent) {
evt.preventDefault()
trackEvent(getFormData())
setState(ViewState.END)
if (!isEmailError) {
setState(ViewState.END)
setIsEmailError(false)
}
}
function getFormData() {
@@ -64,7 +83,10 @@ export const Survey = () => {
checked={state === ViewState.YES}
/>
<label
className={cx('btn mr-1', state === ViewState.YES && 'color-bg-accent-emphasis')}
className={cx(
'btn mr-1 color-border-accent-emphasis',
state === ViewState.YES && 'color-bg-accent-emphasis'
)}
htmlFor="survey-yes"
>
<ThumbsupIcon size={16} className={state === ViewState.YES ? '' : 'color-fg-muted'} />
@@ -80,7 +102,10 @@ export const Survey = () => {
checked={state === ViewState.NO}
/>
<label
className={cx('btn', state === ViewState.NO && 'color-bg-danger-emphasis')}
className={cx(
'btn color-border-accent-emphasis',
state === ViewState.NO && 'color-bg-danger-emphasis'
)}
htmlFor="survey-no"
>
<ThumbsdownIcon size={16} className={state === ViewState.NO ? '' : 'color-fg-muted'} />
@@ -104,7 +129,7 @@ export const Survey = () => {
id="survey-comment"
></textarea>
</p>
<p>
<div className={cx('form-group', isEmailError ? 'warn' : '')}>
<label className="d-block mb-1 f6" htmlFor="survey-email">
{t`email_label`}
<span className="text-normal color-fg-muted float-right ml-1">{t`optional`}</span>
@@ -115,18 +140,33 @@ export const Survey = () => {
name="survey-email"
id="survey-email"
placeholder={t`email_placeholder`}
onChange={handleEmailInputChange}
aria-invalid={isEmailError}
{...(isEmailError ? { 'aria-describedby': 'email-input-validation' } : {})}
/>
<span className="f6 color-fg-muted">{t`not_support`}</span>
</p>
{isEmailError && (
<p className="note warning" id="email-input-validation">
{t`email_validation`}
</p>
)}
</div>
<span className="f6 color-fg-muted">{t`not_support`}</span>
<div className="d-flex flex-justify-end flex-items-center mt-3">
<button
type="button"
className="btn btn-sm btn-invisible mr-3"
onClick={() => setState(ViewState.START)}
onClick={() => {
setState(ViewState.START)
setIsEmailError(false)
}}
>
Cancel
</button>
<button type="submit" className="btn btn-sm">
<button
disabled={isEmailError}
type="submit"
className="btn btn-sm color-border-accent-emphasis"
>
{t`send`}
</button>
</div>

View File

@@ -28,39 +28,43 @@ export const Breadcrumbs = () => {
className={cx('f5 breadcrumbs', styles.breadcrumbs)}
aria-label="Breadcrumb"
>
{Object.values(breadcrumbs).map((breadcrumb, i, arr) => {
if (!breadcrumb) {
return null
}
const title = `${breadcrumb.title}`
return [
!breadcrumb.href ? (
<span data-testid="breadcrumb-title" key={title} title={title} className="px-2">
{breadcrumb.title}
</span>
) : (
<Link
key={title}
data-testid="breadcrumb-link"
href={breadcrumb.href}
title={title}
className={cx(
'pr-3',
// Always show first and last, show middle on XL size
i === 0 || i === arr.length - 1 ? 'd-inline-block' : 'd-none d-xl-inline-block',
pathWithLocale === breadcrumb.href && 'color-fg-muted'
)}
>
{breadcrumb.title}
{i !== arr.length - 1 ? (
<span className="color-fg-muted pl-3" key={`${i}-slash`}>
/
<ul>
{Object.values(breadcrumbs)
.filter(Boolean)
.map((breadcrumb, i, arr) => {
const title = `${breadcrumb.title}`
return [
!breadcrumb.href ? (
<span data-testid="breadcrumb-title" key={title} title={title} className="px-2">
{breadcrumb.title}
</span>
) : null}
</Link>
),
]
})}
) : (
<li className="d-inline-block" key={title}>
<Link
data-testid="breadcrumb-link"
href={breadcrumb.href}
title={title}
className={cx(
'pr-3',
// Always show first and last, show middle on XL size
i === 0 || i === arr.length - 1
? 'd-inline-block'
: 'd-none d-xl-inline-block',
pathWithLocale === breadcrumb.href && 'color-fg-muted'
)}
>
{breadcrumb.title}
{i !== arr.length - 1 ? (
<span className="color-fg-muted pl-3" key={`${i}-slash`}>
/
</span>
) : null}
</Link>
</li>
),
]
})}
</ul>
</nav>
)
}

View File

@@ -11,7 +11,7 @@ const restDisplayPages = [
'/rest/reference/pages',
'/rest/reference/releases',
'/rest/reference/repos',
'/rest/reference/repository-metrics',
'/rest/reference/metrics',
'/rest/reference/webhooks',
]
const restRepoCategoryExceptionsTitles = {
@@ -21,7 +21,7 @@ const restRepoCategoryExceptionsTitles = {
deployments: 'Deployments',
pages: 'GitHub Pages',
releases: 'Releases',
'repository-metrics': 'Repository metrics',
metrics: 'Metrics',
webhooks: 'Webhooks',
}

View File

@@ -37,7 +37,7 @@ export const ScrollButton = ({ className, ariaLabel }: ScrollButtonPropsT) => {
<div className={cx(className, 'transition-200', show ? 'opacity-100' : 'opacity-0')}>
<button
onClick={onClick}
className="color-bg-default color-fg-on-emphasis border-0 d-inline-block mr-2 f6"
className="color-bg-default color-fg-default border-0 d-inline-block mr-2 f6"
>
{t('scroll_to_top')}
</button>

View File

@@ -23,7 +23,7 @@ To help you understand your subscriptions and decide whether to unsubscribe, see
## Choosing how to unsubscribe
To unwatch (or unsubscribe from) repositories quickly, go to the "Watched repositories" page, where you can see all repositories you're watching. For more information, see "[Unwatch a repository](#unwatch-a-repository)."
To unwatch (or unsubscribe from) repositories quickly, navigate to [github.com/watching](https://github.com/watching) to see all the repositories you're following. For more information, see "[Unwatching repositories](#unwatching-repositories)."
To unsubscribe from multiple notifications at the same time, you can unsubscribe using your inbox or on the subscriptions page. Both of these options offer more context about your subscriptions than the "Watched repositories" page.
@@ -57,20 +57,32 @@ When you unsubscribe from notifications in your inbox, they will automatically d
2. Select the notifications you want to unsubscribe to. In the top right, click **Unsubscribe.**
![Subscriptions page](/assets/images/help/notifications-v2/unsubscribe-from-subscriptions-page.png)
## Unwatch a repository
## Unwatching repositories
When you unwatch a repository, you unsubscribe from future updates from that repository unless you participate in a conversation or are @mentioned.
{% data reusables.notifications.access_notifications %}
1. In the left sidebar, under the list of repositories, use the "Manage notifications" drop-down to click **Watched repositories**.
![Manage notifications drop down menu options](/assets/images/help/notifications-v2/manage-notifications-options.png)
2. On the watched repositories page, after you've evaluated the repositories you're watching, choose whether to:
{% ifversion fpt or ghes > 3.0 or ghae or ghec %}
- Unwatch a repository
- Ignore all notifications for a repository
- Customize the types of event you receive notifications for ({% data reusables.notifications-v2.custom-notification-types %}, if enabled)
{% else %}
- Unwatch a repository
- Only watch releases for a repository
- Ignore all notifications for a repository
{% endif %}
{%- ifversion fpt or ghes > 3.0 or ghae or ghec %}
- Unwatch a repository
- Ignore all notifications for a repository
- If enabled, customize the types of event you receive notifications for ({% data reusables.notifications-v2.custom-notification-types %})
{%- else %}
- Unwatch a repository
- Only watch releases for a repository
- Ignore all notifications for a repository
{%- endif %}
{%- ifversion fpt or ghec or ghes > 3.3 or ghae-issue-5819 %}
1. Optionally, to unsubscribe from all repositories owned by a given user or organization, select the **Unwatch all** dropdown and click the organization whose repositories you'd like to unsubscribe from. The button to unwatch all repositories is only available if you are watching all activity or custom notifications on over 10 repositories.
![Screenshot of the Unwatch All button.](/assets/images/help/notifications-v2/unsubscribe-from-all-repos.png)
- Click **Unwatch** to confirm that you want to unwatch the repositories owned by the selected user or organization, or click **Cancel** to cancel.
![Screenshot of the unwatch all confirmation dialogue.](/assets/images/help/notifications-v2/unwatch-repo-dialog.png)
{% endif %}

View File

@@ -2,8 +2,6 @@
title: Managing accessibility settings
intro: 'You can disable character key shortcuts on {% data variables.product.prodname_dotcom %} in your accessibility settings.'
versions:
fpt: '*'
ghes: '>=3.4'
feature: keyboard-shortcut-accessibility-setting
---
@@ -11,12 +9,12 @@ versions:
{% data variables.product.product_name %} includes a variety of keyboard shortcuts so that you can perform actions across the site without using your mouse to navigate. While shortcuts are useful to save time, they can sometimes make {% data variables.product.prodname_dotcom %} harder to use and less accessible.
All keyboard shortcuts are enabled by default on {% data variables.product.product_name %}, but you can choose to disable character key shortcuts in your accessibility settings. This setting does not affect keyboard shortcuts provided by your web browser or {% data variables.product.prodname_dotcom %} shortcuts that use a modifier key such as `control` or `command`.
All keyboard shortcuts are enabled by default on {% data variables.product.product_name %}, but you can choose to disable character key shortcuts in your accessibility settings. This setting does not affect keyboard shortcuts provided by your web browser or {% data variables.product.prodname_dotcom %} shortcuts that use a modifier key such as <kbd>Control</kbd> or <kbd>Command</kbd>.
## Managing character key shortcuts
{% data reusables.user_settings.access_settings %}
{% data reusables.user_settings.accessibility_settings %}
1. Select or deselect the **Enable character key shortcuts** checkbox.
1. Select or deselect the **Enable character key shortcuts** checkbox.
![Screenshot of the 'Enable character key shortcuts' checkbox](/assets/images/help/settings/disable-character-key-shortcuts.png)
2. Click **Save**.

View File

@@ -40,7 +40,7 @@ By default, your organization membership visibility is set to private. You can c
{% ifversion fpt or ghec %}
If your organization belongs to an enterprise account, you are automatically a member of the enterprise account and visible to enterprise account owners. For more information, see "[About enterprise accounts](/admin/overview/about-enterprise-accounts)."
If your organization belongs to an enterprise account, you are automatically a member of the enterprise account and visible to enterprise account owners. For more information, see "[About enterprise accounts](/enterprise-cloud@latest/admin/overview/about-enterprise-accounts){% ifversion fpt %}" in the {% data variables.product.prodname_ghe_cloud %} documentation.{% else %}."{% endif %}
{% endif %}

View File

@@ -125,11 +125,11 @@ Returns `true` if `search` contains `item`. If `search` is an array, this functi
#### Example using an array
`contains(github.event.issue.labels.*.name, 'bug')`
`contains(github.event.issue.labels.*.name, 'bug')` returns whether the issue related to the event has a label "bug".
#### Example using a string
`contains('Hello world', 'llo')` returns `true`
`contains('Hello world', 'llo')` returns `true`.
### startsWith
@@ -139,7 +139,7 @@ Returns `true` when `searchString` starts with `searchValue`. This function is n
#### Example
`startsWith('Hello world', 'He')` returns `true`
`startsWith('Hello world', 'He')` returns `true`.
### endsWith
@@ -149,7 +149,7 @@ Returns `true` if `searchString` ends with `searchValue`. This function is not c
#### Example
`endsWith('Hello world', 'ld')` returns `true`
`endsWith('Hello world', 'ld')` returns `true`.
### format
@@ -159,13 +159,11 @@ Replaces values in the `string`, with the variable `replaceValueN`. Variables in
#### Example
Returns 'Hello Mona the Octocat'
`format('Hello {0} {1} {2}', 'Mona', 'the', 'Octocat')`
#### Example escaping braces
Returns 'Hello Mona the Octocat'.
Returns '{Hello Mona the Octocat!}'
#### Example escaping braces
{% raw %}
```js
@@ -173,6 +171,8 @@ format('{{Hello {0} {1} {2}!}}', 'Mona', 'the', 'Octocat')
```
{% endraw %}
Returns '{Hello Mona the Octocat!}'.
### join
`join( array, optionalSeparator )`

View File

@@ -61,7 +61,7 @@ The patterns defined in `branches` and `tags` are evaluated against the Git ref'
on:
push:
# Sequence of patterns matched against refs/heads
branches:
branches:
# Push events on main branch
- main
# Push events to branches matching refs/heads/mona/octocat
@@ -69,7 +69,7 @@ on:
# Push events to branches matching refs/heads/releases/10
- 'releases/**'
# Sequence of patterns matched against refs/tags
tags:
tags:
- v1 # Push events to v1 tag
- v1.* # Push events to v1.0, v1.1, and v1.9 tags
```
@@ -109,7 +109,7 @@ The following workflow will run on pushes to `releases/10` or `releases/beta/mon
```yaml
on:
push:
branches:
branches:
- 'releases/**'
- '!releases/**-alpha'
```
@@ -208,7 +208,7 @@ on:
default: 'john-doe'
required: false
type: string
jobs:
print-username:
runs-on: ubuntu-latest
@@ -244,7 +244,7 @@ on:
value: ${{ jobs.my_job.outputs.job_output1 }}
workflow_output2:
description: "The second job output"
value: ${{ jobs.my_job.outputs.job_output2 }}
value: ${{ jobs.my_job.outputs.job_output2 }}
```
{% endraw %}
@@ -268,12 +268,12 @@ on:
access-token:
description: 'A token passed from the caller workflow'
required: false
jobs:
pass-secret-to-action:
runs-on: ubuntu-latest
steps:
steps:
- name: Pass the received secret to an action
uses: ./.github/actions/my-action@v1
with:
@@ -283,7 +283,7 @@ jobs:
## `on.workflow_call.secrets.<secret_id>`
A string identifier to associate with the secret.
A string identifier to associate with the secret.
## `on.workflow_call.secrets.<secret_id>.required`
@@ -297,13 +297,12 @@ When using the `workflow_dispatch` event, you can optionally specify inputs that
The triggered workflow receives the inputs in the `github.event.inputs` context. For more information, see "[Contexts](/actions/learn-github-actions/contexts#github-context)."
### Example
{% raw %}
```yaml
on:
on:
workflow_dispatch:
inputs:
logLevel:
description: 'Log level'
description: 'Log level'
required: true
default: 'warning' {% ifversion ghec or ghes > 3.3 or ghae-issue-5511 %}
type: choice
@@ -319,16 +318,16 @@ on:
description: 'Environment to run tests against'
type: environment
required: true {% endif %}
jobs:
print-tag:
runs-on: ubuntu-latest
steps:
- name: Print the input tag to STDOUT
run: echo The tag is ${{ github.event.inputs.tag }}
run: echo {% raw %} The tag is ${{ github.event.inputs.tag }} {% endraw %}
```
{% endraw %}
## `on.schedule`
@@ -1029,7 +1028,7 @@ jobs:
with:
first_name: Mona
middle_name: The
last_name: Octocat
last_name: Octocat
```
## `jobs.<job_id>.steps[*].with.args`
@@ -1459,7 +1458,7 @@ Additional Docker container resource options. For a list of options, see "[`dock
{% ifversion fpt or ghes > 3.3 or ghae-issue-4757 or ghec %}
## `jobs.<job_id>.uses`
The location and version of a reusable workflow file to run as a job.
The location and version of a reusable workflow file to run as a job.
`{owner}/{repo}/{path}/{filename}@{ref}`
@@ -1509,7 +1508,7 @@ jobs:
call-workflow:
uses: octo-org/example-repo/.github/workflows/called-workflow.yml@main
secrets:
access-token: ${{ secrets.PERSONAL_ACCESS_TOKEN }}
access-token: ${{ secrets.PERSONAL_ACCESS_TOKEN }}
```
{% endraw %}

View File

@@ -31,8 +31,6 @@ You can also disable and enable a workflow using the REST API. For more informat
## Disabling a workflow
{% include tool-switcher %}
{% webui %}
{% data reusables.repositories.navigate-to-repo %}
@@ -62,8 +60,6 @@ gh workflow disable <em>workflow</em>
## Enabling a workflow
{% include tool-switcher %}
{% webui %}
You can re-enable a workflow that was previously disabled.

View File

@@ -16,8 +16,6 @@ By default, {% data variables.product.product_name %} stores build logs and arti
{% data reusables.repositories.permissions-statement-read %}
{% include tool-switcher %}
{% webui %}
{% data reusables.repositories.navigate-to-repo %}

View File

@@ -20,8 +20,6 @@ To run a workflow manually, the workflow must be configured to run on the `workf
## Running a workflow
{% include tool-switcher %}
{% webui %}
{% data reusables.repositories.navigate-to-repo %}

View File

@@ -17,9 +17,7 @@ versions:
## Re-running all the jobs in a workflow
Re-running a workflow uses the same `GITHUB_SHA` (commit SHA) and `GITHUB_REF` (Git ref) of the original event that triggered the workflow run. You can re-run a workflow for up to 30 days after the initial run.
{% include tool-switcher %}
Re-running a workflow uses the same `GITHUB_SHA` (commit SHA) and `GITHUB_REF` (Git ref) of the original event that triggered the workflow run. You can re-run a workflow for up to 30 days after the initial run.
{% webui %}

View File

@@ -16,8 +16,6 @@ shortTitle: View workflow run history
{% data reusables.repositories.permissions-statement-read %}
{% include tool-switcher %}
{% webui %}
{% data reusables.repositories.navigate-to-repo %}

View File

@@ -41,7 +41,7 @@ For secrets stored at the environment level, you can enable required reviewers t
{% data reusables.codespaces.secrets-naming %}
For example, {% ifversion fpt or ghes > 3.0 or ghae or ghec %}a secret created at the environment level must have a unique name in that environment, {% endif %}a secret created at the repository level must have a unique name in that repository, and a secret created at the organization level must have a unique name at that level.
For example, {% ifversion fpt or ghes > 3.0 or ghae or ghec %}a secret created at the environment level must have a unique name in that environment, {% endif %}a secret created at the repository level must have a unique name in that repository, and a secret created at the organization level must have a unique name at that level.
{% data reusables.codespaces.secret-precedence %}{% ifversion fpt or ghes > 3.0 or ghae or ghec %} Similarly, if an organization, repository, and environment all have a secret with the same name, the environment-level secret takes precedence.{% endif %}
@@ -79,8 +79,6 @@ When generating credentials, we recommend that you grant the minimum permissions
{% data reusables.github-actions.permissions-statement-secrets-repository %}
{% include tool-switcher %}
{% webui %}
{% data reusables.repositories.navigate-to-repo %}
@@ -121,8 +119,6 @@ To list all secrets for the repository, use the `gh secret list` subcommand.
{% data reusables.github-actions.permissions-statement-secrets-environment %}
{% include tool-switcher %}
{% webui %}
{% data reusables.repositories.navigate-to-repo %}
@@ -160,8 +156,6 @@ When creating a secret in an organization, you can use a policy to limit which r
{% data reusables.github-actions.permissions-statement-secrets-organization %}
{% include tool-switcher %}
{% webui %}
{% data reusables.organizations.navigate-to-org %}

View File

@@ -1,7 +1,6 @@
---
title: Configuring SAML single sign-on for your enterprise using Okta
intro: 'You can use Security Assertion Markup Language (SAML) single sign-on (SSO) with Okta to automatically manage access to your enterprise account on {% data variables.product.product_name %}.'
product: '{% data reusables.gated-features.enterprise-accounts %}'
redirect_from:
- /github/setting-up-and-managing-your-enterprise/configuring-single-sign-on-for-your-enterprise-account-using-okta
- /github/setting-up-and-managing-your-enterprise-account/configuring-saml-single-sign-on-for-your-enterprise-account-using-okta

View File

@@ -1,7 +1,6 @@
---
title: Managing team synchronization for organizations in your enterprise
intro: 'You can enable team synchronization between an identity provider (IdP) and {% data variables.product.product_name %} to allow organizations owned by your enterprise account to manage team membership through IdP groups.'
product: '{% data reusables.gated-features.enterprise-accounts %}'
permissions: Enterprise owners can manage team synchronization for an enterprise account.
versions:
ghec: '*'

View File

@@ -1,7 +1,6 @@
---
title: Switching your SAML configuration from an organization to an enterprise account
intro: Learn special considerations and best practices for replacing an organization-level SAML configuration with an enterprise-level SAML configuration.
product: '{% data reusables.gated-features.enterprise-accounts %}'
permissions: Enterprise owners can configure SAML single sign-on for an enterprise account.
versions:
ghec: '*'

View File

@@ -14,7 +14,7 @@ topics:
## About provisioning for {% data variables.product.prodname_emus %}
You can configure provisioning for {% data variables.product.prodname_emus %} to create, manage, and deactivate user accounts for your enterprise members. When you configure provisioning for {% data variables.product.prodname_emus %}, users assigned to the {% data variables.product.prodname_emu_idp_application %} application in your identity provider are provisioned as new user accounts on {% data variables.product.prodname_dotcom %} via SCIM, and the users are added to your enterprise.
You must configure provisioning for {% data variables.product.prodname_emus %} to create, manage, and deactivate user accounts for your enterprise members. When you configure provisioning for {% data variables.product.prodname_emus %}, users assigned to the {% data variables.product.prodname_emu_idp_application %} application in your identity provider are provisioned as new user accounts on {% data variables.product.prodname_dotcom %} via SCIM, and the users are added to your enterprise.
When you update information associated with a user's identity on your IdP, your IdP will update the user's account on GitHub.com. When you unassign the user from the {% data variables.product.prodname_emu_idp_application %} application or deactivate a user's account on your IdP, your IdP will communicate with {% data variables.product.prodname_dotcom %} to invalidate any SAML sessions and disable the member's account. The disabled account's information is maintained and their username is changed to a hash of their original username with the short code appended. If you reassign a user to the {% data variables.product.prodname_emu_idp_application %} application or reactivate their account on your IdP, the {% data variables.product.prodname_managed_user %} account on {% data variables.product.prodname_dotcom %} will be reactivated and username restored.

View File

@@ -1,6 +1,7 @@
---
title: Enabling the dependency graph and Dependabot alerts on your enterprise account
intro: 'You can connect {% data variables.product.product_location %} to {% data variables.product.prodname_ghe_cloud %} and enable the dependency graph and {% data variables.product.prodname_dependabot_alerts %} in repositories in your instance.'
miniTocMaxHeadingLevel: 3
shortTitle: Enable dependency analysis
redirect_from:
- /enterprise/admin/installation/enabling-security-alerts-for-vulnerable-dependencies-on-github-enterprise-server
@@ -33,12 +34,17 @@ For more information about these features, see "[About the dependency graph](/gi
### About synchronization of data from the {% data variables.product.prodname_advisory_database %}
{% data reusables.repositories.tracks-vulnerabilities %}
{% data reusables.repositories.tracks-vulnerabilities %}
You can connect {% data variables.product.product_location %} to {% data variables.product.prodname_dotcom_the_website %} with {% data variables.product.prodname_github_connect %}. Once connected, vulnerability data is synced from the {% data variables.product.prodname_advisory_database %} to your instance once every hour. You can also choose to manually sync vulnerability data at any time. No code or information about code from {% data variables.product.product_location %} is uploaded to {% data variables.product.prodname_dotcom_the_website %}.
Only {% data variables.product.company_short %}-reviewed advisories are synchronized. {% data reusables.security-advisory.link-browsing-advisory-db %}
### About scanning of repositories with synchronized data from the {% data variables.product.prodname_advisory_database %}
For repositories with {% data variables.product.prodname_dependabot_alerts %} enabled, scanning is triggered on any push to the default branch that contains a manifest file or lock file. Additionally, when a new vulnerability record is added to the instance, {% data variables.product.prodname_ghe_server %} scans all existing repositories in that instance and generates alerts for any repository that is vulnerable. For more information, see "[Detection of vulnerable dependencies](/code-security/supply-chain-security/managing-vulnerabilities-in-your-projects-dependencies/about-alerts-for-vulnerable-dependencies#detection-of-vulnerable-dependencies)."
### About generation of {% data variables.product.prodname_dependabot_alerts %}
If you enable vulnerability detection, when {% data variables.product.product_location %} receives information about a vulnerability, it identifies repositories in your instance that use the affected version of the dependency and generates {% data variables.product.prodname_dependabot_alerts %}. You can choose whether or not to notify users automatically about new {% data variables.product.prodname_dependabot_alerts %}.
@@ -54,7 +60,7 @@ For {% data variables.product.product_location %} to detect vulnerable dependenc
{% ifversion ghes %}
{% ifversion ghes > 3.1 %}
You can enable the dependency graph via the {% data variables.enterprise.management_console %} or the administrative shell. We recommend you follow the {% data variables.enterprise.management_console %} route unless {% data variables.product.product_location %} uses clustering.
You can enable the dependency graph via the {% data variables.enterprise.management_console %} or the administrative shell. We recommend you follow the {% data variables.enterprise.management_console %} route unless {% data variables.product.product_location %} uses clustering.
### Enabling the dependency graph via the {% data variables.enterprise.management_console %}
{% data reusables.enterprise_site_admin_settings.sign-in %}
@@ -104,7 +110,7 @@ Before enabling {% data variables.product.prodname_dependabot_alerts %} for your
![Drop-down menu to enable scanning repositories for vulnerabilities](/assets/images/enterprise/site-admin-settings/enable-vulnerability-scanning-in-repositories.png)
{% tip %}
**Tip**: We recommend configuring {% data variables.product.prodname_dependabot_alerts %} without notifications for the first few days to avoid an overload of emails. After a few days, you can enable notifications to receive {% data variables.product.prodname_dependabot_alerts %} as usual.
{% endtip %}

View File

@@ -2,7 +2,6 @@
title: Enforcing policies for dependency insights in your enterprise
intro: 'You can enforce policies for dependency insights within your enterprise''s organizations, or allow policies to be set in each organization.'
permissions: Enterprise owners can enforce policies for dependency insights in an enterprise.
product: '{% data reusables.gated-features.enterprise-accounts %}'
redirect_from:
- /articles/enforcing-a-policy-on-dependency-insights
- /articles/enforcing-a-policy-on-dependency-insights-in-your-enterprise-account

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