forked from github/docs
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add centralized staging build files for docs-staging-x deploys (#53586)
- Loading branch information
1 parent
3a792f8
commit fc769e1
Showing
18 changed files
with
1,004 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,164 @@ | ||
# **What it does**: Synchronizes each of the github/docs-staging-X repositories with the latest build scripts, workflows, and other files from src/deployments/staging. | ||
# **Why we have it**: We want to centralize build config in src/deployments/staging for use across multiple repos. | ||
# **Who does it impact**: Docs engineering, and potentially content writers. | ||
|
||
name: Sync Staging Repo Files | ||
|
||
on: | ||
push: | ||
branches: [main] | ||
paths: | ||
- 'src/deployments/staging/build-scripts/*.sh' | ||
- 'src/deployments/staging/.github/**' | ||
- 'src/deployments/staging/Dockerfile' | ||
- 'src/deployments/staging/.env.example' | ||
- 'src/deployments/staging/README.example.md' | ||
- 'src/deployments/staging/config/**' | ||
|
||
permissions: | ||
contents: write | ||
|
||
jobs: | ||
# Determine how many staging repos we have and generate a matrix with repo and index | ||
generate-matrix: | ||
if: github.repository == 'github/docs-internal' | ||
runs-on: ubuntu-latest | ||
outputs: | ||
matrix: ${{ steps.set-matrix.outputs.matrix }} | ||
steps: | ||
- name: Checkout source repository | ||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 | ||
with: | ||
fetch-depth: 1 # Only need latest commit for config.json | ||
|
||
- name: Read configuration | ||
id: read-config | ||
run: | | ||
sudo apt-get update && sudo apt-get install -y jq | ||
NUMBER_OF_REPOS=$(jq '.number_of_staging_repos' src/deployments/staging/config.json) | ||
if ! [[ "$NUMBER_OF_REPOS" =~ ^[0-9]+$ ]]; then | ||
echo "Invalid number_of_staging_repos in config.json: $NUMBER_OF_REPOS" | ||
exit 1 | ||
fi | ||
echo "number_of_repos=$NUMBER_OF_REPOS" >> $GITHUB_OUTPUT | ||
- name: Generate repository list with indices | ||
id: generate-repos | ||
run: | | ||
NUMBER_OF_REPOS=${{ steps.read-config.outputs.number_of_repos }} | ||
repos=() | ||
for i in $(seq 0 $NUMBER_OF_REPOS); do | ||
repos+=("{\"repo\": \"github/docs-staging-$i\", \"index\": $i}") | ||
done | ||
json_repos=$(printf '%s\n' "${repos[@]}" | jq -s .) | ||
echo "repos=$json_repos" >> $GITHUB_OUTPUT | ||
- name: Set matrix output with repo and index | ||
id: set-matrix | ||
run: | | ||
repos=${{ steps.generate-repos.outputs.repos }} | ||
echo "matrix={\"include\": $repos}" >> $GITHUB_OUTPUT | ||
- uses: ./.github/actions/slack-alert | ||
if: ${{ failure() && github.event_name != 'workflow_dispatch' }} | ||
with: | ||
slack_channel_id: ${{ secrets.DOCS_ALERTS_SLACK_CHANNEL_ID }} | ||
slack_token: ${{ secrets.SLACK_DOCS_BOT_TOKEN }} | ||
|
||
sync: | ||
if: github.repository == 'github/docs-internal' | ||
needs: generate-matrix | ||
runs-on: ubuntu-latest | ||
strategy: | ||
fail-fast: false | ||
matrix: ${{ fromJson(needs.generate-matrix.outputs.matrix) }} | ||
steps: | ||
- name: Checkout source repository | ||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 | ||
with: | ||
fetch-depth: 0 | ||
|
||
- name: Checkout target repository | ||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 | ||
with: | ||
repository: ${{ matrix.repo }} | ||
token: ${{ secrets.DOCS_BOT_PAT_READPUBLICKEY }} | ||
path: target_repo | ||
fetch-depth: 0 | ||
|
||
- name: Synchronize files to target repo | ||
run: | | ||
# Create necessary directories if they DNE | ||
mkdir -p target_repo/build-scripts | ||
mkdir -p target_repo/.github/workflows | ||
mkdir -p target_repo/config | ||
# Copy build scripts | ||
cp src/deployments/staging/build-scripts/*.sh target_repo/build-scripts/ || true | ||
# Copy .github directory | ||
cp -r src/deployments/staging/.github target_repo/ | ||
# Copy config files | ||
cp -r src/deployments/staging/config/* target_repo/config/ || true | ||
# Overwrite Dockerfile | ||
cp src/deployments/staging/Dockerfile target_repo/Dockerfile | ||
# Conditional copy for .env if not present | ||
if [ ! -f target_repo/.env ]; then | ||
cp src/deployments/staging/.env.example target_repo/.env | ||
fi | ||
# Conditional copy for README.md if not present | ||
if [ ! -f target_repo/README.md ]; then | ||
cp src/deployments/staging/README.example.md target_repo/README.md | ||
fi | ||
- name: Install jq | ||
run: sudo apt-get update && sudo apt-get install -y jq | ||
|
||
- name: Replace template variables | ||
run: | | ||
# Determine which values to use based on the index | ||
INDEX=${{ matrix.index }} | ||
if [ "$INDEX" -eq 0 ]; then | ||
DOMAIN=$(jq -r '.server_domain_name.internal' src/deployments/staging/config.json) | ||
LOADBALANCER=$(jq -r '.load_balancer_type.internal' src/deployments/staging/config.json) | ||
elif [ "$INDEX" -eq 1 ]; then | ||
DOMAIN=$(jq -r '.server_domain_name.external' src/deployments/staging/config.json) | ||
LOADBALANCER=$(jq -r '.load_balancer_type.external' src/deployments/staging/config.json) | ||
else | ||
DOMAIN=$(jq -r '.server_domain_name["docs-staging-x"]' src/deployments/staging/config.json) | ||
LOADBALANCER=$(jq -r '.load_balancer_type.["docs-staging-x"]' src/deployments/staging/config.json) | ||
# Replace {{x}} in the domain variable with the current index | ||
DOMAIN=$(echo "$DOMAIN" | sed "s/{{x}}/$INDEX/g") | ||
fi | ||
# Perform replacements in target_repo files | ||
# Replace the server_domain_name and load_balancer_type | ||
find target_repo -type f -exec sed -i "s|{{server_domain_name}}|$DOMAIN|g" {} + | ||
find target_repo -type f -exec sed -i "s|{{load_balancer_type}}|$LOADBALANCER|g" {} + | ||
# If any files still contain {{x}}, replace them with the current index | ||
find target_repo -type f -exec sed -i "s/{{x}}/$INDEX/g" {} + | ||
- name: Commit and push changes | ||
run: | | ||
cd target_repo | ||
git config user.name "github-actions[bot]" | ||
git config user.email "github-actions[bot]@users.noreply.github.com" | ||
git add . | ||
# If there are changes, commit and push | ||
if ! git diff --cached --quiet; then | ||
git commit -m "Synchronize files from source repository with index ${{ matrix.index }}" | ||
git push | ||
fi | ||
- uses: ./.github/actions/slack-alert | ||
if: ${{ failure() && github.event_name != 'workflow_dispatch' }} | ||
with: | ||
slack_channel_id: ${{ secrets.DOCS_ALERTS_SLACK_CHANNEL_ID }} | ||
slack_token: ${{ secrets.SLACK_DOCS_BOT_TOKEN }} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
# **What it does**: Triggers a repo disaptch event when pushing to a `docs-staging-x` branch | ||
# or when a PR is labeled with `docs-staging-x`. The repo dispatch updates the corresponding | ||
# docs-staging-x repo with the latest commit SHA, which triggers a deployment. | ||
# | ||
# Note: This does not work for docs-staging-{0/1} (review servers) updates to those are | ||
# handled in the `update-review-servers-on-code-push.yml` workflow. | ||
# | ||
# **Why we have it**: Makes staging deployments easy | ||
# **Who does it impact**: Anyone trying to deploy a staging branch, both Docs Content and Docs Engineering | ||
|
||
name: Update docs-staging-x | ||
|
||
on: | ||
push: | ||
branches: | ||
- 'docs-staging-[0-9]*' | ||
pull_request: | ||
types: [labeled] | ||
|
||
permissions: | ||
contents: read | ||
|
||
jobs: | ||
dispatch-sha: | ||
if: github.repository == 'github/docs-internal' | ||
runs-on: ubuntu-latest | ||
|
||
steps: | ||
# Needed because we call a composite action (Slack alert) | ||
- name: Checkout source repository | ||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 | ||
with: | ||
fetch-depth: 1 # Only need latest commit | ||
|
||
- name: Determine target staging repo | ||
id: determine_repo | ||
run: | | ||
# Determine the event type | ||
EVENT_TYPE="${{ github.event_name }}" | ||
SHOULD_DISPATCH="false" | ||
if [ "$EVENT_TYPE" = "push" ]; then | ||
# Triggered by a push event | ||
BRANCH_NAME=${GITHUB_REF#refs/heads/} | ||
echo "Triggered by push event on branch: $BRANCH_NAME" | ||
# Extract the staging number from branch name | ||
if [[ "$BRANCH_NAME" =~ ^docs-staging-([0-9]+)$ ]]; then | ||
STAGING_NUMBER="${BASH_REMATCH[1]}" | ||
else | ||
echo "Branch name does not match the required pattern docs-staging-X." | ||
exit 1 | ||
fi | ||
# Get the commit SHA from the push event | ||
COMMIT_SHA="${GITHUB_SHA}" | ||
elif [ "$EVENT_TYPE" = "pull_request" ]; then | ||
# Triggered by a PR labeled event | ||
LABEL_NAME="${{ github.event.label.name }}" | ||
echo "Triggered by PR labeled event with label: $LABEL_NAME" | ||
if [[ "$LABEL_NAME" =~ ^docs-staging-([0-9]+)$ ]]; then | ||
STAGING_NUMBER="${BASH_REMATCH[1]}" | ||
else | ||
echo "Label does not match the required pattern docs-staging-X." | ||
# Do not dispatch if it doesn't match | ||
echo "should_dispatch=false" >> $GITHUB_OUTPUT | ||
exit 0 | ||
fi | ||
# Get the commit SHA from the pull request head | ||
COMMIT_SHA="${{ github.event.pull_request.head.sha }}" | ||
else | ||
echo "Event type $EVENT_TYPE not supported." | ||
echo "should_dispatch=false" >> $GITHUB_OUTPUT | ||
exit 0 | ||
fi | ||
echo "Staging Number: $STAGING_NUMBER" | ||
# Check if staging number is 0 or 1 | ||
if [ "$STAGING_NUMBER" = "0" ] || [ "$STAGING_NUMBER" = "1" ]; then | ||
echo "Staging number $STAGING_NUMBER is reserved." | ||
echo "Review server repos are handled in the \`update-review-servers-on-code-push.yml\` repository." | ||
echo "should_dispatch=false" >> $GITHUB_OUTPUT | ||
exit 0 | ||
fi | ||
TARGET_REPO="docs-staging-$STAGING_NUMBER" | ||
echo "Target Repository: $TARGET_REPO" | ||
SHOULD_DISPATCH="true" | ||
# Set outputs | ||
echo "target_repo=$TARGET_REPO" >> $GITHUB_OUTPUT | ||
echo "commit_sha=$COMMIT_SHA" >> $GITHUB_OUTPUT | ||
echo "should_dispatch=$SHOULD_DISPATCH" >> $GITHUB_OUTPUT | ||
- name: Dispatch repository dispatch event to staging repo | ||
if: steps.determine_repo.outputs.should_dispatch == 'true' | ||
env: | ||
REPO_DISPATCH_TOKEN: ${{ secrets.DOCS_BOT_PAT_WORKFLOW }} | ||
TARGET_OWNER: github | ||
TARGET_REPO: ${{ steps.determine_repo.outputs.target_repo }} | ||
EVENT_TYPE: update-sha | ||
SHA: ${{ steps.determine_repo.outputs.commit_sha }} | ||
run: | | ||
curl -X POST \ | ||
-H "Accept: application/vnd.github.v3+json" \ | ||
-H "Authorization: token $REPO_DISPATCH_TOKEN" \ | ||
https://api.github.com/repos/$TARGET_OWNER/$TARGET_REPO/dispatches \ | ||
-d "{\"event_type\":\"$EVENT_TYPE\",\"client_payload\":{\"SHA\":\"$SHA\"}}" | ||
- uses: ./.github/actions/slack-alert | ||
if: ${{ failure() && github.event_name != 'workflow_dispatch' }} | ||
with: | ||
slack_channel_id: ${{ secrets.DOCS_ALERTS_SLACK_CHANNEL_ID }} | ||
slack_token: ${{ secrets.SLACK_DOCS_BOT_TOKEN }} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
# **What it does**: Triggers a repo dispatch event when pushing a code change to `main` | ||
# dispatches the latest SHA to both review server repos, `docs-staging-0` and `docs-staging-1` | ||
# | ||
# Note: We only dispatch on code changes to prevent unnecessary deployments since content changes | ||
# won't affect the review servers. | ||
# | ||
# **Why we have it**: Keeps the review servers up-to-date with the latest code changes | ||
# **Who does it impact**: Docs Content and Docs Engineering | ||
|
||
name: Update review servers on code push | ||
|
||
on: | ||
push: | ||
branches: | ||
- main | ||
paths: | ||
- 'src/**' | ||
- 'package.json' | ||
- 'tsconfig.json' | ||
- 'next.config.js' | ||
|
||
permissions: | ||
contents: read | ||
|
||
jobs: | ||
dispatch-sha: | ||
if: github.repository == 'github/docs-internal' | ||
runs-on: ubuntu-latest | ||
strategy: | ||
matrix: | ||
target_repo: [docs-staging-0, docs-staging-1] | ||
|
||
steps: | ||
# Needed because we call a composite action (Slack alert) | ||
- name: Checkout source repository | ||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 | ||
with: | ||
fetch-depth: 1 # Only need latest commit | ||
|
||
- name: Determine commit SHA and dispatch condition | ||
id: determine_repo | ||
run: | | ||
echo "commit_sha=${GITHUB_SHA}" >> $GITHUB_OUTPUT | ||
# Since this workflow only runs when code changes occur (due to path filters), | ||
# we can always set should_dispatch to true. | ||
echo "should_dispatch=true" >> $GITHUB_OUTPUT | ||
- name: Dispatch repository dispatch event to staging repos | ||
if: steps.determine_repo.outputs.should_dispatch == 'true' | ||
env: | ||
REPO_DISPATCH_TOKEN: ${{ secrets.DOCS_BOT_PAT_WORKFLOW }} | ||
TARGET_OWNER: github | ||
TARGET_REPO: ${{ matrix.target_repo }} | ||
EVENT_TYPE: update-sha | ||
SHA: ${{ steps.determine_repo.outputs.commit_sha }} | ||
run: | | ||
curl -X POST \ | ||
-H "Accept: application/vnd.github.v3+json" \ | ||
-H "Authorization: token $REPO_DISPATCH_TOKEN" \ | ||
https://api.github.com/repos/$TARGET_OWNER/$TARGET_REPO/dispatches \ | ||
-d "{\"event_type\":\"$EVENT_TYPE\",\"client_payload\":{\"SHA\":\"$SHA\"}}" | ||
- uses: ./.github/actions/slack-alert | ||
if: ${{ failure() && github.event_name != 'workflow_dispatch' }} | ||
with: | ||
slack_channel_id: ${{ secrets.DOCS_ALERTS_SLACK_CHANNEL_ID }} | ||
slack_token: ${{ secrets.SLACK_DOCS_BOT_TOKEN }} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
# The .env file in every docs-staging-X repo can be adjusted freely and is not synchronized | ||
|
||
# - - - | ||
# Unique per staging server | ||
# - - - | ||
# The name of the staging branch (should be the same as the repo name except for the review server) | ||
STAGING_BRANCH=docs-staging-{{x}} | ||
# Required for identifing image in datadog metrics | ||
MODA_APP_NAME=docs-staging-{{x}} | ||
# The most recent SHA of the STAGING_BRANCH | ||
SHA={{sha}} | ||
|
||
# - - - | ||
# Unique per review server | ||
# - - - | ||
# Empty for regular staging servers, 'internal' or 'external' for review server | ||
REVIEW_SERVER= | ||
|
||
# - - - | ||
# Shared defaults | ||
# - - - | ||
NODE_ENV=production | ||
PORT=4000 | ||
ENABLED_LANGUAGES='en,zh,es,pt,ru,ja,fr,de,ko' | ||
RATE_LIMIT_MAX='21' | ||
# Moda uses a non-default port for sending datadog metrics | ||
DD_DOGSTATSD_PORT='28125' |
Oops, something went wrong.