1
0
mirror of synced 2026-01-06 06:02:35 -05:00

Merge branch 'main' into patch-2

This commit is contained in:
Martin Lopes
2022-02-15 10:07:05 +10:00
committed by GitHub
1310 changed files with 27339 additions and 57977 deletions

View File

@@ -14,3 +14,8 @@ FROM mcr.microsoft.com/vscode/devcontainers/javascript-node:0-${VARIANT}
# [Optional] Uncomment if you want to install more global node modules
# RUN su node -c "npm install -g <your-package-list-here>"
# Install the GitHub CLI see:
# https://github.com/microsoft/vscode-dev-containers/blob/3d59f9fe37edb68f78874620f33dac5a62ef2b93/script-library/docs/github.md
COPY library-scripts/github-debian.sh /tmp/library-scripts/
RUN apt-get update && bash /tmp/library-scripts/github-debian.sh

View File

@@ -1,5 +1,6 @@
// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at:
// https://github.com/microsoft/vscode-dev-containers/tree/v0.177.0/containers/javascript-node
// -
{
"name": "docs.github.com",
"build": {

View File

@@ -0,0 +1,43 @@
#!/usr/bin/env bash
#-------------------------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information.
#-------------------------------------------------------------------------------------------------------------
#
# Docs: https://github.com/microsoft/vscode-dev-containers/blob/master/script-library/docs/github.md
#
# Syntax: ./github-debian.sh [version]
CLI_VERSION=${1:-"latest"}
set -e
if [ "$(id -u)" -ne 0 ]; then
echo -e 'Script must be run as root. Use sudo, su, or add "USER root" to your Dockerfile before running this script.'
exit 1
fi
export DEBIAN_FRONTEND=noninteractive
# Install curl, apt-transport-https or gpg if missing
if ! dpkg -s curl ca-certificates > /dev/null 2>&1; then
if [ ! -d "/var/lib/apt/lists" ] || [ "$(ls /var/lib/apt/lists/ | wc -l)" = "0" ]; then
apt-get update
fi
apt-get -y install --no-install-recommends curl ca-certificates
fi
# Get latest release number if latest is specified
if [ "${CLI_VERSION}" = "latest" ] || [ "${CLI_VERSION}" = "current" ] || [ "${CLI_VERSION}" = "lts" ]; then
LATEST_RELEASE=$(curl -sSL -H "Accept: application/vnd.github.v3+json" "https://api.github.com/repos/cli/cli/releases?per_page=1&page=1")
CLI_VERSION=$(echo ${LATEST_RELEASE} | grep -oE 'tag_name":\s*"v[^"]+' | sed -n '/tag_name":\s*"v/s///p')
fi
# Install the GitHub CLI
echo "Downloading github CLI..."
curl -OsSL https://github.com/cli/cli/releases/download/v${CLI_VERSION}/gh_${CLI_VERSION}_linux_amd64.deb
echo "Installing github CLI..."
apt-get install ./gh_${CLI_VERSION}_linux_amd64.deb
echo "Removing github CLI deb file after installation..."
rm -rf ./gh_${CLI_VERSION}_linux_amd64.deb
echo "Done!"

View File

@@ -10,3 +10,5 @@ tests/
lib/rest/static/dereferenced
# Folder is cloned during the preview + prod workflows, the assets are merged into other locations for use before the build
docs-early-access/
# During the preview deploy untrusted user code may be cloned into this directory
user-code/

1
.github/CODEOWNERS vendored
View File

@@ -11,7 +11,6 @@
/script/ @github/docs-engineering
/includes/ @github/docs-engineering
/lib/search/popular-pages.json @github/docs-engineering
app.json @github/docs-engineering
Dockerfile @github/docs-engineering
package-lock.json @github/docs-engineering
package.json @github/docs-engineering

View File

@@ -36,7 +36,7 @@ for (const file of articleFiles) {
const sourceUrl = file.blob_url
const fileName = file.filename.slice(pathPrefix.length)
const fileUrl = fileName.slice(0, fileName.lastIndexOf('.'))
const previewLink = `https://${APP_URL}/${fileUrl}`
const previewLink = `${APP_URL}/${fileUrl}`
const productionLink = `https://docs.github.com/${fileUrl}`
let markdownLine = ''

View File

@@ -10,9 +10,10 @@
[[ -z $GITHUB_REPOSITORY ]] && { echo "Missing GITHUB_REPOSITORY. Exiting."; exit 1; }
[[ -z $PR_NUMBER ]] && { echo "Missing PR_NUMBER. Exiting."; exit 1; }
[[ -z $GITHUB_ENV ]] && { echo "Missing GITHUB_ENV. Exiting."; exit 1; }
[[ -z $APP_NAME_SEED ]] && { echo "Missing APP_NAME_SEED. Exiting."; exit 1; }
# Number of resource groups that we use to split preview envs across
PREVIEW_ENV_RESOURCE_GROUPS=4
PREVIEW_ENV_LOCATION="eastus"
echo "PREVIEW_ENV_LOCATION=${PREVIEW_ENV_LOCATION}" >> $GITHUB_ENV
REPO_NAME="${GITHUB_REPOSITORY#*\/}"
echo "REPO_NAME=${REPO_NAME}" >> $GITHUB_ENV
@@ -20,22 +21,17 @@ echo "REPO_NAME=${REPO_NAME}" >> $GITHUB_ENV
DEPLOYMENT_NAME="${REPO_NAME}-pr-${PR_NUMBER}"
echo "DEPLOYMENT_NAME=${DEPLOYMENT_NAME}" >> $GITHUB_ENV
RESOURCE_GROUP="preview-env-${REPO_NAME}-$((${PR_NUMBER} % ${PREVIEW_ENV_RESOURCE_GROUPS}))"
echo "RESOURCE_GROUP=${RESOURCE_GROUP}" >> $GITHUB_ENV
APP_NAME_BASE="${REPO_NAME}-preview-${PR_NUMBER}"
echo "APP_NAME_BASE=${APP_NAME_BASE}" >> $GITHUB_ENV
APP_NAME_SHORT="${REPO_NAME}-preview-${PR_NUMBER}"
echo "APP_NAME_SHORT=${APP_NAME_SHORT}" >> $GITHUB_ENV
# pseudo random string so guessing a preview env URL is more difficult
APP_SHA=$(echo -n "${APP_NAME_SEED}-${APP_NAME_BASE}" | sha1sum | cut -c1-6)
APP_NAME="${APP_NAME_BASE}-${APP_SHA}"
echo "APP_NAME=${APP_NAME}" >> $GITHUB_ENV
APP_URL="https://${APP_NAME}.${PREVIEW_ENV_LOCATION}.azurecontainer.io"
echo "APP_URL=${APP_URL}" >> $GITHUB_ENV
IMAGE_REPO="${GITHUB_REPOSITORY}/pr-${PR_NUMBER}"
echo "IMAGE_REPO=${IMAGE_REPO}" >> $GITHUB_ENV
# Since this incurs a network request and can be slow, we make it optional
if [ $FULL_APP_INFO ]; then
APP_INFO=$(az webapp list -g ${RESOURCE_GROUP} --query "[?tags.DocsAppName == '${APP_NAME_SHORT}'].{defaultHostName:defaultHostName, name:name} | [0]")
APP_URL=$(echo $APP_INFO | jq '.defaultHostName' | tr -d '"')
echo "APP_URL=${APP_URL}" >> $GITHUB_ENV
APP_NAME_FULL=$(echo $APP_INFO | jq '.name' | tr -d '"')
echo "APP_NAME_FULL=${APP_NAME_FULL}" >> $GITHUB_ENV
fi

View File

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

View File

@@ -20,5 +20,4 @@ mkdir translations
# front-matter will be at play.
# These static redirects json files are notoriously large
echo '[]' > lib/redirects/static/archived-frontmatter-fallbacks.json
echo '{}' > lib/redirects/static/developer.json
echo '{}' > lib/redirects/static/archived-redirects-from-213-to-217.json

View File

@@ -1,42 +0,0 @@
#!/usr/bin/env node
import * as github from '@actions/github'
import getOctokit from '../../script/helpers/github.js'
const { GITHUB_TOKEN } = process.env
// Exit if GitHub Actions PAT is not found
if (!GITHUB_TOKEN) {
throw new Error('You must supply a GITHUB_TOKEN environment variable!')
}
// This helper uses the `GITHUB_TOKEN` implicitly!
// We're using our usual version of Octokit vs. the provided `github`
// instance to avoid versioning discrepancies.
const octokit = getOctokit()
const { CONTEXT_NAME, ACTIONS_RUN_LOG, HEAD_SHA } = process.env
if (!CONTEXT_NAME) {
throw new Error('$CONTEXT_NAME not set')
}
if (!ACTIONS_RUN_LOG) {
throw new Error('$ACTIONS_RUN_LOG not set')
}
if (!HEAD_SHA) {
throw new Error('$HEAD_SHA not set')
}
const { context } = github
const owner = context.repo.owner
const repo = context.payload.repository.name
await octokit.repos.createCommitStatus({
owner,
repo,
sha: HEAD_SHA,
context: CONTEXT_NAME,
state: 'success',
description: 'Successfully deployed! See logs.',
target_url: ACTIONS_RUN_LOG,
})

View File

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

View File

@@ -1,12 +1,13 @@
name: Azure - Deploy Preview Environment
# **What it does**: Build and deploy to an Azure preview environment
# **Why we have it**: It's our preview environment deploy mechanism, only applicable to docs-internal
# **What it does**: Build and deploy an Azure preview environment for this PR
# **Why we have it**: It's our preview environment deploy mechanism, to docs-internal and docs public repo
# **Who does it impact**: All contributors.
# This whole workflow is only guaranteed to be secure in the *private
# repo* and because we repo-sync these files over the to the public one,
# IT'S IMPORTANT THAT THIS WORKFLOW IS ONLY ENABLED IN docs-internal!
# !!!
# ! This worflow has access to secrets, runs in the public repository, and clones untrusted user code.
# ! Modify with extreme caution
# !!!
on:
# The advantage of 'pull_request' over 'pull_request_target' is that we
@@ -15,13 +16,17 @@ on:
# From a security point of view, its arguably safer this way because
# unlike 'pull_request_target', these only have secrets if the pull
# request creator has permission to access secrets.
pull_request:
pull_request_target:
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
@@ -34,18 +39,23 @@ concurrency:
jobs:
build-and-deploy-azure-preview:
if: ${{ github.repository == 'github/docs-internal' }}
name: Build and deploy Azure preview environment
runs-on: ubuntu-latest
timeout-minutes: 15
environment:
name: preview-env-${{ github.event.number }}
url: ${{ steps.deploy.outputs.defaultHostName }}
# The environment variable is computer later in this job in
# the "Get preview app info" step.
# That script sets environment variables which is used by Actions
# to link a PR to a list of environments later.
url: ${{ env.APP_URL }}
env:
PR_NUMBER: ${{ github.event.number || github.event.inputs.PR_NUMBER }}
NONPROD_REGISTRY_USERNAME: ghdocs
APP_LOCATION: eastus
ENABLE_EARLY_ACCESS: ${{ github.repository == 'github/docs-internal' }}
COMMIT_REF: ${{ github.event.pull_request.head.sha || github.event.inputs.COMMIT_REF }}
BRANCH_NAME: ${{ github.head_ref || github.ref_name }}
IS_INTERNAL_BUILD: ${{ github.repository == 'github/docs-internal' }}
# This may also run in forked repositories, not just 'github/docs'
IS_PUBLIC_BUILD: ${{ github.repository != 'github/docs-internal' }}
steps:
- name: 'Az CLI login'
@@ -57,16 +67,25 @@ jobs:
uses: azure/docker-login@81744f9799e7eaa418697cb168452a2882ae844a
with:
login-server: ${{ secrets.NONPROD_REGISTRY_SERVER }}
username: ${{ env.NONPROD_REGISTRY_USERNAME }}
username: ${{ secrets.NONPROD_REGISTRY_USERNAME }}
password: ${{ secrets.NONPROD_REGISTRY_PASSWORD }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@94ab11c41e45d028884a99163086648e898eed25
- name: Check out repo
- if: ${{ env.IS_PUBLIC_BUILD == 'true' }}
name: Check out main branch
uses: actions/checkout@1e204e9a9253d643386038d443f96446fa156a97
with:
ref: ${{ github.event.pull_request.head.sha }}
ref: 'main'
persist-credentials: 'false'
lfs: 'true'
- if: ${{ env.IS_INTERNAL_BUILD == 'true' }}
name: Check out PR code
uses: actions/checkout@1e204e9a9253d643386038d443f96446fa156a97
with:
ref: ${{ env.COMMIT_REF }}
# To prevent issues with cloning early access content later
persist-credentials: 'false'
lfs: 'true'
@@ -75,19 +94,21 @@ jobs:
run: git lfs checkout
- name: Get preview app info
env:
APP_NAME_SEED: ${{ secrets.PREVIEW_ENV_NAME_SEED }}
run: .github/actions-scripts/get-preview-app-info.sh
- name: 'Set env vars'
run: |
# Image tag is unique to each workflow run so that it always triggers a new deployment
echo "DOCKER_IMAGE=${{ secrets.NONPROD_REGISTRY_SERVER }}/${IMAGE_REPO}:${{ github.event.pull_request.head.sha }}-${{ github.run_number }}-${{ github.run_attempt }}" >> $GITHUB_ENV
echo "DOCKER_IMAGE=${{ secrets.NONPROD_REGISTRY_SERVER }}/${IMAGE_REPO}:${{ env.COMMIT_REF }}-${{ github.run_number }}-${{ github.run_attempt }}" >> $GITHUB_ENV
- if: ${{ env.ENABLE_EARLY_ACCESS }}
- if: ${{ env.IS_INTERNAL_BUILD == 'true' }}
name: Determine which docs-early-access branch to clone
id: 'check-early-access'
uses: actions/github-script@2b34a689ec86a68d8ab9478298f91d5401337b7d
env:
BRANCH_NAME: ${{ github.head_ref || github.ref_name }}
BRANCH_NAME: ${{ env.BRANCH_NAME }}
with:
github-token: ${{ secrets.DOCUBOT_REPO_PAT }}
result-encoding: string
@@ -112,7 +133,7 @@ jobs:
return 'main'
}
- if: ${{ env.ENABLE_EARLY_ACCESS }}
- if: ${{ env.IS_INTERNAL_BUILD == 'true' }}
name: Clone docs-early-access
uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
with:
@@ -121,10 +142,27 @@ jobs:
path: docs-early-access
ref: ${{ steps.check-early-access.outputs.result }}
- if: ${{ env.ENABLE_EARLY_ACCESS }}
- if: ${{ env.IS_INTERNAL_BUILD == 'true' }}
name: Merge docs-early-access repo's folders
run: .github/actions-scripts/merge-early-access.sh
- if: ${{ env.IS_PUBLIC_BUILD == 'true' }}
name: Check out user code to temp directory
uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
with:
path: ./user-code
ref: ${{ env.COMMIT_REF }}
# Move acceptable user changes into our main branch checkout
- if: ${{ env.IS_PUBLIC_BUILD == 'true' }}
name: Move acceptable user changes
run: |
# Make sure recursive path expansion is enabled
shopt -s globstar
rsync -rptovR ./user-code/content/./**/*.md ./content
rsync -rptovR ./user-code/assets/./**/*.png ./assets
rsync -rptovR ./user-code/data/./**/*.{yml,md} ./data
# In addition to making the final image smaller, we also save time by not sending unnecessary files to the docker build context
- name: 'Prune for preview env'
run: .github/actions-scripts/prune-for-preview-env.sh
@@ -144,7 +182,7 @@ jobs:
# Succeed despite any non-zero exit code (e.g. if there is no deployment to cancel)
- name: 'Cancel any existing deployments for this PR'
run: |
az deployment group cancel --name ${{ env.DEPLOYMENT_NAME }} -g ${{ env.RESOURCE_GROUP }} || true
az deployment group cancel --name ${{ env.DEPLOYMENT_NAME }} -g ${{ secrets.PREVIEW_ENV_RESOURCE_GROUP }} || true
# Deploy ARM template is idempotent
# Note: once the resources exist the image tag must change for a new deployment to occur (the image tag includes workflow run number, run attempt, as well as sha)
@@ -152,15 +190,18 @@ jobs:
id: deploy
uses: azure/arm-deploy@841b12551939c88af8f6df767c24c38a5620fd0d
with:
resourceGroupName: ${{ env.RESOURCE_GROUP }}
resourceGroupName: ${{ secrets.PREVIEW_ENV_RESOURCE_GROUP }}
subscriptionId: ${{ secrets.NONPROD_SUBSCRIPTION_ID }}
template: ./azure-preview-env-template.json
deploymentName: ${{ env.DEPLOYMENT_NAME }}
parameters: appName="${{ env.APP_NAME_SHORT }}"
location="${{ env.APP_LOCATION }}"
linuxFxVersion="DOCKER|${{ env.DOCKER_IMAGE }}"
dockerRegistryUrl="https://${{ secrets.NONPROD_REGISTRY_SERVER }}"
dockerRegistryUsername="${{ env.NONPROD_REGISTRY_USERNAME }}"
parameters: appName="${{ env.APP_NAME }}"
location="${{ env.PREVIEW_ENV_LOCATION }}"
containerImage="${{ env.DOCKER_IMAGE }}"
dockerRegistryUrl="${{ secrets.NONPROD_REGISTRY_SERVER }}"
dockerRegistryUsername="${{ secrets.NONPROD_REGISTRY_USERNAME }}"
dockerRegistryPassword="${{ secrets.NONPROD_REGISTRY_PASSWORD }}"
- run: echo ${{ steps.deploy.outputs.defaultHostName }}
storageAccountName="${{ secrets.AZURE_STORAGE_ACCOUNT_NAME }}"
storageAccountKey="${{ secrets.AZURE_STORAGE_ACCOUNT_KEY }}"
# 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

@@ -5,7 +5,7 @@ name: Azure - Destroy Preview Env
# **Who does it impact**: All contributors.
on:
pull_request:
pull_request_target:
types:
- closed
- locked
@@ -16,15 +16,16 @@ on:
type: string
required: true
permissions:
contents: read
jobs:
destory-azure-preview-env:
name: Destroy
if: ${{ github.repository == 'github/docs-internal' }}
runs-on: ubuntu-latest
timeout-minutes: 5
env:
PR_NUMBER: ${{ github.event.number || github.event.inputs.PR_NUMBER }}
NONPROD_REGISTRY_NAME: ghdocs
steps:
- name: 'Az CLI login'
@@ -37,28 +38,29 @@ jobs:
- name: Get preview app info
env:
FULL_APP_INFO: 1
APP_NAME_SEED: ${{ secrets.PREVIEW_ENV_NAME_SEED }}
run: .github/actions-scripts/get-preview-app-info.sh
# Succeed despite any non-zero exit code (e.g. if there is no deployment to cancel)
- name: 'Cancel any in progress deployments'
run: |
az deployment group cancel --name ${{ env.DEPLOYMENT_NAME }} -g ${{ env.RESOURCE_GROUP }} || true
az deployment group cancel --name ${{ env.DEPLOYMENT_NAME }} -g ${{ secrets.PREVIEW_ENV_RESOURCE_GROUP }} || true
# Delete web app (which will also delete the App Service plan)
# This will succeed even if the app doesn't exist / has already been deleted
- name: 'Delete App Service App (which will also delete the App Service plan)'
run: |
az webapp delete -n ${{ env.APP_NAME_FULL }} -g ${{ env.RESOURCE_GROUP }}
az container delete -n ${{ env.APP_NAME }} -g ${{ secrets.PREVIEW_ENV_RESOURCE_GROUP }} -y
# Untag all images under this PR's container registry repo - the container registry will automatically remove untagged images.
# This will fail if the IMAGE_REPO doesn't exist, but we don't care
- name: 'Untag all docker images for this PR'
run: |
az acr repository delete -n ${{ env.NONPROD_REGISTRY_NAME }} --repository ${{ env.IMAGE_REPO }} -y || true
az acr repository delete -n ${{ secrets.NONPROD_REGISTRY_NAME }} --repository ${{ env.IMAGE_REPO }} -y || true
# Remove all GitHub deployments from this environment and remove the environment
- uses: strumwolf/delete-deployment-environment@45c821e46baa405e25410700fe2e9643929706a0
with:
# The token provided by the workflow does not have the permissions to delete created environments
token: ${{ secrets.DOCUBOT_REPO_PAT }}
environment: preview-env-${{ env.PR_NUMBER }}

View File

@@ -48,17 +48,12 @@ jobs:
env:
PR_NUMBER: ${{ github.event.pull_request.number }}
steps:
- name: 'Az CLI login'
uses: azure/login@1f63701bf3e6892515f1b7ce2d2bf1708b46beaf
with:
creds: ${{ secrets.NONPROD_AZURE_CREDENTIALS }}
- name: check out repo content
uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
- name: Get preview app info
env:
FULL_APP_INFO: 1
APP_NAME_SEED: ${{ secrets.PREVIEW_ENV_NAME_SEED }}
run: .github/actions-scripts/get-preview-app-info.sh
- name: Setup Node

View File

@@ -41,7 +41,7 @@ jobs:
run: |
gh pr comment $PR --body "Thanks so much for opening this PR and contributing to GitHub Docs!
- When you're ready for the Docs team to review this PR, apply the **ready-for-doc-review** label and your PR will be added to the [Docs Content review board](https://github.com/orgs/github/memexes/901?layout=table&groupedBy%5BcolumnId%5D=11024). **Please factor in at least 72 hours for a review, even longer if this is a substantial change.**
- When you're ready for the Docs team to review this PR, request a review by *docs-content* and your PR will be added to the [Docs Content review board](https://github.com/orgs/github/memexes/901?layout=table&groupedBy%5BcolumnId%5D=11024). **Please factor in at least 72 hours for a review, even longer if this is a substantial change.**
- If this is a major update to the docs, you might want to go back and open an [issue](https://github.com/github/docs-content/issues/new/choose) to ensure we've covered all areas of the docs in these updates. Not doing so may result in delays or inaccurate documentation."
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -24,8 +24,6 @@ jobs:
timeout-minutes: 15
env:
ENABLE_EARLY_ACCESS: ${{ github.repository == 'github/docs-internal' }}
NONPROD_REGISTRY_USERNAME: ghdocs
NONPROD_REGISTRY_NAME: ghdocs
DOCKER_IMAGE_CACHE_REF: ${{ secrets.NONPROD_REGISTRY_SERVER }}/${{ github.repository }}:main-preview
steps:
@@ -38,7 +36,7 @@ jobs:
uses: azure/docker-login@81744f9799e7eaa418697cb168452a2882ae844a
with:
login-server: ${{ secrets.NONPROD_REGISTRY_SERVER }}
username: ${{ env.NONPROD_REGISTRY_USERNAME }}
username: ${{ secrets.NONPROD_REGISTRY_USERNAME }}
password: ${{ secrets.NONPROD_REGISTRY_PASSWORD }}
- name: Set up Docker Buildx

View File

@@ -50,6 +50,6 @@ jobs:
git push --set-upstream origin $BRANCH
echo "Open a pull request"
gh pr create --title "Optimize images" --body "Optimize images" --reviewer "@github/docs-engineering"
gh pr create --title "Optimize images" --body "Optimize images" --reviewer "github/docs-engineering"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -1,31 +0,0 @@
name: Ping staging apps
# **What it does**: This keeps our staging applications from automatically spinning down.
# **Why we have it**: Staging applications can hiberate without use.
# **Who does it impact**: Anyone with a pull request in docs-internal.
on:
schedule:
- cron: '10,30,50 * * * *' # every twenty minutes
permissions:
contents: read
jobs:
ping_staging_apps:
name: Ping
if: github.repository == 'github/docs-internal'
runs-on: ubuntu-latest
env:
HEROKU_API_TOKEN: ${{ secrets.HEROKU_API_TOKEN }}
steps:
- uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
- name: Setup node
uses: actions/setup-node@1f8c6b94b26d0feae1e387ca63ccbdc44d27b561
with:
node-version: 16.13.x
cache: npm
- name: npm ci
run: npm ci
- name: Run script
run: script/ping-staging-apps.js

View File

@@ -90,12 +90,12 @@ jobs:
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 preview slot'
- name: 'Apply updated docker-compose.prod.yaml config to staging slot'
run: |
az webapp config container set --multicontainer-config-type COMPOSE --multicontainer-config-file docker-compose.prod.yaml --slot preview -n ghdocs-prod -g docs-prod
az webapp config container set --multicontainer-config-type COMPOSE --multicontainer-config-file docker-compose.prod.yaml --slot staging -n ghdocs-prod -g docs-prod
# Watch preview slot instances to see when all the instances are ready
- name: Check that preview slot is ready
# Watch staging slot instances to see when all the instances are ready
- name: Check that staging slot is ready
uses: actions/github-script@2b34a689ec86a68d8ab9478298f91d5401337b7d
env:
CHECK_INTERVAL: 10000
@@ -115,7 +115,7 @@ jobs:
let hasStopped = false
const waitDuration = parseInt(process.env.CHECK_INTERVAL, 10) || 10000
async function doCheck() {
const states = getStatesForSlot('preview')
const states = getStatesForSlot('staging')
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 +136,10 @@ jobs:
doCheck()
# TODO - make a request to verify the preview app version aligns with *this* github action workflow commit sha
- name: 'Swap preview slot to production'
# TODO - make a request to verify the staging app version aligns with *this* github action workflow commit sha
- name: 'Swap staging slot to production'
run: |
az webapp deployment slot swap --slot preview --target-slot production -n ghdocs-prod -g docs-prod
az webapp deployment slot swap --slot staging --target-slot production -n ghdocs-prod -g docs-prod
- name: Purge Fastly edge cache
env:

View File

@@ -1,199 +0,0 @@
name: Production - Build and Deploy
# **What it does**: Builds and deploys the default branch to production
# **Why we have it**: To enable us to deploy the latest to production whenever necessary rather than relying on PR merges.
# **Who does it impact**: All contributors.
on:
push:
branches:
- main
workflow_dispatch:
permissions:
contents: read
deployments: write
# This allows a subsequently queued workflow run to take priority over
# previously queued runs but NOT interrupt currently executing runs
concurrency:
group: '${{ github.workflow }}'
cancel-in-progress: false
jobs:
build-and-deploy:
if: ${{ github.repository == 'github/docs-internal'}}
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Check out repo
uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
with:
persist-credentials: 'false'
lfs: 'true'
- name: Check out LFS objects
run: git lfs checkout
- name: Setup node
uses: actions/setup-node@1f8c6b94b26d0feae1e387ca63ccbdc44d27b561
with:
node-version: 16.13.x
cache: npm
# Required for `npm pkg ...` command support
- name: Update to npm@^7.20.0
run: npm install --global npm@^7.20.0
- name: Install dependencies
run: npm ci
- name: Clone early access
run: node script/early-access/clone-for-build.js
env:
DOCUBOT_REPO_PAT: ${{ secrets.DOCUBOT_REPO_PAT }}
GIT_BRANCH: main
- name: Cache nextjs build
uses: actions/cache@937d24475381cd9c75ae6db12cb4e79714b926ed
with:
path: .next/cache
key: ${{ runner.os }}-nextjs-${{ hashFiles('package*.json') }}
- name: Build
run: npm run build
- name: Remove development-only dependencies
run: npm prune --production
- name: Remove all npm scripts
run: npm pkg delete scripts
- name: Set npm script for Heroku build to noop
run: npm set-script heroku-postbuild "echo 'Application was pre-built!'"
- name: Create a gzipped archive
run: |
tar -cz --file=app.tar.gz \
node_modules/ \
.next/ \
assets/ \
content/ \
data/ \
includes/ \
lib/ \
middleware/ \
translations/ \
server.mjs \
package*.json \
.npmrc \
feature-flags.json \
next.config.js \
app.json \
Procfile
- name: Install the development dependencies again
run: npm install
- name: Create a Heroku build source
id: build-source
uses: actions/github-script@2b34a689ec86a68d8ab9478298f91d5401337b7d
env:
HEROKU_API_TOKEN: ${{ secrets.HEROKU_API_TOKEN }}
with:
script: |
const { owner, repo } = context.repo
if (owner !== 'github') {
throw new Error(`Repository owner must be 'github' but was: ${owner}`)
}
if (repo !== 'docs-internal') {
throw new Error(`Repository name must be 'docs-internal' but was: ${repo}`)
}
const Heroku = require('heroku-client')
const heroku = new Heroku({ token: process.env.HEROKU_API_TOKEN })
try {
const { source_blob: sourceBlob } = await heroku.post('/sources')
const { put_url: uploadUrl, get_url: downloadUrl } = sourceBlob
core.setOutput('upload_url', uploadUrl)
core.setOutput('download_url', downloadUrl)
} catch (error) {
if (error.statusCode === 503) {
console.error('💀 Heroku may be down! Please check its Status page: https://status.heroku.com/')
}
throw error
}
# See: https://devcenter.heroku.com/articles/build-and-release-using-the-api#sources-endpoint
- name: Upload to the Heroku build source
env:
UPLOAD_URL: ${{ steps.build-source.outputs.upload_url }}
run: |
curl "$UPLOAD_URL" \
-X PUT \
-H 'Content-Type:' \
--data-binary @app.tar.gz
- name: Deploy
id: deploy
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
HEROKU_API_TOKEN: ${{ secrets.HEROKU_API_TOKEN }}
HEROKU_PRODUCTION_APP_NAME: ${{ secrets.HEROKU_PRODUCTION_APP_NAME }}
HYDRO_ENDPOINT: ${{ secrets.HYDRO_ENDPOINT }}
HYDRO_SECRET: ${{ secrets.HYDRO_SECRET }}
SOURCE_BLOB_URL: ${{ steps.build-source.outputs.download_url }}
DELAY_FOR_PREBOOT: 'true'
ALLOWED_POLLING_FAILURES_PER_PHASE: '15'
RUN_ID: ${{ github.run_id }}
run: .github/actions-scripts/prod-deploy.js
- name: Mark the deployment as inactive if timed out
uses: actions/github-script@2b34a689ec86a68d8ab9478298f91d5401337b7d
if: ${{ steps.deploy.outcome == 'cancelled' }}
env:
DEPLOYMENT_ID: ${{ steps.deploy.outputs.deploymentId }}
LOG_URL: ${{ steps.deploy.outputs.logUrl }}
with:
script: |
const { DEPLOYMENT_ID, LOG_URL } = process.env
const { owner, repo } = context.repo
if (!DEPLOYMENT_ID) {
throw new Error('A deployment wasn't created before a timeout occurred!')
}
await github.repos.createDeploymentStatus({
owner,
repo,
deployment_id: DEPLOYMENT_ID,
state: 'error',
description: 'The deployment step timed out. See workflow logs.',
log_url: LOG_URL,
// The 'ant-man' preview is required for `state` values of 'inactive', as well as
// the use of the `log_url`, `environment_url`, and `auto_inactive` parameters.
// The 'flash' preview is required for `state` values of 'in_progress' and 'queued'.
mediaType: {
previews: ['ant-man', 'flash'],
},
})
console.log('⏲️ Deployment status: error - The deployment timed out...')
# - name: Purge Fastly edge cache
# env:
# FASTLY_TOKEN: ${{ secrets.FASTLY_TOKEN }}
# FASTLY_SERVICE_ID: ${{ secrets.FASTLY_SERVICE_ID }}
# FASTLY_SURROGATE_KEY: 'every-deployment'
# run: .github/actions-scripts/purge-fastly-edge-cache.js
- 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: Production deployment failed at commit ${{ github.sha }}. See https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}

View File

@@ -1,12 +1,12 @@
name: Ready for docs-content review
# **What it does**: Adds pull requests in the docs-internal repository to the docs-content review board when the "ready-for-doc-review" label is added
# **What it does**: Adds pull requests in the docs-internal repository to the docs-content review board when the "ready-for-doc-review" label is added or when a review by docs-content is requested
# **Why we have it**: So that other GitHub teams can easily request reviews from the docs-content team, and so that writers can see when a PR is ready for review
# **Who does it impact**: Writers working in the docs-internal repository
on:
pull_request_target:
types: [labeled]
types: [labeled, review_requested]
permissions:
contents: read
@@ -14,7 +14,9 @@ permissions:
jobs:
request_doc_review:
name: Request a review from the docs-content team
if: github.event.label.name == 'ready-for-doc-review' && github.repository == 'github/docs-internal'
if: >-
github.repository == 'github/docs-internal' &&
(github.event.label.name == 'ready-for-doc-review' || github.event.requested_team.name == 'docs-content')
runs-on: ubuntu-latest
steps:
- name: Check out repo content

View File

@@ -1,69 +0,0 @@
name: Remove stale staging resources
# **What it does**:
# This cleans up any rogue staging applications and environments that outlasted
# the closure of their corresponding pull requests.
# **Why we have it**:
# Staging applications and environments should be destroyed after their
# corresponding pull request is closed or merged, especially to save money spent
# on Heroku App staging deployments for closed PRs.
# **Who does it impact**:
# Anyone with a closed, spammy, or deleted pull request in docs or docs-internal.
on:
schedule:
- cron: '15,45 * * * *' # every thirty minutes at :15 and :45
permissions:
actions: read
contents: read
deployments: write
pull-requests: write
jobs:
remove_stale_staging_apps:
name: Remove stale staging apps
if: ${{ github.repository == 'github/docs-internal' }}
runs-on: ubuntu-latest
steps:
- name: Check out repo's default branch
uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
- name: Setup Node
uses: actions/setup-node@1f8c6b94b26d0feae1e387ca63ccbdc44d27b561
with:
node-version: 16.13.x
cache: npm
- name: Install dependencies
run: npm ci
- name: Run script
run: script/remove-stale-staging-apps.js
env:
HEROKU_API_TOKEN: ${{ secrets.HEROKU_API_TOKEN }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
remove_stale_staging_envs:
name: Remove stale staging environments
runs-on: ubuntu-latest
steps:
- name: Check out repo's default branch
uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
- name: Setup Node
uses: actions/setup-node@1f8c6b94b26d0feae1e387ca63ccbdc44d27b561
with:
node-version: 16.13.x
cache: npm
- name: Install dependencies
run: npm ci
- name: Run script
run: script/remove-stale-staging-envs.js
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
ELEVATED_TOKEN: ${{ secrets.DOCS_BOT_FR }}
REPO: ${{ github.repository }}
RUN_ID: ${{ github.run_id }}

View File

@@ -1,210 +0,0 @@
name: Staging - Build and Deploy PR (fast and private-only)
# **What it does**: Builds and deploys PRs to staging but ONLY for docs-internal
# **Why we have it**: Most PRs are made on the private repo. Let's make those extra fast if we can worry less about security.
# **Who does it impact**: All staff.
# This whole workflow is only guaranteed to be secure in the *private
# repo* and because we repo-sync these files over the to the public one,
# IT'S IMPORTANT THAT THIS WORKFLOW IS ONLY ENABLED IN docs-internal!
on:
# The advantage of 'pull_request' over 'pull_request_target' is that we
# can make changes to this file and test them in a pull request, instead
# of relying on landing it in 'main' first.
# From a security point of view, its arguably safer this way because
# unlike 'pull_request_target', these only have secrets if the pull
# request creator has permission to access secrets.
pull_request:
permissions:
actions: read
contents: read
deployments: write
pull-requests: read
statuses: write
# This allows a subsequently queued workflow run to interrupt previous runs
concurrency:
group: '${{ github.workflow }} @ ${{ github.event.pull_request.head.label || github.head_ref || github.ref }}'
cancel-in-progress: true
jobs:
build-and-deploy-pr:
# Important. This whole file is only supposed to run in the PRIVATE repo.
if: ${{ github.repository == 'github/docs-internal' }}
# The assumption here is that self-hosted is faster (e.g CPU power)
# that the regular ones. And it matters in this workflow because
# we do heavy CPU stuff with `npm run build` and `tar`
# runs-on: ubuntu-latest
runs-on: self-hosted
timeout-minutes: 5
steps:
- name: Check out repo
uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
with:
lfs: 'true'
# To prevent issues with cloning early access content later
persist-credentials: 'false'
- name: Check out LFS objects
run: git lfs checkout
- name: Setup node
uses: actions/setup-node@1f8c6b94b26d0feae1e387ca63ccbdc44d27b561
with:
node-version: 16.13.x
cache: npm
- name: Install dependencies
run: npm ci
- name: Cache nextjs build
uses: actions/cache@937d24475381cd9c75ae6db12cb4e79714b926ed
with:
path: .next/cache
key: ${{ runner.os }}-nextjs-${{ hashFiles('package*.json') }}
- name: Build
run: npm run build
- name: Clone early access
run: node script/early-access/clone-for-build.js
env:
DOCUBOT_REPO_PAT: ${{ secrets.DOCUBOT_REPO_PAT }}
GIT_BRANCH: ${{ github.head_ref || github.ref }}
- name: Create a Heroku build source
id: build-source
uses: actions/github-script@2b34a689ec86a68d8ab9478298f91d5401337b7d
env:
HEROKU_API_TOKEN: ${{ secrets.HEROKU_API_TOKEN }}
with:
script: |
const { owner, repo } = context.repo
if (owner !== 'github') {
throw new Error(`Repository owner must be 'github' but was: ${owner}`)
}
if (repo !== 'docs-internal') {
throw new Error(`Repository name must be 'docs-internal' but was: ${repo}`)
}
const Heroku = require('heroku-client')
const heroku = new Heroku({ token: process.env.HEROKU_API_TOKEN })
try {
const { source_blob: sourceBlob } = await heroku.post('/sources')
const { put_url: uploadUrl, get_url: downloadUrl } = sourceBlob
core.setOutput('upload_url', uploadUrl)
core.setOutput('download_url', downloadUrl)
} catch (error) {
if (error.statusCode === 503) {
console.error('💀 Heroku may be down! Please check its Status page: https://status.heroku.com/')
}
throw error
}
- name: Remove development-only dependencies
run: npm prune --production
- name: Remove all npm scripts
run: npm pkg delete scripts
- name: Set npm script for Heroku build to noop
run: npm set-script heroku-postbuild "echo 'Application was pre-built!'"
- name: Delete heavy things we won't need deployed
run: |
# The dereferenced file is not used in runtime once the
# decorated file has been created from it.
rm -rf lib/rest/static/dereferenced
# Translations are never tested in Staging builds
# but let's keep the empty directory.
rm -rf translations
mkdir translations
# Delete all the big search indexes that are NOT English (`*-en-*`)
pushd lib/search/indexes
ls | grep -ve '\-en\b' | xargs rm
popd
# Note! Some day it would be nice to be able to delete
# all the heavy assets because they bloat the tarball.
# But it's not obvious how to test it then. For now, we'll have
# to accept that every staging build has a copy of the images.
# The assumption here is that a staging build will not
# need these legacy redirects. Only the redirects from
# front-matter will be at play.
# These static redirects json files are notoriously large
# and they make the tarball unnecessarily large.
echo '[]' > lib/redirects/static/archived-frontmatter-fallbacks.json
echo '{}' > lib/redirects/static/developer.json
echo '{}' > lib/redirects/static/archived-redirects-from-213-to-217.json
# This will turn every `lib/**/static/*.json` into
# an equivalent `lib/**/static/*.json.br` file.
# Once the server starts, it'll know to fall back to reading
# the `.br` equivalent if the `.json` file isn't present.
node .github/actions-scripts/compress-large-files.js
- name: Make the tarball for Heroku
run: |
# We can't delete the .next/cache directory from the workflow
# because it's needed for caching, but we can at least exclude it
# from the tarball. Then it can be cached but not weigh down the
# tarball we intend to deploy.
tar -zc --exclude=.next/cache --file=app.tar.gz \
node_modules/ \
.next/ \
assets/ \
content/ \
data/ \
includes/ \
lib/ \
middleware/ \
translations/ \
server.mjs \
package*.json \
.npmrc \
feature-flags.json \
next.config.js \
app.json \
Procfile
du -sh app.tar.gz
# See: https://devcenter.heroku.com/articles/build-and-release-using-the-api#sources-endpoint
- name: Upload to the Heroku build source
env:
UPLOAD_URL: ${{ steps.build-source.outputs.upload_url }}
run: |
curl "$UPLOAD_URL" \
-X PUT \
-H 'Content-Type:' \
--data-binary @app.tar.gz
# 'npm install' is faster than 'npm ci' because it only needs to
# *append* what's missing from ./node_modules/
- name: Re-install dependencies so we get devDependencies back
run: npm install --no-audit --no-fund --only=dev
- name: Deploy
id: deploy
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
HEROKU_API_TOKEN: ${{ secrets.HEROKU_API_TOKEN }}
HYDRO_ENDPOINT: ${{ secrets.HYDRO_ENDPOINT }}
HYDRO_SECRET: ${{ secrets.HYDRO_SECRET }}
PR_URL: ${{ github.event.pull_request.html_url }}
SOURCE_BLOB_URL: ${{ steps.build-source.outputs.download_url }}
ALLOWED_POLLING_FAILURES_PER_PHASE: '15'
RUN_ID: ${{ github.run_id }}
run: .github/actions-scripts/staging-deploy.js

View File

@@ -1,135 +0,0 @@
name: Staging - Build PR
# **What it does**: Builds PRs before deploying them.
# **Why we have it**: Because it's not safe to share our deploy secrets with forked repos: https://securitylab.github.com/research/github-actions-preventing-pwn-requests/
# **Who does it impact**: All contributors.
# IT'S CRUCIALLY IMPORTANT THAT THIS WORKFLOW IS ONLY ENABLED IN docs!
on:
pull_request:
permissions:
contents: read
# This allows a subsequently queued workflow run to interrupt previous runs
# These are different from the concurrency in that here it checks if the
# whole workflow runs again. The "inner concurrency" is used for
# undeployments to cleaning up resources.
concurrency:
group: '${{ github.workflow }} @ ${{ github.event.pull_request.head.label || github.head_ref || github.ref }}'
cancel-in-progress: true
jobs:
build-pr:
# Important. This whole file is only supposed to run in the PUBLIC repo.
if: ${{ github.repository == 'github/docs' }}
runs-on: ${{ fromJSON('["ubuntu-latest", "self-hosted"]')[github.repository == 'github/docs-internal'] }}
timeout-minutes: 5
# This interrupts Build and Deploy workflow runs in progress for this PR branch.
concurrency:
group: 'PR Staging @ ${{ github.event.pull_request.head.label || github.head_ref || github.ref }}'
cancel-in-progress: true
steps:
- name: Check out repo
uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
# Make sure only approved files are changed if it's in github/docs
- name: Check changed files
if: ${{ github.event.pull_request.user.login != 'Octomerger' }}
uses: dorny/paths-filter@eb75a1edc117d3756a18ef89958ee59f9500ba58
id: filter
with:
# Base branch used to get changed files
base: 'main'
# Enables setting an output in the format in `${FILTER_NAME}_files
# with the names of the matching files formatted as JSON array
list-files: json
# Returns list of changed files matching each filter
filters: |
notAllowed:
- '*.js'
- '*.mjs'
- '*.cjs'
- '*.ts'
- '*.tsx'
- '*.json'
- '.npmrc'
- '.babelrc*'
- '.env*'
- 'script/**'
- 'Procfile'
# When there are changes to files we can't accept
- name: Fail when disallowed files are changed
if: ${{ steps.filter.outputs.notAllowed == 'true' }}
run: exit 1
- name: Setup node
uses: actions/setup-node@1f8c6b94b26d0feae1e387ca63ccbdc44d27b561
with:
node-version: 16.13.x
cache: npm
# Required for `npm pkg ...` command support
- name: Update to npm@^7.20.0
run: npm install --global npm@^7.20.0
- name: Install dependencies
run: npm ci
- name: Cache nextjs build
uses: actions/cache@937d24475381cd9c75ae6db12cb4e79714b926ed
with:
path: .next/cache
key: ${{ runner.os }}-nextjs-${{ hashFiles('package*.json') }}
- name: Build
run: npm run build
- name: Remove development-only dependencies
run: npm prune --production
- name: Remove all npm scripts
run: npm pkg delete scripts
- name: Set npm script for Heroku build to noop
run: npm set-script heroku-postbuild "echo 'Application was pre-built!'"
- name: Create an archive
run: |
tar -c --file=app.tar \
node_modules/ \
.next/ \
assets/ \
content/ \
data/ \
includes/ \
lib/ \
middleware/ \
translations/ \
server.mjs \
package*.json \
.npmrc \
feature-flags.json \
next.config.js \
app.json \
Procfile
# We can't delete the .next/cache directory from the workflow
# because it's needed for caching, but we can at least delete it
# from within the tarball. Then it can be cached but not
# weigh down the tarball we intend to deploy.
tar --delete --file=app.tar .next/cache
# Upload only the files needed to run this application.
# 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@82c141cc518b40d92cc801eee768e7aafc9c2fa2
with:
name: pr_build
path: app.tar

View File

@@ -1,466 +0,0 @@
name: Staging - Deploy PR
# **What it does**: To deploy PRs to a Heroku staging environment.
# **Why we have it**: To deploy with high visibility in case of failures.
# **Who does it impact**: All contributors.
# IT'S CRUCIALLY IMPORTANT THAT THIS WORKFLOW IS ONLY ENABLED IN docs!
on:
workflow_run:
workflows:
- 'Staging - Build PR'
types:
- completed
permissions:
actions: read
contents: read
deployments: write
pull-requests: read
statuses: write
# IMPORTANT: Intentionally OMIT a `concurrency` configuration from this workflow's
# top-level as we do not have any guarantee of identifying values being available
# within the `github.event` context for PRs from forked repos!
#
# The implication of this shortcoming is that we may have multiple workflow runs
# of this running at the same time for different commits within the same PR.
# However, once they reach the `concurrency` configurations deeper down within
# this workflow's jobs, then we can expect concurrent short-circuiting to begin.
env:
CONTEXT_NAME: '${{ github.workflow }} / deploy (${{ github.event.workflow_run.event }})'
ACTIONS_RUN_LOG: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}
BUILD_ACTIONS_RUN_ID: ${{ github.event.workflow_run.id }}
BUILD_ACTIONS_RUN_LOG: https://github.com/${{ github.repository }}/actions/runs/${{ github.event.workflow_run.id }}
jobs:
pr-metadata:
# This is needed because the workflow we depend on
# (see on.workflow_run.workflows) might be running from pushes on
# main. That's because it needs to do that to popular the cache.
if: >-
${{
github.repository == 'github/docs' &&
github.event.workflow_run.event == 'pull_request' &&
github.event.workflow_run.conclusion == 'success'
}}
runs-on: ubuntu-latest
outputs:
number: ${{ steps.pr.outputs.number }}
url: ${{ steps.pr.outputs.url }}
state: ${{ steps.pr.outputs.state }}
head_sha: ${{ steps.pr.outputs.head_sha }}
head_branch: ${{ steps.pr.outputs.head_branch }}
head_label: ${{ steps.pr.outputs.head_label }}
head_ref: ${{ steps.pr.outputs.head_ref }}
steps:
- name: Find the originating pull request
id: pr
uses: actions/github-script@2b34a689ec86a68d8ab9478298f91d5401337b7d
env:
BUILD_ACTIONS_RUN_ID: ${{ env.BUILD_ACTIONS_RUN_ID }}
with:
script: |
// Curious about what version of node you get
console.log('Node version:', process.version)
// In order to find out the PR info for a forked repo, we must query
// the API for more info based on the originating workflow run
const { BUILD_ACTIONS_RUN_ID } = process.env
const { owner, repo } = context.repo
const { data: run } = await github.actions.getWorkflowRun({
owner,
repo,
run_id: BUILD_ACTIONS_RUN_ID,
})
// Gather PR-identifying information from the workflow run
const {
head_branch: headBranch,
head_sha: headSha,
head_repository: {
owner: { login: prRepoOwner },
name: prRepoName
}
} = run
const prIsInternal = owner === prRepoOwner && repo === prRepoName
let headLabel = `${prRepoOwner}:${headBranch}`
// If the PR is external, prefix its head branch name with the
// forked repo owner's login and their fork repo name e.g.
// "octocat/my-fork:docs". We need to include the fork repo
// name as well to account for an API issue (this will work fine
// if they don't have a different fork repo name).
if (!prIsInternal) {
headLabel = `${prRepoOwner}/${prRepoName}:${headBranch}`
}
// If the PR is external, prefix its head branch name with the
// forked repo owner's login, e.g. "octocat:docs"
const headRef = prIsInternal ? headBranch : headLabel
// Retrieve matching PRs (up to 30)
const { data: pulls } = await github.pulls.list({
owner,
repo,
head: headLabel,
sort: 'updated',
direction: 'desc',
per_page: 30
})
// Find the open PR, if any, otherwise choose the most recently updated
const targetPull = pulls.find(pr => pr.state === 'open') || pulls[0] || {}
const pullNumber = targetPull.number || 0
const pullUrl = targetPull.html_url || 'about:blank'
const pullState = targetPull.state || 'closed'
core.setOutput('number', pullNumber.toString())
core.setOutput('url', pullUrl)
core.setOutput('state', pullState)
core.setOutput('head_sha', headSha)
core.setOutput('head_branch', headBranch)
core.setOutput('head_label', headLabel)
core.setOutput('head_ref', headRef)
debug-originating-trigger:
needs: pr-metadata
runs-on: ubuntu-latest
steps:
- name: Dump info about the originating workflow run
env:
PR_NUMBER: ${{ needs.pr-metadata.outputs.number }}
PR_URL: ${{ needs.pr-metadata.outputs.url }}
PR_STATE: ${{ needs.pr-metadata.outputs.state }}
HEAD_SHA: ${{ needs.pr-metadata.outputs.head_sha }}
HEAD_BRANCH: ${{ needs.pr-metadata.outputs.head_branch }}
HEAD_LABEL: ${{ needs.pr-metadata.outputs.head_label }}
HEAD_REF: ${{ needs.pr-metadata.outputs.head_ref }}
BUILD_ACTIONS_RUN_ID: ${{ env.BUILD_ACTIONS_RUN_ID }}
BUILD_ACTIONS_RUN_LOG: ${{ env.BUILD_ACTIONS_RUN_LOG }}
run: |
echo "Originating workflow info:"
echo " - PR_NUMBER = $PR_NUMBER"
echo " - PR_URL = $PR_URL"
echo " - PR_STATE = $PR_STATE"
echo " - HEAD_SHA = $HEAD_SHA"
echo " - HEAD_BRANCH = $HEAD_BRANCH"
echo " - HEAD_LABEL = $HEAD_LABEL"
echo " - HEAD_REF = $HEAD_REF"
echo " - BUILD_ACTIONS_RUN_ID = $BUILD_ACTIONS_RUN_ID"
echo " - BUILD_ACTIONS_RUN_LOG = $BUILD_ACTIONS_RUN_LOG"
notify-of-failed-builds:
needs: pr-metadata
if: >-
${{
needs.pr-metadata.outputs.number != '0' &&
github.event.workflow_run.conclusion == 'failure'
}}
runs-on: ubuntu-latest
timeout-minutes: 1
# Specifically omitting a concurrency group here in case the build was not
# successful BECAUSE a subsequent build already canceled it
steps:
- name: Verify build workflow run was not cancelled
id: check-workflow-run
uses: actions/github-script@2b34a689ec86a68d8ab9478298f91d5401337b7d
env:
BUILD_ACTIONS_RUN_ID: ${{ env.BUILD_ACTIONS_RUN_ID }}
with:
script: |
const { owner, repo } = context.repo
const { data: { jobs: buildJobs } } = await github.actions.listJobsForWorkflowRun({
owner,
repo,
run_id: process.env.BUILD_ACTIONS_RUN_ID,
filter: 'latest'
})
const wasCancelled = (
buildJobs.length > 0 &&
buildJobs.every(({ status, conclusion }) => {
return status === 'completed' && conclusion === 'cancelled'
})
)
core.setOutput('cancelled', wasCancelled.toString())
- if: ${{ steps.check-workflow-run.outputs.cancelled == 'false' }}
name: Send Slack notification if build workflow failed
uses: someimportantcompany/github-actions-slack-message@f8d28715e7b8a4717047d23f48c39827cacad340
with:
channel: ${{ secrets.DOCS_STAGING_DEPLOYMENT_FAILURES_SLACK_CHANNEL_ID }}
bot-token: ${{ secrets.SLACK_DOCS_BOT_TOKEN }}
color: failure
text: Staging build failed for PR ${{ needs.pr-metadata.outputs.url }} at commit ${{ needs.pr-metadata.outputs.head_sha }}. See ${{ env.BUILD_ACTIONS_RUN_LOG }}. This run was ${{ env.ACTIONS_RUN_LOG }}.
prepare-for-deploy:
needs: pr-metadata
if: ${{ needs.pr-metadata.outputs.state == 'open' }}
runs-on: ubuntu-latest
timeout-minutes: 5
# This interrupts Build and Deploy workflow runs in progress for this PR branch.
concurrency:
group: 'PR Staging @ ${{ needs.pr-metadata.outputs.head_label }}'
cancel-in-progress: true
outputs:
source_blob_url: ${{ steps.build-source.outputs.download_url }}
steps:
- name: Create initial status
uses: actions/github-script@2b34a689ec86a68d8ab9478298f91d5401337b7d
env:
CONTEXT_NAME: ${{ env.CONTEXT_NAME }}
ACTIONS_RUN_LOG: ${{ env.ACTIONS_RUN_LOG }}
HEAD_SHA: ${{ needs.pr-metadata.outputs.head_sha }}
with:
script: |
const { CONTEXT_NAME, ACTIONS_RUN_LOG, HEAD_SHA } = process.env
const { owner, repo } = context.repo
await github.repos.createCommitStatus({
owner,
repo,
sha: HEAD_SHA,
context: CONTEXT_NAME,
state: 'pending',
description: 'The app is being deployed. See logs.',
target_url: ACTIONS_RUN_LOG
})
- name: Check out repo's default branch
uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
with:
# To prevent issues with cloning early access content later
persist-credentials: 'false'
lfs: 'true'
- name: Check out LFS objects
run: git lfs checkout
- name: Setup node
uses: actions/setup-node@1f8c6b94b26d0feae1e387ca63ccbdc44d27b561
with:
node-version: 16.13.x
cache: npm
# Install any additional dependencies *before* downloading the build artifact
- name: Install Heroku client development-only dependency
run: npm install --no-save heroku-client
# Download the previously built "app.tar"
- name: Download build artifact
uses: dawidd6/action-download-artifact@af92a8455a59214b7b932932f2662fdefbd78126
with:
workflow: ${{ github.event.workflow_run.workflow_id }}
run_id: ${{ env.BUILD_ACTIONS_RUN_ID }}
name: pr_build
path: ${{ runner.temp }}
# gzip the app.tar to meet Heroku's expected format
- name: Create a gzipped archive (docs)
run: gzip -9 < "$RUNNER_TEMP/app.tar" > app.tar.gz
- name: Create a Heroku build source
id: build-source
uses: actions/github-script@2b34a689ec86a68d8ab9478298f91d5401337b7d
env:
HEROKU_API_TOKEN: ${{ secrets.HEROKU_API_TOKEN }}
with:
script: |
const { owner, repo } = context.repo
if (owner !== 'github') {
throw new Error(`Repository owner must be 'github' but was: ${owner}`)
}
if (repo !== 'docs') {
throw new Error(`Repository name must be 'docs' but was: ${repo}`)
}
const Heroku = require('heroku-client')
const heroku = new Heroku({ token: process.env.HEROKU_API_TOKEN })
try {
const { source_blob: sourceBlob } = await heroku.post('/sources')
const { put_url: uploadUrl, get_url: downloadUrl } = sourceBlob
core.setOutput('upload_url', uploadUrl)
core.setOutput('download_url', downloadUrl)
} catch (error) {
if (error.statusCode === 503) {
console.error('💀 Heroku may be down! Please check its Status page: https://status.heroku.com/')
}
throw error
}
# See: https://devcenter.heroku.com/articles/build-and-release-using-the-api#sources-endpoint
- name: Upload to the Heroku build source
env:
UPLOAD_URL: ${{ steps.build-source.outputs.upload_url }}
run: |
curl "$UPLOAD_URL" \
-X PUT \
-H 'Content-Type:' \
--data-binary @app.tar.gz
- name: Create failure status
uses: actions/github-script@2b34a689ec86a68d8ab9478298f91d5401337b7d
if: ${{ failure() }}
env:
CONTEXT_NAME: ${{ env.CONTEXT_NAME }}
ACTIONS_RUN_LOG: ${{ env.ACTIONS_RUN_LOG }}
HEAD_SHA: ${{ needs.pr-metadata.outputs.head_sha }}
with:
script: |
const { CONTEXT_NAME, ACTIONS_RUN_LOG, HEAD_SHA } = process.env
const { owner, repo } = context.repo
await github.repos.createCommitStatus({
owner,
repo,
sha: HEAD_SHA,
context: CONTEXT_NAME,
state: 'error',
description: 'Failed to deploy. See logs.',
target_url: ACTIONS_RUN_LOG
})
- name: Send Slack notification if deployment preparation job failed
uses: someimportantcompany/github-actions-slack-message@f8d28715e7b8a4717047d23f48c39827cacad340
if: ${{ failure() }}
with:
channel: ${{ secrets.DOCS_STAGING_DEPLOYMENT_FAILURES_SLACK_CHANNEL_ID }}
bot-token: ${{ secrets.SLACK_DOCS_BOT_TOKEN }}
color: failure
text: Staging preparation failed for PR ${{ needs.pr-metadata.outputs.url }} at commit ${{ needs.pr-metadata.outputs.head_sha }}. See ${{ env.ACTIONS_RUN_LOG }}.
check-pr-before-deploy:
needs: [pr-metadata, prepare-for-deploy]
runs-on: ubuntu-latest
timeout-minutes: 1
# This interrupts Build and Deploy workflow runs in progress for this PR branch.
concurrency:
group: 'PR Staging @ ${{ needs.pr-metadata.outputs.head_label }}'
cancel-in-progress: true
outputs:
pull_request_state: ${{ steps.check-pr.outputs.state }}
steps:
- name: Check pull request state
id: check-pr
uses: actions/github-script@2b34a689ec86a68d8ab9478298f91d5401337b7d
env:
PR_NUMBER: ${{ needs.pr-metadata.outputs.number }}
with:
script: |
const { owner, repo } = context.repo
const { data: pullRequest } = await github.pulls.get({
owner,
repo,
pull_number: process.env.PR_NUMBER
})
core.setOutput('state', pullRequest.state)
deploy:
needs: [pr-metadata, prepare-for-deploy, check-pr-before-deploy]
if: ${{ needs.check-pr-before-deploy.outputs.pull_request_state == 'open' }}
runs-on: ubuntu-latest
timeout-minutes: 10
# This interrupts Build and Deploy workflow runs in progress for this PR branch.
concurrency:
group: 'PR Staging @ ${{ needs.pr-metadata.outputs.head_label }}'
cancel-in-progress: true
steps:
- name: Check out repo's default branch
uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
- name: Setup node
uses: actions/setup-node@1f8c6b94b26d0feae1e387ca63ccbdc44d27b561
with:
node-version: 16.13.x
cache: npm
- name: Install dependencies
run: npm ci
- name: Deploy
id: deploy
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
HEROKU_API_TOKEN: ${{ secrets.HEROKU_API_TOKEN }}
HYDRO_ENDPOINT: ${{ secrets.HYDRO_ENDPOINT }}
HYDRO_SECRET: ${{ secrets.HYDRO_SECRET }}
PR_URL: ${{ needs.pr-metadata.outputs.url }}
SOURCE_BLOB_URL: ${{ needs.prepare-for-deploy.outputs.source_blob_url }}
ALLOWED_POLLING_FAILURES_PER_PHASE: '15'
RUN_ID: ${{ github.run_id }}
run: .github/actions-scripts/staging-deploy.js
- name: Create successful commit status
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
CONTEXT_NAME: ${{ env.CONTEXT_NAME }}
ACTIONS_RUN_LOG: ${{ env.ACTIONS_RUN_LOG }}
HEAD_SHA: ${{ needs.pr-metadata.outputs.head_sha }}
run: .github/actions-scripts/staging-commit-status-success.js
- name: Mark the deployment as inactive if timed out
uses: actions/github-script@2b34a689ec86a68d8ab9478298f91d5401337b7d
if: ${{ steps.deploy.outcome == 'cancelled' }}
env:
DEPLOYMENT_ID: ${{ steps.deploy.outputs.deploymentId }}
LOG_URL: ${{ steps.deploy.outputs.logUrl }}
with:
script: |
const { DEPLOYMENT_ID, LOG_URL } = process.env
const { owner, repo } = context.repo
if (!DEPLOYMENT_ID) {
throw new Error('A deployment wasn't created before a timeout occurred!')
}
await github.repos.createDeploymentStatus({
owner,
repo,
deployment_id: DEPLOYMENT_ID,
state: 'error',
description: 'The deployment step timed out. See workflow logs.',
log_url: LOG_URL,
// The 'ant-man' preview is required for `state` values of 'inactive', as well as
// the use of the `log_url`, `environment_url`, and `auto_inactive` parameters.
// The 'flash' preview is required for `state` values of 'in_progress' and 'queued'.
mediaType: {
previews: ['ant-man', 'flash'],
},
})
console.log('⏲️ Deployment status: error - The deployment timed out...')
- name: Create failure status
uses: actions/github-script@2b34a689ec86a68d8ab9478298f91d5401337b7d
if: ${{ failure() }}
env:
CONTEXT_NAME: ${{ env.CONTEXT_NAME }}
ACTIONS_RUN_LOG: ${{ env.ACTIONS_RUN_LOG }}
HEAD_SHA: ${{ needs.pr-metadata.outputs.head_sha }}
with:
script: |
const { CONTEXT_NAME, ACTIONS_RUN_LOG, HEAD_SHA } = process.env
const { owner, repo } = context.repo
await github.repos.createCommitStatus({
owner,
repo,
sha: HEAD_SHA,
context: CONTEXT_NAME,
state: 'error',
description: 'Failed to deploy. See logs.',
target_url: ACTIONS_RUN_LOG
})
- name: Send Slack notification if deployment job failed
uses: someimportantcompany/github-actions-slack-message@f8d28715e7b8a4717047d23f48c39827cacad340
if: ${{ failure() }}
with:
channel: ${{ secrets.DOCS_STAGING_DEPLOYMENT_FAILURES_SLACK_CHANNEL_ID }}
bot-token: ${{ secrets.SLACK_DOCS_BOT_TOKEN }}
color: failure
text: Staging deployment failed for PR ${{ needs.pr-metadata.outputs.url }} at commit ${{ needs.pr-metadata.outputs.head_sha }}. See ${{ env.ACTIONS_RUN_LOG }}.

View File

@@ -1,76 +0,0 @@
# NOTE: Changes to this file should also be applied to './test.yml'
name: Node.js Tests - Windows
# **What it does**: This runs our tests on Windows.
# **Why we have it**: We want to support Windows contributors to docs.
# **Who does it impact**: Anyone working on docs on a Windows device.
on:
workflow_dispatch:
pull_request:
schedule:
- cron: '50 19 * * *' # once a day at 19:50 UTC / 11:50 PST
permissions:
contents: read
# This allows a subsequently queued workflow run to interrupt previous runs
concurrency:
group: '${{ github.workflow }} @ ${{ github.event.pull_request.head.label || github.head_ref || github.ref }}'
cancel-in-progress: true
jobs:
test:
runs-on: windows-latest
if: (github.event_name != 'pull_request') || (github.event_name == 'pull_request' && (contains(github.event.pull_request.labels.*.name, 'Windows') || contains(github.event.pull_request.labels.*.name, 'windows')))
timeout-minutes: 60
strategy:
fail-fast: false
matrix:
test-group:
[
content,
graphql,
meta,
rendering,
routing,
unit,
linting,
translations,
]
steps:
- name: Check out repo
uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
with:
# Enables cloning the Early Access repo later with the relevant PAT
persist-credentials: 'false'
- name: Setup node
uses: actions/setup-node@1f8c6b94b26d0feae1e387ca63ccbdc44d27b561
with:
node-version: 16.13.x
cache: npm
- name: Install dependencies
run: npm ci
- name: Cache nextjs build
uses: actions/cache@937d24475381cd9c75ae6db12cb4e79714b926ed
with:
path: .next/cache
key: ${{ runner.os }}-nextjs-${{ hashFiles('package*.json') }}
- if: ${{ github.repository == 'github/docs-internal' }}
name: Clone early access
run: npm run heroku-postbuild
env:
DOCUBOT_REPO_PAT: ${{ secrets.DOCUBOT_REPO_PAT }}
GIT_BRANCH: ${{ github.head_ref || github.ref }}
- if: ${{ github.repository != 'github/docs-internal' }}
name: Run build script
run: npm run build
- name: Run tests
run: npm test -- tests/${{ matrix.test-group }}/

View File

@@ -1,5 +1,3 @@
# NOTE: Changes to this file should also be applied to './test-windows.yml'
name: Node.js Tests
# **What it does**: Runs our tests.
@@ -51,6 +49,53 @@ jobs:
# Enables cloning the Early Access repo later with the relevant PAT
persist-credentials: 'false'
- name: Figure out which docs-early-access branch to checkout, if internal repo
if: ${{ github.repository == 'github/docs-internal' }}
id: check-early-access
uses: actions/github-script@2b34a689ec86a68d8ab9478298f91d5401337b7d
env:
BRANCH_NAME: ${{ github.head_ref || github.ref_name }}
with:
github-token: ${{ secrets.DOCUBOT_REPO_PAT }}
result-encoding: string
script: |
// If being run from a PR, this becomes 'my-cool-branch'.
// If run on main, with the `workflow_dispatch` action for
// example, the value becomes 'main'.
const { BRANCH_NAME } = process.env
try {
const response = await github.repos.getBranch({
owner: 'github',
repo: 'docs-early-access',
BRANCH_NAME,
})
console.log(`Using docs-early-access branch called '${BRANCH_NAME}'.`)
return BRANCH_NAME
} catch (err) {
if (err.status === 404) {
console.log(`There is no docs-early-access branch called '${BRANCH_NAME}' so checking out 'main' instead.`)
return 'main'
}
throw err
}
- name: Check out docs-early-access too, if internal repo
if: ${{ github.repository == 'github/docs-internal' }}
uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
with:
repository: github/docs-early-access
token: ${{ secrets.DOCUBOT_REPO_PAT }}
path: docs-early-access
ref: ${{ steps.check-early-access.outputs.result }}
- name: Merge docs-early-access repo's folders
if: ${{ github.repository == 'github/docs-internal' }}
run: |
mv docs-early-access/assets assets/images/early-access
mv docs-early-access/content content/early-access
mv docs-early-access/data data/early-access
rm -r docs-early-access
- name: Checkout LFS objects
run: git lfs checkout
@@ -78,13 +123,6 @@ jobs:
- name: Install dependencies
run: npm ci
- name: Clone early access
if: ${{ github.repository == 'github/docs-internal' }}
run: script/early-access/clone-for-build.js
env:
DOCUBOT_REPO_PAT: ${{ secrets.DOCUBOT_REPO_PAT }}
GIT_BRANCH: ${{ github.head_ref || github.ref }}
- name: Cache nextjs build
uses: actions/cache@937d24475381cd9c75ae6db12cb4e79714b926ed
with:

View File

@@ -10,7 +10,6 @@ on:
- '.github/actions-scripts/**'
- '.github/workflows/**'
- '.github/CODEOWNERS'
- 'app.json'
- 'assets/fonts/**'
- 'data/graphql/**'
- 'Dockerfile*'
@@ -20,7 +19,6 @@ on:
- 'lib/webhooks/**'
- 'lib/search/indexes/**'
- 'package*.json'
- 'Procfile'
- 'script/**'
- 'translations/**'
@@ -58,7 +56,6 @@ jobs:
- '.github/actions-scripts/**'
- '.github/workflows/**'
- '.github/CODEOWNERS'
- 'app.json'
- 'assets/fonts/**'
- 'data/graphql/**'
- 'Dockerfile*'
@@ -68,7 +65,6 @@ jobs:
- 'lib/webhooks/**'
- 'lib/search/indexes/**'
- 'package*.json'
- 'Procfile'
- 'scripts/**'
- 'translations/**'
@@ -83,7 +79,6 @@ jobs:
'.github/actions-scripts/**',
'.github/workflows/**',
'.github/CODEOWNERS',
'app.json',
'assets/fonts/**',
'data/graphql/**',
'Dockerfile*',
@@ -93,7 +88,6 @@ jobs:
'lib/webhooks/**',
'lib/search/indexes/**',
'package*.json',
'Procfile',
'scripts/**',
'translations/**',
]
@@ -111,7 +105,7 @@ jobs:
body: reviewMessage,
})
workflowFailMessage = `${workflowFailMessage} Please see ${createdComment.data.html_url} for details.`
workflowFailMessage = `${workflowFailMessage} Please see ${createdComment.data.html_url} for details.`
} catch(err) {
console.log("Error creating comment.", err)
}

View File

@@ -1,7 +1,7 @@
name: Check for unallowed internal changes
# **What it does**: If someone changes app.json or search indexes, we fail the check.
# **Why we have it**: app.json should rarely be edited, so we'll require an admin merge if the file really needs to be changed. The search indexes are synced every 4 hours, so changes should not need to be made.
# **What it does**: If someone changes search indexes, we fail the check.
# **Why we have it**: The search indexes are synced every 4 hours, so changes should not need to be made.
# **Who does it impact**: Docs engineering and content writers.
on:
@@ -44,19 +44,8 @@ jobs:
# Returns list of changed files matching each filter
filters: |
notAllowed:
- 'app.json'
notAllowedSearchSyncLabel:
- 'lib/search/indexes/**'
notAllowed:
needs: check-internal-changes
if: ${{ needs.check-internal-changes.outputs.notAllowed == 'true' }}
runs-on: ubuntu-latest
steps:
- name: Fail if unallowed changes were made
run: |
echo "Please admin merge if you really need to update app.json!"
exit 1
notAllowedSearchSyncLabel:
needs: check-internal-changes
if: ${{ needs.check-internal-changes.outputs.notAllowedSearchSyncLabel == 'true' }}

6
.gitignore vendored
View File

@@ -16,4 +16,8 @@ coverage/
blc_output.log
blc_output_internal.log
broken_links.md
lib/redirects/.redirects-cache_*.json
lib/redirects/.redirects-cache.json
# During the preview deploy untrusted user code may be cloned into this directory
# We ignore it from git to keep things deterministic
user-code/

View File

@@ -1,6 +1,4 @@
# This Dockerfile can be used for docker-based deployments to platforms
# like Now or Moda, but it is currently _not_ used by our Heroku deployments
# It uses two multi-stage builds: `install` and the main build to keep the image size down.
# This Dockerfile is used for docker-based deployments to Azure for both preview environments and production
# --------------------------------------------------------------------------------
# BASE IMAGE
@@ -23,7 +21,7 @@ FROM base as all_deps
COPY --chown=node:node package.json package-lock.json ./
RUN npm ci --no-optional
RUN npm ci --no-optional --registry https://registry.npmjs.org/
# For Next.js v12+
# This the appropriate necessary extra for node:16-alpine

View File

@@ -1 +0,0 @@
web: NODE_ENV=production node server.mjs

View File

@@ -60,4 +60,4 @@ When using the GitHub logos, be sure to follow the [GitHub logo guidelines](http
## Thanks :purple_heart:
Thanks for all your contributions and efforts towards improving the GitHub documentation. We thank you being part of our :sparkles: community :sparkles: !
Thanks for all your contributions and efforts towards improving the GitHub documentation. We thank you being part of our :sparkles: community :sparkles:!

View File

@@ -1,17 +0,0 @@
{
"name": "docs.github.com",
"env": {
"NODE_ENV": "production",
"ENABLED_LANGUAGES": "en",
"WEB_CONCURRENCY": "1"
},
"buildpacks": [
{ "url": "heroku/nodejs" }
],
"formation": {
"web": {
"quantity": 1,
"size": "standard-2x"
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 120 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 146 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 134 KiB

After

Width:  |  Height:  |  Size: 488 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

After

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 63 KiB

After

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 149 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 69 KiB

After

Width:  |  Height:  |  Size: 98 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 51 KiB

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 96 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 72 KiB

After

Width:  |  Height:  |  Size: 140 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.1 KiB

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 KiB

After

Width:  |  Height:  |  Size: 208 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.9 KiB

After

Width:  |  Height:  |  Size: 26 KiB

View File

@@ -2,109 +2,170 @@
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"appName": {
"type": "String"
},
"location": {
"type": "String"
},
"linuxFxVersion": {
"type": "String"
},
"dockerRegistryUrl": {
"type": "String"
},
"dockerRegistryUsername": {
"type": "String"
},
"dockerRegistryPassword": {
"type": "SecureString"
"appName": {
"defaultValue": null,
"type": "string",
"minLength": 5,
"maxLength": 63,
"metadata": {
"description": "A unique name for the app"
}
},
"variables": {
"appServicePlanName": "[concat('ASP-', parameters('appName'))]",
"dnsName": "[concat(parameters('appName'), '-', take(uniqueString(subscription().subscriptionId, resourceGroup().id, deployment().name), 6))]"
},
"location": {
"type": "String"
},
"containerImage": {
"type": "string",
"defaultValue": null,
"metadata": {
"description": "Container image to deploy"
}
},
"dockerRegistryUrl": {
"type": "String",
"metadata": {
"description": "Should be a valid host name without protocol"
}
},
"dockerRegistryUsername": {
"type": "String"
},
"dockerRegistryPassword": {
"type": "SecureString"
},
"storageAccountName": {
"type": "String"
},
"storageAccountKey": {
"type": "SecureString"
}
},
"resources": [
{
"type": "Microsoft.Web/serverfarms",
"apiVersion": "2021-02-01",
"name": "[variables('appServicePlanName')]",
"location": "[parameters('location')]",
"sku": {
"name": "B2"
{
"type": "Microsoft.ContainerInstance/containerGroups",
"name": "[parameters('appName')]",
"apiVersion": "2021-07-01",
"location": "[resourceGroup().location]",
"properties": {
"containers": [
{
"name": "app",
"properties": {
"image": "[parameters('containerImage')]",
"ports": [
{
"protocol": "TCP",
"port": 4000
}
],
"environmentVariables": [
{
"name": "PORT",
"value": "4000"
},
{
"name": "NODE_ENV",
"value": "production"
},
{
"name": "WEB_CONCURRENCY",
"value": "1"
},
{
"name": "ENABLED_LANGUAGES",
"value": "en"
}
],
"resources": {
"requests": {
"memoryInGB": 4,
"cpu": 1
}
}
}
},
"kind": "linux",
"properties": {
"reserved": true
}
},
{
"type": "Microsoft.Web/sites",
"apiVersion": "2018-11-01",
"name": "[variables('dnsName')]",
"location": "[parameters('location')]",
"dependsOn": [
"[resourceId('Microsoft.Web/serverfarms', variables('appServicePlanName'))]"
],
"tags": {
"DocsAppName": "[parameters('appName')]"
},
"properties": {
"name": "[variables('dnsName')]",
"siteConfig": {
"appSettings": [
{
"name": "DOCKER_REGISTRY_SERVER_URL",
"value": "[parameters('dockerRegistryUrl')]"
},
{
"name": "DOCKER_REGISTRY_SERVER_USERNAME",
"value": "[parameters('dockerRegistryUsername')]"
},
{
"name": "DOCKER_REGISTRY_SERVER_PASSWORD",
"value": "[parameters('dockerRegistryPassword')]"
},
{
"name": "WEBSITES_ENABLE_APP_SERVICE_STORAGE",
"value": "false"
},
{
"name": "NODE_ENV",
"value": "production"
},
{
"name": "PORT",
"value": "4000"
},
{
"name": "DEPLOYMENT_ENV",
"value": "azure"
},
{
"name": "ENABLED_LANGUAGES",
"value": "en"
}
],
"linuxFxVersion": "[parameters('linuxFxVersion')]",
"appCommandLine": "",
"alwaysOn": false,
"numberOfWorkers": 1,
"healthCheckPath": "/healthz",
"httpLoggingEnabled": true,
"logsDirectorySizeLimit": 35
{
"name": "caddy-ssl-server",
"properties": {
"image": "caddy:2.4.6",
"command": [
"caddy",
"reverse-proxy",
"--from",
"[concat(parameters('appName'), '.', parameters('location'), '.azurecontainer.io')]",
"--to",
"localhost:4000"
],
"ports": [
{
"protocol": "TCP",
"port": 443
},
{
"protocol": "TCP",
"port": 80
}
],
"environmentVariables": [],
"resources": {
"requests": {
"memoryInGB": 1,
"cpu": 1
}
},
"serverFarmId": "[concat('/subscriptions/', subscription().id, '/resourcegroups/', resourceGroup().name, '/providers/Microsoft.Web/serverfarms/', variables('appServicePlanName'))]",
"clientAffinityEnabled": false
"volumeMounts": [
{
"name": "caddy-data",
"mountPath": "/data"
}
]
}
}
],
"volumes": [
{
"name": "caddy-data",
"azureFile": {
"shareName": "caddy",
"storageAccountName": "[parameters('storageAccountName')]",
"storageAccountKey": "[parameters('storageAccountKey')]"
}
}
],
"imageRegistryCredentials": [
{
"server": "[parameters('dockerRegistryUrl')]",
"username": "[parameters('dockerRegistryUsername')]",
"password": "[parameters('dockerRegistryPassword')]"
}
],
"restartPolicy": "Always",
"ipAddress": {
"ports": [
{
"protocol": "TCP",
"port": 443
},
{
"protocol": "TCP",
"port": 4000
},
{
"protocol": "TCP",
"port": 80
}
],
"type": "Public",
"dnsNameLabel": "[parameters('appName')]"
},
"osType": "Linux"
}
}
],
"outputs": {
"defaultHostName": {
"type": "string",
"value": "[concat('https://', variables('dnsName'), '.azurewebsites.net')]"
}
"defaultHostName": {
"value": "[reference(resourceId('Microsoft.ContainerInstance/containerGroups', parameters('appName'))).ipAddress.fqdn]",
"type": "string"
}
}
}

View File

@@ -132,9 +132,9 @@ export function Search({
if (router.pathname === '/') {
// Don't include router.locale so next doesn't attempt a
// request to `/_next/static/chunks/pages/en.js`
router.replace(`/?${params.toString()}`, asPath)
router.replace(`/?${params.toString()}`, asPath, { shallow: true })
} else {
router.replace(asPath)
router.replace(asPath, undefined, { shallow: true })
}
}
}, [debouncedQuery])

View File

@@ -27,7 +27,7 @@ export const PlaygroundArticle = () => {
{article.prerequisites && (
<div className="mt-4 d-flex">
<div className="pr-3 mt-1">
<Circle className="color-bg-accent-emphasis">
<Circle className="color-fg-on-emphasis color-bg-emphasis">
<CheckIcon className="" size={15} />
</Circle>
</div>
@@ -44,7 +44,7 @@ export const PlaygroundArticle = () => {
{/* toc */}
<div className="mt-4 d-flex">
<div className="pr-3 mt-1">
<Circle className="color-bg-accent-emphasis">
<Circle className="color-fg-on-emphasis color-bg-emphasis">
<SearchIcon className="" size={15} />
</Circle>
</div>

View File

@@ -37,7 +37,7 @@ If you're a member of an {% data variables.product.prodname_emu_enterprise %}, y
1. Ask for the username of the person you're inviting as a collaborator.{% ifversion fpt or ghec %} If they don't have a username yet, they can sign up for {% data variables.product.prodname_dotcom %} For more information, see "[Signing up for a new {% data variables.product.prodname_dotcom %} account](/articles/signing-up-for-a-new-github-account)".{% endif %}
{% data reusables.repositories.navigate-to-repo %}
{% data reusables.repositories.sidebar-settings %}
{% ifversion fpt or ghec or ghes > 3.3 or ghae-issue-5658%}
{% ifversion fpt or ghec or ghes > 3.4 or ghae-issue-5658%}
{% data reusables.repositories.click-collaborators-teams %}
1. Click **Invite a collaborator**.
!["Invite a collaborator" button](/assets/images/help/repository/invite-a-collaborator-button.png)

View File

@@ -29,7 +29,7 @@ While forks of private repositories are deleted when a collaborator is removed,
{% data reusables.repositories.navigate-to-repo %}
{% data reusables.repositories.sidebar-settings %}
{% ifversion fpt or ghec or ghes > 3.3 or ghae-issue-5658 %}
{% ifversion fpt or ghec or ghes > 3.4 or ghae-issue-5658 %}
{% data reusables.repositories.click-collaborators-teams %}
4. To the right of the collaborator you want to remove, click {% octicon "trash" aria-label="The trash icon" %}.
![Button to remove collaborator](/assets/images/help/repository/collaborator-remove.png)

View File

@@ -20,7 +20,7 @@ topics:
shortTitle: Remove yourself
---
{% data reusables.user_settings.access_settings %}
{% ifversion fpt or ghec or ghes > 3.3 or ghae-issue-5658 %}
{% ifversion fpt or ghec or ghes > 3.4 or ghae-issue-5658 %}
2. In the "Code, planning, and automation" section of the sidebar, click **{% octicon "repo" aria-label="The repo icon" %} Repositories**.
{% else %}
2. In the left sidebar, click **Repositories**.

View File

@@ -22,7 +22,7 @@ You may want to use a dark theme to reduce power consumption on certain devices,
{% note %}
**Note:** The colorblind themes and light high contrast theme are currently in public beta. For more information on enabling features in public beta, see "[Exploring early access releases with feature preview](/get-started/using-github/exploring-early-access-releases-with-feature-preview)."
**Note:** The colorblind themes are currently in public beta. For more information on enabling features in public beta, see "[Exploring early access releases with feature preview](/get-started/using-github/exploring-early-access-releases-with-feature-preview)."
{% endnote %}

View File

@@ -69,7 +69,7 @@ jobs:
- name: Validate Gradle wrapper
uses: gradle/wrapper-validation-action@e6e38bacfdf1a337459f332974bb2327a31aaf4b
- name: Build with Gradle
uses: gradle/gradle-build-action@4137be6a8bf7d7133955359dbd952c0ca73b1021
uses: gradle/gradle-build-action@937999e9cc2425eddc7fd62d1053baf041147db7
with:
arguments: build
```
@@ -106,7 +106,7 @@ steps:
- name: Validate Gradle wrapper
uses: gradle/wrapper-validation-action@e6e38bacfdf1a337459f332974bb2327a31aaf4b
- name: Run the Gradle package task
uses: gradle/gradle-build-action@4137be6a8bf7d7133955359dbd952c0ca73b1021
uses: gradle/gradle-build-action@937999e9cc2425eddc7fd62d1053baf041147db7
with:
arguments: -b ci.gradle package
```
@@ -135,7 +135,7 @@ steps:
- name: Validate Gradle wrapper
uses: gradle/wrapper-validation-action@e6e38bacfdf1a337459f332974bb2327a31aaf4b
- name: Build with Gradle
uses: gradle/gradle-build-action@4137be6a8bf7d7133955359dbd952c0ca73b1021
uses: gradle/gradle-build-action@937999e9cc2425eddc7fd62d1053baf041147db7
with:
arguments: build
- uses: actions/upload-artifact@v2

View File

@@ -54,9 +54,9 @@ jobs:
steps:
- uses: actions/checkout@v2
- name: Set up Ruby
uses: ruby/setup-ruby@477b21f02be01bcb8030d50f37cfec92bfa615b6
uses: ruby/setup-ruby@359bebbc29cbe6c87da6bc9ea3bc930432750108
with:
ruby-version: 2.6
ruby-version: '3.1'
- name: Install dependencies
run: bundle install
- name: Run tests
@@ -65,7 +65,7 @@ jobs:
## Specifying the Ruby version
The easiest way to specify a Ruby version is by using the `ruby/setup-ruby` action provided by the Ruby organization on GitHub. The action adds any supported Ruby version to `PATH` for each job run in a workflow. For more information see, the [`ruby/setup-ruby`](https://github.com/ruby/setup-ruby).
The easiest way to specify a Ruby version is by using the `ruby/setup-ruby` action provided by the Ruby organization on GitHub. The action adds any supported Ruby version to `PATH` for each job run in a workflow. For more information and available Ruby versions, see [`ruby/setup-ruby`](https://github.com/ruby/setup-ruby).
Using Ruby's `ruby/setup-ruby` action is the recommended way of using Ruby with GitHub Actions because it ensures consistent behavior across different runners and different versions of Ruby.
@@ -75,9 +75,9 @@ The `setup-ruby` action takes a Ruby version as an input and configures that ver
```yaml
steps:
- uses: actions/checkout@v2
- uses: ruby/setup-ruby@477b21f02be01bcb8030d50f37cfec92bfa615b6
- uses: ruby/setup-ruby@359bebbc29cbe6c87da6bc9ea3bc930432750108
with:
ruby-version: 2.6 # Not needed with a .ruby-version file
ruby-version: '3.1' # Not needed with a .ruby-version file
- run: bundle install
- run: bundle exec rake
```
@@ -87,13 +87,13 @@ Alternatively, you can check a `.ruby-version` file into the root of your repos
## Testing with multiple versions of Ruby
You can add a matrix strategy to run your workflow with more than one version of Ruby. For example, you can test your code against the latest patch releases of versions 2.7, 2.6, and 2.5. The 'x' is a wildcard character that matches the latest patch release available for a version.
You can add a matrix strategy to run your workflow with more than one version of Ruby. For example, you can test your code against the latest patch releases of versions 3.1, 3.0, and 2.7.
{% raw %}
```yaml
strategy:
matrix:
ruby-version: [2.7.x, 2.6.x, 2.5.x]
ruby-version: ['3.1', '3.0', '2.7']
```
{% endraw %}
@@ -119,12 +119,12 @@ jobs:
strategy:
matrix:
ruby-version: [2.7.x, 2.6.x, 2.5.x]
ruby-version: ['3.1', '3.0', '2.7']
steps:
- uses: actions/checkout@v2
- name: {% raw %}Set up Ruby ${{ matrix.ruby-version }}{% endraw %}
uses: ruby/setup-ruby@477b21f02be01bcb8030d50f37cfec92bfa615b6
uses: ruby/setup-ruby@359bebbc29cbe6c87da6bc9ea3bc930432750108
with:
ruby-version: {% raw %}${{ matrix.ruby-version }}{% endraw %}
- name: Install dependencies
@@ -141,9 +141,9 @@ The `setup-ruby` action will automatically install bundler for you. The version
```yaml
steps:
- uses: actions/checkout@v2
- uses: ruby/setup-ruby@477b21f02be01bcb8030d50f37cfec92bfa615b6
- uses: ruby/setup-ruby@359bebbc29cbe6c87da6bc9ea3bc930432750108
with:
ruby-version: 2.6
ruby-version: '3.1'
- run: bundle install
```
{% endraw %}
@@ -157,7 +157,7 @@ To enable caching, set the following.
{% raw %}
```yaml
steps:
- uses: ruby/setup-ruby@477b21f02be01bcb8030d50f37cfec92bfa615b6
- uses: ruby/setup-ruby@359bebbc29cbe6c87da6bc9ea3bc930432750108
with:
bundler-cache: true
```

View File

@@ -89,10 +89,14 @@ This procedure demonstrates how to create the service account for your GKE integ
{% raw %}
```
$ gcloud projects add-iam-policy-binding $GKE_PROJECT \
--member=serviceAccount:$SA_EMAIL \
--role=roles/container.admin \
--role=roles/storage.admin \
--role=roles/container.clusterViewer
--member=serviceAccount:$SA_EMAIL \
--role=roles/container.admin
$ gcloud projects add-iam-policy-binding $GKE_PROJECT \
--member=serviceAccount:$SA_EMAIL \
--role=roles/storage.admin
$ gcloud projects add-iam-policy-binding $GKE_PROJECT \
--member=serviceAccount:$SA_EMAIL \
--role=roles/container.clusterViewer
```
{% endraw %}
1. Download the JSON keyfile for the service account:

View File

@@ -37,19 +37,18 @@ For more information, see "[About self-hosted runners](/github/automating-your-w
You can add self-hosted runners to a single repository. To add a self-hosted runner to a user repository, you must be the repository owner. For an organization repository, you must be an organization owner or have admin access to the repository. For information about how to add a self-hosted runner with the REST API, see "[Self-hosted runners](/rest/reference/actions#self-hosted-runners)."
{% ifversion fpt or ghec %}
{% ifversion fpt or ghec or ghes > 3.3 or ghae-issue-5091 %}
{% data reusables.repositories.navigate-to-repo %}
{% data reusables.repositories.sidebar-settings %}
{% data reusables.github-actions.settings-sidebar-actions %}
{% data reusables.github-actions.settings-sidebar-actions-runners-updated %}
1. Click **New self-hosted runner**.
{% data reusables.github-actions.self-hosted-runner-configure %}
{% endif %}
{% ifversion ghae or ghes %}
{% elsif ghae or ghes < 3.4 %}
{% data reusables.repositories.navigate-to-repo %}
{% data reusables.repositories.sidebar-settings %}
{% data reusables.github-actions.settings-sidebar-actions-runners %}
1. Under {% ifversion fpt or ghes > 3.1 or ghae or ghec %}"Runners"{% else %}"Self-hosted runners"{% endif %}, click **Add runner**.
1. Under {% ifversion ghes > 3.1 or ghae or ghec %}"Runners"{% else %}"Self-hosted runners"{% endif %}, click **Add runner**.
{% data reusables.github-actions.self-hosted-runner-configure %}
{% endif %}
{% data reusables.github-actions.self-hosted-runner-check-installation-success %}
@@ -58,19 +57,18 @@ You can add self-hosted runners to a single repository. To add a self-hosted run
You can add self-hosted runners at the organization level, where they can be used to process jobs for multiple repositories in an organization. To add a self-hosted runner to an organization, you must be an organization owner. For information about how to add a self-hosted runner with the REST API, see "[Self-hosted runners](/rest/reference/actions#self-hosted-runners)."
{% ifversion fpt or ghec %}
{% ifversion fpt or ghec or ghes > 3.3 or ghae-issue-5091 %}
{% data reusables.organizations.navigate-to-org %}
{% data reusables.organizations.org_settings %}
{% data reusables.github-actions.settings-sidebar-actions %}
{% data reusables.github-actions.settings-sidebar-actions-runners-updated %}
1. Click **New runner**.
{% data reusables.github-actions.self-hosted-runner-configure %}
{% endif %}
{% ifversion ghae or ghes %}
{% elsif ghae or ghes < 3.4 %}
{% data reusables.organizations.navigate-to-org %}
{% data reusables.organizations.org_settings %}
{% data reusables.github-actions.settings-sidebar-actions-runners %}
1. Under {% ifversion fpt or ghes > 3.1 or ghae or ghec %}"Runners"{% else %}"Self-hosted runners"{% endif %}, click **Add runner**.
1. Under {% ifversion ghes > 3.1 or ghae %}"Runners", click **Add new**, then click **New runner**.{% elsif ghes < 3.2 %}"Self-hosted runners", click **Add runner**."{% endif %}
{% data reusables.github-actions.self-hosted-runner-configure %}
{% endif %}
@@ -86,7 +84,7 @@ You can add self-hosted runners at the organization level, where they can be use
New runners are assigned to the default group. You can modify the runner's group after you've registered the runner. For more information, see "[Managing access to self-hosted runners](/actions/hosting-your-own-runners/managing-access-to-self-hosted-runners-using-groups#moving-a-self-hosted-runner-to-a-group)."
{% ifversion ghec %}
{% ifversion ghec or ghes > 3.3 or ghae-issue-5091 %}
To add a self-hosted runner to an enterprise account, you must be an enterprise owner. For information about how to add a self-hosted runner with the REST API, see the [Enterprise Administration GitHub Actions APIs](/rest/reference/enterprise-admin#github-actions).
{% data reusables.enterprise-accounts.access-enterprise %}
@@ -95,8 +93,7 @@ To add a self-hosted runner to an enterprise account, you must be an enterprise
{% data reusables.enterprise-accounts.actions-runners-tab %}
1. Click **New runner**.
{% data reusables.github-actions.self-hosted-runner-configure %}
{% endif %}
{% ifversion ghae or ghes %}
{% elsif ghae or ghes < 3.4 %}
To add a self-hosted runner at the enterprise level of {% data variables.product.product_location %}, you must be a site administrator.
{% data reusables.enterprise-accounts.access-enterprise %}
{% data reusables.enterprise-accounts.policies-tab %}
@@ -105,11 +102,9 @@ To add a self-hosted runner at the enterprise level of {% data variables.product
1. Click **Add new**, then click **New runner**.
{% data reusables.github-actions.self-hosted-runner-configure %}
{% endif %}
{% ifversion ghec or ghae or ghes %}
{% data reusables.github-actions.self-hosted-runner-check-installation-success %}
{% data reusables.github-actions.self-hosted-runner-public-repo-access %}
{% endif %}
### Making enterprise runners available to repositories

View File

@@ -45,7 +45,7 @@ Self-hosted runners are automatically assigned to the default group when created
When creating a group, you must choose a policy that defines which repositories have access to the runner group.
{% ifversion ghec %}
{% ifversion ghec or ghes > 3.3 or ghae-issue-5091 %}
{% data reusables.organizations.navigate-to-org %}
{% data reusables.organizations.org_settings %}
{% data reusables.github-actions.settings-sidebar-actions-runner-groups %}
@@ -60,12 +60,11 @@ When creating a group, you must choose a policy that defines which repositories
{% endwarning %}
{% data reusables.github-actions.self-hosted-runner-create-group %}
{% endif %}
{% ifversion ghae or ghes %}
{% elsif ghae or ghes < 3.4 %}
{% data reusables.organizations.navigate-to-org %}
{% data reusables.organizations.org_settings %}
{% data reusables.github-actions.settings-sidebar-actions-runners %}
1. In the "Self-hosted runners" section, click **Add new**, and then **New group**.
1. Under {% ifversion ghes > 3.1 or ghae %}"Runners"{% elsif ghes < 3.2 %}"Self-hosted runners"{% endif %}, click **Add new**, and then **New group**.
![Add runner group](/assets/images/help/settings/actions-org-add-runner-group.png)
1. Enter a name for your runner group, and assign a policy for repository access.
@@ -94,7 +93,7 @@ Self-hosted runners are automatically assigned to the default group when created
When creating a group, you must choose a policy that defines which organizations have access to the runner group.
{% ifversion ghec %}
{% ifversion ghec or ghes > 3.3 or ghae-issue-5091 %}
{% data reusables.enterprise-accounts.access-enterprise %}
{% data reusables.enterprise-accounts.policies-tab %}
{% data reusables.enterprise-accounts.actions-tab %}
@@ -112,8 +111,7 @@ When creating a group, you must choose a policy that defines which organizations
{% endwarning %}
{% data reusables.github-actions.self-hosted-runner-create-group %}
{% endif %}
{% ifversion ghae or ghes %}
{% elsif ghae or ghes < 3.4 %}
{% data reusables.enterprise-accounts.access-enterprise %}
{% data reusables.enterprise-accounts.policies-tab %}
{% data reusables.enterprise-accounts.actions-tab %}
@@ -143,7 +141,7 @@ When creating a group, you must choose a policy that defines which organizations
## Changing the access policy of a self-hosted runner group
You can update the access policy of a runner group, or rename a runner group.
{% ifversion fpt or ghec %}
{% ifversion fpt or ghec or ghes > 3.3 or ghae-issue-5091 %}
{% data reusables.github-actions.self-hosted-runner-groups-navigate-to-repo-org-enterprise %}
{% data reusables.github-actions.settings-sidebar-actions-runner-groups-selection %}
1. Modify the access options, or change the runner group name.
@@ -157,8 +155,7 @@ You can update the access policy of a runner group, or rename a runner group.
For more information, see "[About self-hosted runners](/actions/hosting-your-own-runners/about-self-hosted-runners#self-hosted-runner-security-with-public-repositories)."
{% endwarning %}
{% endif %}
{% ifversion ghae or ghes %}
{% elsif ghae or ghes < 3.4 %}
{% data reusables.github-actions.self-hosted-runner-configure-runner-group-access %}
{% endif %}
@@ -180,20 +177,21 @@ Could not find any self-hosted runner group named "rg-runnergroup".
## Moving a self-hosted runner to a group
If you don't specify a runner group during the registration process, your new self-hosted runners are automatically assigned to the default group, and can then be moved to another group.
{% ifversion ghec or ghes > 3.1 or ghae %}
{% data reusables.github-actions.self-hosted-runner-navigate-to-org-enterprise %}
{% ifversion ghec or ghes > 3.3 or ghae-issue-5091 %}
1. In the "Runners" list, click the runner that you want to configure.
2. Select the Runner group dropdown menu.
3. In "Move runner to group", choose a destination group for the runner.
{% endif %}
{% ifversion ghes < 3.2 or ghae %}
1. In the "Self-hosted runners" section of the settings page, locate the current group of the runner you want to move and expand the list of group members.
{% elsif ghae or ghes < 3.4 %}
1. In the {% ifversion ghes > 3.1 or ghae %}"Runner groups"{% elsif ghes < 3.2 %}"Self-hosted runners"{% endif %} section of the settings page, locate the current group of the runner you want to move and expand the list of group members.
![View runner group members](/assets/images/help/settings/actions-org-runner-group-members.png)
2. Select the checkbox next to the self-hosted runner, and then click **Move to group** to see the available destinations.
![Runner group member move](/assets/images/help/settings/actions-org-runner-group-member-move.png)
3. To move the runner, click on the destination group.
![Runner group member move](/assets/images/help/settings/actions-org-runner-group-member-move-destination.png)
{% endif %}
## Removing a self-hosted runner group
Self-hosted runners are automatically returned to the default group when their group is removed.
@@ -203,8 +201,7 @@ Self-hosted runners are automatically returned to the default group when their g
1. In the list of groups, to the right of the group you want to delete, click {% octicon "kebab-horizontal" aria-label="The horizontal kebab icon" %}.
2. To remove the group, click **Remove group**.
3. Review the confirmation prompts, and click **Remove this runner group**.
{% endif %}
{% ifversion ghes < 3.2 or ghae %}
{% elsif ghes < 3.2 %}
1. In the "Self-hosted runners" section of the settings page, locate the group you want to delete, and click the {% octicon "kebab-horizontal" aria-label="The horizontal kebab icon" %} button.
![View runner group settings](/assets/images/help/settings/actions-org-runner-group-kebab.png)

View File

@@ -30,20 +30,20 @@ shortTitle: Remove self-hosted runners
To remove a self-hosted runner from a user repository you must be the repository owner. For an organization repository, you must be an organization owner or have admin access to the repository. We recommend that you also have access to the self-hosted runner machine. For information about how to remove a self-hosted runner with the REST API, see "[Self-hosted runners](/rest/reference/actions#self-hosted-runners)."
{% data reusables.github-actions.self-hosted-runner-reusing %}
{% ifversion fpt or ghec %}
{% ifversion fpt or ghec or ghes > 3.3 or ghae-issue-5091 %}
{% data reusables.repositories.navigate-to-repo %}
{% data reusables.repositories.sidebar-settings %}
{% data reusables.github-actions.settings-sidebar-actions %}
{% data reusables.github-actions.settings-sidebar-actions-runners-updated %}
{% data reusables.github-actions.settings-sidebar-actions-runner-selection %}
{% data reusables.github-actions.self-hosted-runner-removing-a-runner-updated %}
{% endif %}
{% ifversion ghae or ghes %}
{% elsif ghae or ghes < 3.4 %}
{% data reusables.repositories.navigate-to-repo %}
{% data reusables.repositories.sidebar-settings %}
{% data reusables.github-actions.settings-sidebar-actions-runners %}
{% data reusables.github-actions.self-hosted-runner-removing-a-runner %}
{% endif %}
## Removing a runner from an organization
{% note %}
@@ -57,19 +57,20 @@ To remove a self-hosted runner from a user repository you must be the repository
To remove a self-hosted runner from an organization, you must be an organization owner. We recommend that you also have access to the self-hosted runner machine. For information about how to remove a self-hosted runner with the REST API, see "[Self-hosted runners](/rest/reference/actions#self-hosted-runners)."
{% data reusables.github-actions.self-hosted-runner-reusing %}
{% ifversion fpt or ghes > 3.1 or ghae or ghec %}
{% ifversion fpt or ghes > 3.3 or ghec %}
{% data reusables.organizations.navigate-to-org %}
{% data reusables.organizations.org_settings %}
{% data reusables.github-actions.settings-sidebar-actions %}
{% data reusables.github-actions.settings-sidebar-actions-runners-updated %}
{% data reusables.github-actions.settings-sidebar-actions-runner-selection %}
{% data reusables.github-actions.self-hosted-runner-removing-a-runner-updated %}
{% else %}
{% elsif ghes < 3.4 or ghae %}
{% data reusables.organizations.navigate-to-org %}
{% data reusables.organizations.org_settings %}
{% data reusables.github-actions.settings-sidebar-actions-runners %}
{% data reusables.github-actions.self-hosted-runner-removing-a-runner %}
{% endif %}
## Removing a runner from an enterprise
{% ifversion fpt %}
@@ -84,18 +85,17 @@ If you use {% data variables.product.prodname_ghe_cloud %}, you can also remove
{% endnote %}
{% data reusables.github-actions.self-hosted-runner-reusing %}
To remove a self-hosted runner from an enterprise, you must be an enterprise owner. We recommend that you also have access to the self-hosted runner machine. For information about how to remove a self-hosted runner with the REST API, see the [Enterprise Administration GitHub Actions APIs](/rest/reference/enterprise-admin#github-actions).
{% ifversion ghec %}
To remove a self-hosted runner from an enterprise account, you must be an enterprise owner. We recommend that you also have access to the self-hosted runner machine. For information about how to add a self-hosted runner with the REST API, see the [Enterprise Administration GitHub Actions APIs](/rest/reference/enterprise-admin#github-actions).
{% data reusables.github-actions.self-hosted-runner-reusing %}
{% ifversion ghec or ghes > 3.3 or ghae-issue-5091 %}
{% data reusables.enterprise-accounts.access-enterprise %}
{% data reusables.enterprise-accounts.policies-tab %}
{% data reusables.enterprise-accounts.actions-tab %}
{% data reusables.enterprise-accounts.actions-runners-tab %}
{% data reusables.github-actions.settings-sidebar-actions-runner-selection %}
{% data reusables.github-actions.self-hosted-runner-removing-a-runner-updated %}
{% elsif ghae or ghes %}
To remove a self-hosted runner at the enterprise level of {% data variables.product.product_location %}, you must be an enterprise owner. We recommend that you also have access to the self-hosted runner machine.
{% elsif ghae or ghes < 3.4 %}
{% data reusables.enterprise-accounts.access-enterprise %}
{% data reusables.enterprise-accounts.policies-tab %}
{% data reusables.enterprise-accounts.actions-tab %}

View File

@@ -19,14 +19,14 @@ For information on how to use labels to route jobs to specific types of self-hos
{% data reusables.github-actions.self-hosted-runner-management-permissions-required %}
## Creating a custom label
{% ifversion fpt or ghec %}
{% ifversion fpt or ghec or ghes > 3.3 or ghae-issue-5091 %}
{% data reusables.github-actions.self-hosted-runner-navigate-to-repo-org-enterprise %}
{% data reusables.github-actions.settings-sidebar-actions-runner-selection %}
1. In the "Labels" section, click {% octicon "gear" aria-label="The Gear icon" %}.
1. In the "Find or create a label" field, type the name of your new label and click **Create new label**.
The custom label is created and assigned to the self-hosted runner. Custom labels can be removed from self-hosted runners, but they currently can't be manually deleted. {% data reusables.github-actions.actions-unused-labels %}
{% endif %}
{% ifversion ghae or ghes %}
{% elsif ghae or ghes < 3.4 %}
{% data reusables.github-actions.self-hosted-runner-navigate-to-repo-org-enterprise %}
{% data reusables.github-actions.self-hosted-runner-list %}
{% data reusables.github-actions.self-hosted-runner-list-group %}
@@ -36,34 +36,37 @@ For information on how to use labels to route jobs to specific types of self-hos
The custom label is created and assigned to the self-hosted runner. Custom labels can be removed from self-hosted runners, but they currently can't be manually deleted. {% data reusables.github-actions.actions-unused-labels %}
{% endif %}
## Assigning a label to a self-hosted runner
{% ifversion fpt or ghec %}
{% ifversion fpt or ghec or ghes > 3.3 or ghae-issue-5091 %}
{% data reusables.github-actions.self-hosted-runner-navigate-to-repo-org-enterprise %}
{% data reusables.github-actions.settings-sidebar-actions-runner-selection %}
{% data reusables.github-actions.runner-label-settings %}
1. To assign a label to your self-hosted runner, in the "Find or create a label" field, click the label.
{% endif %}
{% ifversion ghae or ghes %}
{% elsif ghae or ghes < 3.4 %}
{% data reusables.github-actions.self-hosted-runner-navigate-to-repo-org-enterprise %}
{% data reusables.github-actions.self-hosted-runner-list %}
{% data reusables.github-actions.self-hosted-runner-list-group %}
{% data reusables.github-actions.self-hosted-runner-labels-view-assigned-labels %}
1. Click on a label to assign it to your self-hosted runner.
{% endif %}
## Removing a custom label from a self-hosted runner
{% ifversion fpt or ghec %}
{% ifversion fpt or ghec or ghes > 3.3 or ghae-issue-5091 %}
{% data reusables.github-actions.self-hosted-runner-navigate-to-repo-org-enterprise %}
{% data reusables.github-actions.settings-sidebar-actions-runner-selection %}
{% data reusables.github-actions.runner-label-settings %}
1. In the "Find or create a label" field, assigned labels are marked with the {% octicon "check" aria-label="The Check icon" %} icon. Click on a marked label to unassign it from your self-hosted runner.
{% endif %}
{% ifversion ghae or ghes %}
{% elsif ghae or ghes < 3.4 %}
{% data reusables.github-actions.self-hosted-runner-navigate-to-repo-org-enterprise %}
{% data reusables.github-actions.self-hosted-runner-list %}
{% data reusables.github-actions.self-hosted-runner-list-group %}
{% data reusables.github-actions.self-hosted-runner-labels-view-assigned-labels %}
1. Click on the assigned label to remove it from your self-hosted runner. {% data reusables.github-actions.actions-unused-labels %}
{% endif %}
## Using the configuration script to create and assign labels
You can use the configuration script on the self-hosted runner to create and assign custom labels. For example, this command assigns a label named `gpu` to the self-hosted runner.

View File

@@ -76,7 +76,7 @@ The following table indicates where each context and special function can be use
| <code>concurrency</code> | <code>github, inputs</code> | |
| <code>env</code> | <code>github, secrets, inputs</code> | |
| <code>jobs.&lt;job_id&gt;.concurrency</code> | <code>github, needs, strategy, matrix, inputs</code> | |
| <code>jobs.&lt;job_id&gt;.container</code> | <code>github, needs, strategy, matrix, inputs</code> | |
| <code>jobs.&lt;job_id&gt;.container</code> | <code>github, needs, strategy, matrix, secrets, inputs</code> | |
| <code>jobs.&lt;job_id&gt;.container.credentials</code> | <code>github, needs, strategy, matrix, env, secrets, inputs</code> | |
| <code>jobs.&lt;job_id&gt;.container.env.&lt;env_id&gt;</code> | <code>github, needs, strategy, matrix, job, runner, env, secrets, inputs</code> | |
| <code>jobs.&lt;job_id&gt;.continue-on-error</code> | <code>github, needs, strategy, matrix, inputs</code> | |

View File

@@ -55,7 +55,7 @@ As part of an expression, you can use `boolean`, `null`, `number`, or `string` d
| `boolean` | `true` or `false` |
| `null` | `null` |
| `number` | Any number format supported by JSON. |
| `string` | You don't need to enclose strings in {% raw %}${{{% endraw %} and {% raw %}}}{% endraw %}. However, if you do, you must use single quotes around the string and escape literal single quotes with an additional single quote. |
| `string` | You don't need to enclose strings in `{% raw %}${{{% endraw %}` and `{% raw %}}}{% endraw %}`. However, if you do, you must use single quotes (`'`) around the string. To use a literal single quote, escape the literal single quote using an additional single quote (`''`). Wrapping with double quotes (`"`) will throw an error. |
#### Example

View File

@@ -96,7 +96,7 @@ jobs:
- name: Validate Gradle wrapper
uses: gradle/wrapper-validation-action@e6e38bacfdf1a337459f332974bb2327a31aaf4b
- name: Publish package
uses: gradle/gradle-build-action@4137be6a8bf7d7133955359dbd952c0ca73b1021
uses: gradle/gradle-build-action@937999e9cc2425eddc7fd62d1053baf041147db7
with:
arguments: publish
env:
@@ -167,7 +167,7 @@ jobs:
- name: Validate Gradle wrapper
uses: gradle/wrapper-validation-action@e6e38bacfdf1a337459f332974bb2327a31aaf4b
- name: Publish package
uses: gradle/gradle-build-action@4137be6a8bf7d7133955359dbd952c0ca73b1021
uses: gradle/gradle-build-action@937999e9cc2425eddc7fd62d1053baf041147db7
with:
arguments: publish
env:
@@ -246,7 +246,7 @@ jobs:
- name: Validate Gradle wrapper
uses: gradle/wrapper-validation-action@e6e38bacfdf1a337459f332974bb2327a31aaf4b
- name: Publish package
uses: gradle/gradle-build-action@4137be6a8bf7d7133955359dbd952c0ca73b1021
uses: gradle/gradle-build-action@937999e9cc2425eddc7fd62d1053baf041147db7
with:
arguments: publish
env: {% raw %}

View File

@@ -85,8 +85,8 @@ The following table shows the permissions granted to the `GITHUB_TOKEN` by defau
| actions | read/write | none | read |
| checks | read/write | none | read |
| contents | read/write | read | read |
| deployments | read/write | none | read |
| id-token | read/write | none | read |
| deployments | read/write | none | read |{% ifversion fpt or ghec %}
| id-token | read/write | none | read |{% endif %}
| issues | read/write | none | read |
| metadata | read | read | read |
| packages | read/write | none | read |

View File

@@ -202,6 +202,10 @@ The same principles described above for using third-party actions also apply to
{% data reusables.actions.outside-collaborators-internal-actions %} For more information, see "[Sharing actions and workflows with your enterprise](/actions/creating-actions/sharing-actions-and-workflows-with-your-enterprise)."
{% endif %}
## Using OpenSSF Scorecards to secure workflows
[Scorecards](https://github.com/ossf/scorecard) is an automated security tool that flags risky supply chain practices. You can use the [Scorecards action](https://github.com/marketplace/actions/ossf-scorecard-action) and [starter workflow](https://github.com/actions/starter-workflows) to follow best security practices. Once configured, the Scorecards action runs automatically on repository changes, and alerts developers about risky supply chain practices using the built-in code scanning experience. The Scorecards project runs a number of checks, including script injection attacks, token permissions, and pinned actions.
## Potential impact of a compromised runner
These sections consider some of the steps an attacker can take if they're able to run malicious commands on a {% data variables.product.prodname_actions %} runner.

View File

@@ -917,8 +917,6 @@ on:
```yaml
on:
push:
types:
- opened
branches:
- 'releases/**'
paths:
@@ -960,8 +958,6 @@ on:
```yaml
on:
push:
types:
- opened
branches:
- 'releases/**'
paths:
@@ -998,7 +994,7 @@ on:
| Webhook event payload | Activity types | `GITHUB_SHA` | `GITHUB_REF` |
| --------------------- | -------------- | ------------ | -------------|
| [`release`](/developers/webhooks-and-events/webhooks/webhook-events-and-payloads/#release) | - `published` <br/>- `unpublished` <br/>- `created` <br/>- `edited` <br/>- `deleted` <br/>- `prereleased`<br/> - `released` | Last commit in the tagged release | Tag of release |
| [`release`](/developers/webhooks-and-events/webhooks/webhook-events-and-payloads/#release) | - `published` <br/>- `unpublished` <br/>- `created` <br/>- `edited` <br/>- `deleted` <br/>- `prereleased`<br/> - `released` | Last commit in the tagged release | Tag ref of release `refs/tags/<tag_name>` |
{% note %}

View File

@@ -313,7 +313,9 @@ During the execution of a workflow, the runner generates temporary files that ca
{% warning %}
**Warning:** On Windows, legacy PowerShell (`shell: powershell`) does not use UTF-8 by default. Make sure you write files using the correct encoding. For example, you need to set UTF-8 encoding when you set the path:
**Warning:** On Windows, legacy PowerShell (`shell: powershell`) does not use UTF-8 by default.
When using `shell: powershell`, you must specify UTF-8 encoding. For example:
```yaml
jobs:
@@ -324,21 +326,7 @@ jobs:
run: echo "mypath" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
```
Or switch to PowerShell Core, which defaults to UTF-8:
```yaml
jobs:
modern-pwsh-example:
uses: windows-2019
steps:
- shell: pwsh
run: echo "mypath" | Out-File -FilePath $env:GITHUB_PATH -Append # no need for -Encoding utf8
```
More detail about UTF-8 and PowerShell Core found on this great [Stack Overflow answer](https://stackoverflow.com/a/40098904/162694):
> ### Optional reading: The cross-platform perspective: PowerShell _Core_:
> [PowerShell is now cross-platform](https://blogs.msdn.microsoft.com/powershell/2016/08/18/powershell-on-linux-and-open-source-2/), via its **[PowerShell _Core_](https://github.com/PowerShell/PowerShell)** edition, whose encoding - sensibly - **defaults to *BOM-less UTF-8***, in line with Unix-like platforms.
Alternatively, you can use PowerShell Core (`shell: pwsh`), which defaults to UTF-8.
{% endwarning %}

View File

@@ -757,6 +757,8 @@ strategy:
## `jobs.<job_id>.container`
{% data reusables.github-actions.docker-container-os-support %}
{% data reusables.actions.jobs.section-running-jobs-in-a-container %}
### `jobs.<job_id>.container.image`

View File

@@ -70,7 +70,22 @@ If you set up the {% data variables.product.prodname_codeql %} action sync tool,
3. The next step is to configure access to actions on {% data variables.product.prodname_dotcom_the_website %} using {% data variables.product.prodname_github_connect %}. For more information, see "[Enabling automatic access to {% data variables.product.prodname_dotcom_the_website %} actions using {% data variables.product.prodname_github_connect %}](/enterprise/admin/github-actions/enabling-automatic-access-to-githubcom-actions-using-github-connect)."
4. Add a self-hosted runner to your repository, organization, or enterprise account. For more information, see "[Adding self-hosted runners](/actions/hosting-your-own-runners/adding-self-hosted-runners)."
## Running code scanning using the {% data variables.product.prodname_codeql_cli %}
If you don't want to use {% data variables.product.prodname_actions %}, you should run {% data variables.product.prodname_code_scanning %} using the {% data variables.product.prodname_codeql_cli %}.
The {% data variables.product.prodname_codeql_cli %} is a command-line tool that you use to analyze codebases on any machine, including a third-party CI/CD system. For more information, see "[Installing CodeQL CLI in your CI system](/code-security/code-scanning/using-codeql-code-scanning-with-your-existing-ci-system/installing-codeql-cli-in-your-ci-system)."
{% if codeql-runner-supported %}
## Running {% data variables.product.prodname_code_scanning %} using the {% data variables.product.prodname_codeql_runner %}
{% data reusables.code-scanning.deprecation-codeql-runner %}
If you don't want to use {% data variables.product.prodname_actions %}, you can run {% data variables.product.prodname_code_scanning %} using the {% data variables.product.prodname_codeql_runner %}.
The {% data variables.product.prodname_codeql_runner %} is a command-line tool that you can add to your third-party CI/CD system. The tool runs {% data variables.product.prodname_codeql %} analysis on a checkout of a {% data variables.product.prodname_dotcom %} repository. For more information, see "[Running {% data variables.product.prodname_code_scanning %} in your CI system](/github/finding-security-vulnerabilities-and-errors-in-your-code/running-codeql-code-scanning-in-your-ci-system)."
{% endif %}

View File

@@ -458,6 +458,16 @@ You can use these additional options with the utility:
ghe-ssl-ca-certificate-install -c <em>/path/to/certificate</em>
```
### ghe-ssl-certificate-setup
This utility allows you to update an SSL certificate for {% data variables.product.product_location %}.
For more information about this command or for additional options, use the `-h` flag.
```shell
ghe-ssl-certificate-setup
```
### ghe-ssl-generate-csr
This utility allows you to generate a private key and certificate signing request (CSR), which you can share with a commercial or private certificate authority to get a valid certificate to use with your instance. For more information, see "[Configuring TLS](/enterprise/{{ currentVersion }}/admin/guides/installation/configuring-tls)."
@@ -699,7 +709,7 @@ All Storage tests passed
`ghe-migrator` is a hi-fidelity tool to help you migrate from one GitHub instance to another. You can consolidate your instances or move your organization, users, teams, and repositories from GitHub.com to {% data variables.product.prodname_enterprise %}.
For more information, please see our guide on [migrating user, organization, and repository data](/enterprise/admin/guides/migrations/).
For more information, please see our guides on [migrating data to and from your enterprise](/enterprise/admin/user-management/migrating-data-to-and-from-your-enterprise/).
### git-import-detect

View File

@@ -79,3 +79,7 @@ If your {% data variables.product.prodname_ghe_server %} appliance interacts wit
```shell
$ ghe-ssl-ca-certificate-install -c rootCA.crt
```
## Updating an SSL certificate
You can generate a new self-signed certificate or update an existing SSL certificate for {% data variables.product.product_location %} with the `ghe-ssl-certificate-setup` command line utility. For more information, see "[Command-line utilities](/admin/configuration/configuring-your-enterprise/command-line-utilities#ghe-ssl-ca-certificate-setup)."

View File

@@ -34,7 +34,7 @@ High Availability (HA) and Clustering both provide redundancy by eliminating the
## Backups and disaster recovery
Neither HA or Clustering should be considered a replacement for regular backups. For more information, see "[Configuring backups on your appliance](/enterprise/admin/guides/installation/configuring-backups-on-your-appliance)."
Neither HA nor Clustering should be considered a replacement for regular backups. For more information, see "[Configuring backups on your appliance](/enterprise/admin/guides/installation/configuring-backups-on-your-appliance)."
## Monitoring

View File

@@ -19,6 +19,8 @@ shortTitle: Add actions in your enterprise
{% data reusables.actions.enterprise-beta %}
{% data reusables.actions.enterprise-github-hosted-runners %}
## About actions on {% data variables.product.product_name %}
{% data variables.product.prodname_actions %} workflows can use _actions_, which are individual tasks that you can combine to create jobs and customize your workflow. You can create your own actions, or use and customize actions shared by the {% data variables.product.prodname_dotcom %} community.
{% data reusables.actions.enterprise-no-internet-actions %}
@@ -39,8 +41,14 @@ Each action is a repository in the `actions` organization, and each action repos
## Configuring access to actions on {% data variables.product.prodname_dotcom_the_website %}
{% ifversion ghes %}
Before you can configure access to actions on {% data variables.product.prodname_dotcom_the_website %}, you must configure {% data variables.product.product_location %} to use {% data variables.product.prodname_actions %}. For more information, see "[Getting started with {% data variables.product.prodname_actions %} for GitHub Enterprise Server](/admin/github-actions/enabling-github-actions-for-github-enterprise-server/getting-started-with-github-actions-for-github-enterprise-server)."
{% endif %}
{% data reusables.actions.access-actions-on-dotcom %}
The recommended approach is to enable automatic access to all actions from {% data variables.product.prodname_dotcom_the_website %}. You can do this by using {% data variables.product.prodname_github_connect %} to integrate {% data variables.product.product_name %} with {% data variables.product.prodname_ghe_cloud %}. For more information, see "[Enabling automatic access to {% data variables.product.prodname_dotcom_the_website %} actions using {% data variables.product.prodname_github_connect %}](/enterprise/admin/github-actions/enabling-automatic-access-to-githubcom-actions-using-github-connect)". {% data reusables.actions.enterprise-limit-actions-use %}
The recommended approach is to enable automatic access to all actions from {% data variables.product.prodname_dotcom_the_website %}. You can do this by using {% data variables.product.prodname_github_connect %} to integrate {% data variables.product.product_name %} with {% data variables.product.prodname_ghe_cloud %}. For more information, see "[Enabling automatic access to {% data variables.product.prodname_dotcom_the_website %} actions using {% data variables.product.prodname_github_connect %}](/enterprise/admin/github-actions/enabling-automatic-access-to-githubcom-actions-using-github-connect)".
{% data reusables.actions.enterprise-limit-actions-use %}
Alternatively, if you want stricter control over which actions are allowed in your enterprise, you can manually download and sync actions onto your enterprise instance using the `actions-sync` tool. For more information, see "[Manually syncing actions from {% data variables.product.prodname_dotcom_the_website %}](/enterprise/admin/github-actions/manually-syncing-actions-from-githubcom)."

View File

@@ -29,9 +29,11 @@ To use actions from {% data variables.product.prodname_dotcom_the_website %}, yo
## Enabling automatic access to all {% data variables.product.prodname_dotcom_the_website %} actions
{% data reusables.actions.enterprise-github-connect-warning %}
Before enabling access to all actions from {% data variables.product.prodname_dotcom_the_website %} for your enterprise, you must{% ifversion ghes %}:
- Configure {% data variables.product.product_location %} to use {% data variables.product.prodname_actions %}. For more information, see "[Getting started with {% data variables.product.prodname_actions %} for GitHub Enterprise Server](/admin/github-actions/enabling-github-actions-for-github-enterprise-server/getting-started-with-github-actions-for-github-enterprise-server)."
- Enable{% else %} enable{% endif %} {% data variables.product.prodname_github_connect %}. For more information, see "[Managing {% data variables.product.prodname_github_connect %}](/admin/configuration/configuring-github-connect/managing-github-connect)."
Before enabling access to all actions from {% data variables.product.prodname_dotcom_the_website %} on your enterprise instance, you must connect your enterprise to {% data variables.product.prodname_dotcom_the_website %}. For more information, see "[Connecting your enterprise to {% data variables.product.prodname_ghe_cloud %}](/admin/configuration/managing-connections-between-your-enterprise-accounts/connecting-your-enterprise-account-to-github-enterprise-cloud)."
{% data reusables.actions.enterprise-github-connect-warning %}
{% data reusables.enterprise-accounts.access-enterprise %}
{%- ifversion ghes < 3.1 %}

View File

@@ -46,7 +46,7 @@ IdP | SAML | Team synchronization |
--- | :--: | :-------: |
Active Directory Federation Services (AD FS) | {% octicon "check-circle-fill" aria-label= "The check icon" %} | |
Azure Active Directory (Azure AD) | {% octicon "check-circle-fill" aria-label="The check icon" %} | {% octicon "check-circle-fill" aria-label="The check icon" %} |
Okta | {% octicon "check-circle-fill" aria-label="The check icon" %} | {% octicon "check-circle-fill" aria-label="The check icon" %} |
Okta | {% octicon "check-circle-fill" aria-label="The check icon" %} | |
OneLogin | {% octicon "check-circle-fill" aria-label="The check icon" %} | |
PingOne | {% octicon "check-circle-fill" aria-label="The check icon" %} | |
Shibboleth | {% octicon "check-circle-fill" aria-label="The check icon" %} | |

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