зеркало из https://github.com/github/docs.git
Add initial staging deployment workflow.
This commit is contained in:
Родитель
fe67b3d2aa
Коммит
5ae81c09e8
|
@ -20,12 +20,151 @@ 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: 'staging-env @ ${{ github.head_ref || github.run_id }} for ${{ github.event.number || github.event.inputs.PR_NUMBER }}'
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
azure-staging-build-and-deploy:
|
||||
if: ${{ github.repository == 'github/docs-internal' }}
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 20
|
||||
environment:
|
||||
# TODO: Update name and url to point to a specific slot for the branch/PR
|
||||
name: staging-env
|
||||
url: ${{ secrets.STAGING_APP_URL }}
|
||||
env:
|
||||
PR_NUMBER: ${{ github.event.number || github.event.inputs.PR_NUMBER || github.run_id }}
|
||||
COMMIT_REF: ${{ github.event.pull_request.head.sha || github.event.inputs.COMMIT_REF }}
|
||||
IMAGE_REPO: ${{ github.repository }}/pr-${{ github.event.number || github.event.inputs.PR_NUMBER || github.run_id }}
|
||||
RESOURCE_GROUP_NAME: docs-staging
|
||||
APP_SERVICE_NAME: ghdocs-staging
|
||||
SLOT_NAME: canary
|
||||
|
||||
steps:
|
||||
- name: 'No-op'
|
||||
- name: 'Az CLI login'
|
||||
uses: azure/login@1f63701bf3e6892515f1b7ce2d2bf1708b46beaf
|
||||
with:
|
||||
creds: ${{ secrets.PROD_AZURE_CREDENTIALS }}
|
||||
|
||||
- name: 'Docker login'
|
||||
uses: azure/docker-login@81744f9799e7eaa418697cb168452a2882ae844a
|
||||
with:
|
||||
login-server: ${{ secrets.NONPROD_REGISTRY_SERVER }}
|
||||
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
|
||||
uses: actions/checkout@dcd71f646680f2efd8db4afa5ad64fdcba30e748
|
||||
with:
|
||||
ref: ${{ env.COMMIT_REF }}
|
||||
# To prevent issues with cloning early access content later
|
||||
persist-credentials: 'false'
|
||||
lfs: 'true'
|
||||
|
||||
- name: Check out LFS objects
|
||||
run: git lfs checkout
|
||||
|
||||
- name: 'Set env vars'
|
||||
run: |
|
||||
echo "No-op"
|
||||
# Image tag is unique to each workflow run so that it always triggers a new deployment
|
||||
echo "DOCKER_IMAGE=${{ secrets.NONPROD_REGISTRY_SERVER }}/${{ env.IMAGE_REPO }}:${{ env.COMMIT_REF }}-${{ github.run_number }}-${{ github.run_attempt }}" >> $GITHUB_ENV
|
||||
|
||||
- name: Setup node
|
||||
uses: actions/setup-node@1f8c6b94b26d0feae1e387ca63ccbdc44d27b561
|
||||
with:
|
||||
node-version: 16.14.x
|
||||
cache: npm
|
||||
|
||||
- name: Clone docs-early-access
|
||||
uses: actions/checkout@dcd71f646680f2efd8db4afa5ad64fdcba30e748
|
||||
with:
|
||||
repository: github/docs-early-access
|
||||
token: ${{ secrets.DOCUBOT_REPO_PAT }}
|
||||
path: docs-early-access
|
||||
ref: main
|
||||
|
||||
- name: Merge docs-early-access repo's folders
|
||||
run: .github/actions-scripts/merge-early-access.sh
|
||||
|
||||
- name: 'Build and push image'
|
||||
uses: docker/build-push-action@7f9d37fa544684fb73bfe4835ed7214c255ce02b
|
||||
with:
|
||||
context: .
|
||||
push: true
|
||||
target: production
|
||||
tags: ${{ env.DOCKER_IMAGE }}
|
||||
build-args: |
|
||||
BUILD_SHA=${{ env.COMMIT_REF }}
|
||||
|
||||
- name: 'Update docker-compose.staging.yaml template file'
|
||||
run: |
|
||||
sed 's|#{IMAGE}#|${{ env.DOCKER_IMAGE }}|g' docker-compose.staging.tmpl.yaml > docker-compose.staging.yaml
|
||||
|
||||
- name: 'Apply updated docker-compose.staging.yaml config to deployment slot'
|
||||
run: |
|
||||
az webapp config container set --multicontainer-config-type COMPOSE --multicontainer-config-file docker-compose.staging.yaml --slot ${{ env.SLOT_NAME }} -n ${{ env.APP_SERVICE_NAME }} -g ${{ env.RESOURCE_GROUP_NAME }}
|
||||
|
||||
# Watch deployment slot instances to see when all the instances are ready
|
||||
- name: Check that deployment slot is ready
|
||||
uses: actions/github-script@2b34a689ec86a68d8ab9478298f91d5401337b7d
|
||||
env:
|
||||
CHECK_INTERVAL: 10000
|
||||
with:
|
||||
script: |
|
||||
const { execSync } = require('child_process')
|
||||
|
||||
const slotName = process.env.SLOT_NAME
|
||||
const appServiceName = process.env.APP_SERVICE_NAME
|
||||
const resourceGroupName = process.env.RESOURCE_GROUP_NAME
|
||||
|
||||
const getStatesForSlot = (slot, appService, resourceGroup) => {
|
||||
return JSON.parse(
|
||||
execSync(
|
||||
`az webapp list-instances --slot ${slot} --query "[].state" -n ${appService} -g ${resourceGroup}`,
|
||||
{ encoding: 'utf8' }
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
let hasStopped = false
|
||||
const waitDuration = parseInt(process.env.CHECK_INTERVAL, 10) || 10000
|
||||
async function doCheck() {
|
||||
const states = getStatesForSlot(slotName, appServiceName, resourceGroupName)
|
||||
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
|
||||
// That way we don't immediately succeed just because all the previous instances were READY
|
||||
if (!hasStopped) {
|
||||
hasStopped = states.some((s) => s === 'STOPPED')
|
||||
}
|
||||
|
||||
const isAllReady = states.every((s) => s === 'READY')
|
||||
|
||||
if (hasStopped && isAllReady) {
|
||||
process.exit(0) // success
|
||||
}
|
||||
|
||||
console.log(`checking again in ${waitDuration}ms`)
|
||||
setTimeout(doCheck, waitDuration)
|
||||
}
|
||||
|
||||
doCheck()
|
||||
|
||||
- name: 'Swap deployment slot to production'
|
||||
run: |
|
||||
az webapp deployment slot swap --slot ${{ env.SLOT_NAME }} --target-slot production -n ${{ env.APP_SERVICE_NAME }} -g ${{ env.RESOURCE_GROUP_NAME }}
|
||||
|
||||
- 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: Staging deployment (Azure) failed at commit ${{ env.COMMIT_REF }}. See https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
version: '3.7'
|
||||
|
||||
services:
|
||||
ghdocs-staging:
|
||||
image: '#{IMAGE}#'
|
||||
ports:
|
||||
- '4000:4000'
|
||||
environment:
|
||||
NODE_ENV: ${NODE_ENV}
|
||||
NODE_OPTIONS: ${NODE_OPTIONS}
|
||||
DD_API_KEY: ${DD_API_KEY}
|
||||
COOKIE_SECRET: ${COOKIE_SECRET}
|
||||
HYDRO_ENDPOINT: ${HYDRO_ENDPOINT}
|
||||
HYDRO_SECRET: ${HYDRO_SECRET}
|
||||
HAYSTACK_URL: ${HAYSTACK_URL}
|
||||
HEROKU_APP_NAME: ${HEROKU_APP_NAME}
|
||||
ENABLED_LANGUAGES: ${ENABLED_LANGUAGES}
|
||||
DEPLOYMENT_ENV: ${DEPLOYMENT_ENV}
|
||||
HEROKU_PRODUCTION_APP: true
|
||||
PORT: 4000
|
||||
DD_AGENT_HOST: datadog-agent
|
||||
SIGSCI_RPC_ADDRESS: sigsci-agent:8000
|
||||
depends_on:
|
||||
- datadog-agent
|
||||
restart: always
|
||||
|
||||
datadog-agent:
|
||||
image: datadog/dogstatsd:7.32.4
|
||||
ports:
|
||||
- '8125:8125'
|
||||
environment:
|
||||
DD_API_KEY: ${DD_API_KEY}
|
||||
DD_AGENT_HOST: datadog-agent
|
||||
DD_HISTOGRAM_PERCENTILES: 0.99 0.95 0.50
|
||||
|
||||
sigsci-agent:
|
||||
image: signalsciences/sigsci-agent
|
||||
ports:
|
||||
- '8000:8000'
|
||||
environment:
|
||||
SIGSCI_RPC_ADDRESS: 0.0.0.0:8000
|
||||
SIGSCI_ACCESSKEY: ${SIGSCI_ACCESSKEYID}
|
||||
SIGSCI_SECRETACCESSKEY: ${SIGSCI_SECRETACCESSKEY}
|
Загрузка…
Ссылка в новой задаче