Merge branch 'main' into patch-2
@@ -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
|
||||
|
||||
@@ -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": {
|
||||
|
||||
43
.devcontainer/library-scripts/github-debian.sh
Normal 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!"
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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 = ''
|
||||
|
||||
|
||||
30
.github/actions-scripts/get-preview-app-info.sh
vendored
@@ -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
|
||||
|
||||
51
.github/actions-scripts/prod-deploy.js
vendored
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
})
|
||||
55
.github/actions-scripts/staging-deploy.js
vendored
@@ -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,
|
||||
})
|
||||
97
.github/workflows/azure-preview-env-deploy.yml
vendored
@@ -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
|
||||
|
||||
16
.github/workflows/azure-preview-env-destroy.yml
vendored
@@ -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 }}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 }}
|
||||
|
||||
@@ -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
|
||||
|
||||
2
.github/workflows/optimize-images.yml
vendored
@@ -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 }}
|
||||
|
||||
31
.github/workflows/ping-staging-apps.yml
vendored
@@ -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
|
||||
16
.github/workflows/prod-build-deploy-azure.yml
vendored
@@ -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:
|
||||
|
||||
199
.github/workflows/prod-build-deploy.yml
vendored
@@ -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 }}
|
||||
8
.github/workflows/ready-for-doc-review.yml
vendored
@@ -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
|
||||
|
||||
@@ -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 }}
|
||||
210
.github/workflows/staging-build-and-deploy-pr.yml
vendored
@@ -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
|
||||
135
.github/workflows/staging-build-pr.yml
vendored
@@ -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
|
||||
466
.github/workflows/staging-deploy-pr.yml
vendored
@@ -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 }}.
|
||||
76
.github/workflows/test-windows.yml
vendored
@@ -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 }}/
|
||||
56
.github/workflows/test.yml
vendored
@@ -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:
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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
@@ -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/
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:!
|
||||
|
||||
17
app.json
@@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
assets/images/commonmark-lists.png
Normal file
|
After Width: | Height: | Size: 120 KiB |
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 146 KiB |
|
Before Width: | Height: | Size: 134 KiB After Width: | Height: | Size: 488 KiB |
|
After Width: | Height: | Size: 72 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 37 KiB |
|
Before Width: | Height: | Size: 47 KiB After Width: | Height: | Size: 94 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 49 KiB |
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 74 KiB |
|
Before Width: | Height: | Size: 47 KiB After Width: | Height: | Size: 93 KiB |
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 44 KiB |
|
Before Width: | Height: | Size: 63 KiB After Width: | Height: | Size: 118 KiB |
|
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 53 KiB |
BIN
assets/images/help/2fa/try-recovering-your-account-link.png
Normal file
|
After Width: | Height: | Size: 76 KiB |
BIN
assets/images/help/2fa/verify-email-address.png
Normal file
|
After Width: | Height: | Size: 46 KiB |
|
After Width: | Height: | Size: 149 KiB |
|
After Width: | Height: | Size: 98 KiB |
|
Before Width: | Height: | Size: 69 KiB After Width: | Height: | Size: 98 KiB |
|
Before Width: | Height: | Size: 35 KiB |
|
After Width: | Height: | Size: 37 KiB |
BIN
assets/images/help/graphs/dependabot-alerts-filters.png
Normal file
|
After Width: | Height: | Size: 29 KiB |
|
Before Width: | Height: | Size: 51 KiB After Width: | Height: | Size: 36 KiB |
|
After Width: | Height: | Size: 50 KiB |
|
After Width: | Height: | Size: 34 KiB |
|
Before Width: | Height: | Size: 96 KiB After Width: | Height: | Size: 30 KiB |
|
Before Width: | Height: | Size: 54 KiB |
BIN
assets/images/help/repository/headings_toc.png
Normal file
|
After Width: | Height: | Size: 54 KiB |
BIN
assets/images/help/repository/legacy-dependabot-alerts-view.png
Normal file
|
After Width: | Height: | Size: 95 KiB |
|
Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 140 KiB |
|
After Width: | Height: | Size: 60 KiB |
|
Before Width: | Height: | Size: 6.1 KiB After Width: | Height: | Size: 29 KiB |
|
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 47 KiB |
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 33 KiB |
|
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 30 KiB |
BIN
assets/images/help/writing/mermaid-flow-chart.png
Normal file
|
After Width: | Height: | Size: 46 KiB |
|
Before Width: | Height: | Size: 68 KiB After Width: | Height: | Size: 208 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 67 KiB |
|
Before Width: | Height: | Size: 9.9 KiB After Width: | Height: | Size: 26 KiB |
@@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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])
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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**.
|
||||

|
||||
|
||||
@@ -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" %}.
|
||||

|
||||
|
||||
@@ -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**.
|
||||
|
||||
@@ -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 %}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
```
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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**.
|
||||
|
||||

|
||||
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.
|
||||

|
||||
2. Select the checkbox next to the self-hosted runner, and then click **Move to group** to see the available destinations.
|
||||

|
||||
3. To move the runner, click on the destination group.
|
||||

|
||||
{% 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.
|
||||

|
||||
|
||||
|
||||
@@ -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 %}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.<job_id>.concurrency</code> | <code>github, needs, strategy, matrix, inputs</code> | |
|
||||
| <code>jobs.<job_id>.container</code> | <code>github, needs, strategy, matrix, inputs</code> | |
|
||||
| <code>jobs.<job_id>.container</code> | <code>github, needs, strategy, matrix, secrets, inputs</code> | |
|
||||
| <code>jobs.<job_id>.container.credentials</code> | <code>github, needs, strategy, matrix, env, secrets, inputs</code> | |
|
||||
| <code>jobs.<job_id>.container.env.<env_id></code> | <code>github, needs, strategy, matrix, job, runner, env, secrets, inputs</code> | |
|
||||
| <code>jobs.<job_id>.continue-on-error</code> | <code>github, needs, strategy, matrix, inputs</code> | |
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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 %}
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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 %}
|
||||
|
||||
|
||||
@@ -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 %}
|
||||
|
||||
|
||||
@@ -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`
|
||||
|
||||
@@ -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 %}
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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)."
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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)."
|
||||
|
||||
@@ -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 %}
|
||||
|
||||
@@ -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" %} | |
|
||||
|
||||