Move script to check state of canary slots to its own file (#46057)
Co-authored-by: Peter Bengtsson <mail@peterbe.com>
This commit is contained in:
65
.github/workflows/azure-prod-build-deploy.yml
vendored
65
.github/workflows/azure-prod-build-deploy.yml
vendored
@@ -31,6 +31,9 @@ jobs:
|
||||
env:
|
||||
DOCKER_IMAGE: ${{ secrets.PROD_REGISTRY_SERVER }}/${{ github.repository }}:${{ github.sha }}
|
||||
DOCKER_IMAGE_CACHE_REF: ${{ secrets.PROD_REGISTRY_SERVER }}/${{ github.repository }}:main-production
|
||||
RESOURCE_GROUP_NAME: docs-prod
|
||||
APP_SERVICE_NAME: ghdocs-prod
|
||||
SLOT_NAME: canary
|
||||
|
||||
steps:
|
||||
- name: 'Az CLI login'
|
||||
@@ -97,75 +100,19 @@ jobs:
|
||||
|
||||
- name: 'Apply updated docker-compose.prod.yaml config to canary slot'
|
||||
run: |
|
||||
az webapp config container set --multicontainer-config-type COMPOSE --multicontainer-config-file docker-compose.prod.yaml --slot canary -n ghdocs-prod -g docs-prod
|
||||
az webapp config container set --multicontainer-config-type COMPOSE --multicontainer-config-file docker-compose.prod.yaml --slot ${{ env.SLOT_NAME }} -n ${{ env.APP_SERVICE_NAME }} -g ${{ env.RESOURCE_GROUP_NAME }}
|
||||
|
||||
# Watch canary slot instances to see when all the instances are ready
|
||||
- name: Check that canary slot is ready
|
||||
uses: actions/github-script@98814c53be79b1d30f795b907e553d8679345975
|
||||
env:
|
||||
CHECK_INTERVAL: 10000
|
||||
EXPECTED_SHA: ${{ github.sha }}
|
||||
CANARY_BUILD_URL: https://ghdocs-prod-canary.azurewebsites.net/_build
|
||||
with:
|
||||
script: |
|
||||
const { execSync } = require('child_process')
|
||||
|
||||
const getBuildSha = (timeoutSeconds = 5) => {
|
||||
const url = process.env.CANARY_BUILD_URL;
|
||||
console.log(`Fetching ${url}`);
|
||||
const t0 = Date.now();
|
||||
try {
|
||||
const o = execSync(`curl --connect-timeout ${timeoutSeconds} ${url}`, {
|
||||
encoding: "utf8",
|
||||
});
|
||||
console.log(`Fetched ${url}. Took ${Date.now() - t0}ms`);
|
||||
return o.toString().trim();
|
||||
} catch (err) {
|
||||
console.log(`Error fetching build sha from ${url}`);
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
const getStatesForSlot = (slot) => {
|
||||
return JSON.parse(
|
||||
execSync(
|
||||
`az webapp list-instances --slot ${slot} --query "[].state" -n ghdocs-prod -g docs-prod`,
|
||||
{ encoding: 'utf8' }
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
const waitDuration = parseInt(process.env.CHECK_INTERVAL, 10) || 10000
|
||||
let attempts = 0
|
||||
async function doCheck() {
|
||||
attempts++
|
||||
console.log('Attempt:', attempts);
|
||||
const buildSha = getBuildSha();
|
||||
console.log("Canary build SHA:", buildSha || "*unknown/failed*", "Expected SHA:", process.env.EXPECTED_SHA)
|
||||
|
||||
const states = getStatesForSlot('canary')
|
||||
console.log('Instance states:', states)
|
||||
|
||||
const isAllReady = states.every((s) => s === 'READY')
|
||||
|
||||
if (buildSha === process.env.EXPECTED_SHA && isAllReady) {
|
||||
process.exit(0) // success
|
||||
}
|
||||
|
||||
if (attempts * waitDuration > 10 * 60 * 1000) {
|
||||
console.log(`Giving up after a total of ${(attempts * waitDuration)/1000} seconds`)
|
||||
process.exit(1) // failure
|
||||
}
|
||||
|
||||
console.log(`checking again in ${waitDuration}ms`)
|
||||
setTimeout(doCheck, waitDuration)
|
||||
}
|
||||
|
||||
doCheck()
|
||||
run: src/workflows/check-canary-slots.js
|
||||
|
||||
- name: 'Swap canary slot to production'
|
||||
run: |
|
||||
az webapp deployment slot swap --slot canary --target-slot production -n ghdocs-prod -g docs-prod
|
||||
az webapp deployment slot swap --slot ${{ env.SLOT_NAME }} --target-slot production -n ${{ env.APP_SERVICE_NAME }} -g ${{ env.RESOURCE_GROUP_NAME }}
|
||||
|
||||
- uses: ./.github/actions/slack-alert
|
||||
if: ${{ failure() && github.event_name != 'workflow_dispatch' }}
|
||||
|
||||
44
.github/workflows/azure-staging-build-deploy.yml
vendored
44
.github/workflows/azure-staging-build-deploy.yml
vendored
@@ -110,49 +110,11 @@ jobs:
|
||||
|
||||
# Watch deployment slot instances to see when all the instances are ready
|
||||
- name: Check that deployment slot is ready
|
||||
uses: actions/github-script@98814c53be79b1d30f795b907e553d8679345975
|
||||
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()
|
||||
EXPECTED_SHA: ${{ github.sha }}
|
||||
CANARY_BUILD_URL: https://ghdocs-staging-canary.azurewebsites.net/_build
|
||||
run: src/workflows/check-canary-slots.js
|
||||
|
||||
- name: 'Swap deployment slot to production'
|
||||
run: |
|
||||
|
||||
Reference in New Issue
Block a user