|
31 | 31 | env:
|
32 | 32 | DOCKER_IMAGE: ${{ secrets.PROD_REGISTRY_SERVER }}/${{ github.repository }}:${{ github.sha }}
|
33 | 33 | DOCKER_IMAGE_CACHE_REF: ${{ secrets.PROD_REGISTRY_SERVER }}/${{ github.repository }}:main-production
|
| 34 | + RESOURCE_GROUP_NAME: docs-prod |
| 35 | + APP_SERVICE_NAME: ghdocs-prod |
| 36 | + SLOT_NAME: canary |
34 | 37 |
|
35 | 38 | steps:
|
36 | 39 | - name: 'Az CLI login'
|
@@ -97,75 +100,19 @@ jobs:
|
97 | 100 |
|
98 | 101 | - name: 'Apply updated docker-compose.prod.yaml config to canary slot'
|
99 | 102 | run: |
|
100 |
| - az webapp config container set --multicontainer-config-type COMPOSE --multicontainer-config-file docker-compose.prod.yaml --slot canary -n ghdocs-prod -g docs-prod |
| 103 | + 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 }} |
101 | 104 |
|
102 | 105 | # Watch canary slot instances to see when all the instances are ready
|
103 | 106 | - name: Check that canary slot is ready
|
104 |
| - uses: actions/github-script@98814c53be79b1d30f795b907e553d8679345975 |
105 | 107 | env:
|
106 | 108 | CHECK_INTERVAL: 10000
|
107 | 109 | EXPECTED_SHA: ${{ github.sha }}
|
108 | 110 | CANARY_BUILD_URL: https://ghdocs-prod-canary.azurewebsites.net/_build
|
109 |
| - with: |
110 |
| - script: | |
111 |
| - const { execSync } = require('child_process') |
112 |
| -
|
113 |
| - const getBuildSha = (timeoutSeconds = 5) => { |
114 |
| - const url = process.env.CANARY_BUILD_URL; |
115 |
| - console.log(`Fetching ${url}`); |
116 |
| - const t0 = Date.now(); |
117 |
| - try { |
118 |
| - const o = execSync(`curl --connect-timeout ${timeoutSeconds} ${url}`, { |
119 |
| - encoding: "utf8", |
120 |
| - }); |
121 |
| - console.log(`Fetched ${url}. Took ${Date.now() - t0}ms`); |
122 |
| - return o.toString().trim(); |
123 |
| - } catch (err) { |
124 |
| - console.log(`Error fetching build sha from ${url}`); |
125 |
| - return null; |
126 |
| - } |
127 |
| - }; |
128 |
| -
|
129 |
| - const getStatesForSlot = (slot) => { |
130 |
| - return JSON.parse( |
131 |
| - execSync( |
132 |
| - `az webapp list-instances --slot ${slot} --query "[].state" -n ghdocs-prod -g docs-prod`, |
133 |
| - { encoding: 'utf8' } |
134 |
| - ) |
135 |
| - ) |
136 |
| - } |
137 |
| -
|
138 |
| - const waitDuration = parseInt(process.env.CHECK_INTERVAL, 10) || 10000 |
139 |
| - let attempts = 0 |
140 |
| - async function doCheck() { |
141 |
| - attempts++ |
142 |
| - console.log('Attempt:', attempts); |
143 |
| - const buildSha = getBuildSha(); |
144 |
| - console.log("Canary build SHA:", buildSha || "*unknown/failed*", "Expected SHA:", process.env.EXPECTED_SHA) |
145 |
| -
|
146 |
| - const states = getStatesForSlot('canary') |
147 |
| - console.log('Instance states:', states) |
148 |
| -
|
149 |
| - const isAllReady = states.every((s) => s === 'READY') |
150 |
| -
|
151 |
| - if (buildSha === process.env.EXPECTED_SHA && isAllReady) { |
152 |
| - process.exit(0) // success |
153 |
| - } |
154 |
| -
|
155 |
| - if (attempts * waitDuration > 10 * 60 * 1000) { |
156 |
| - console.log(`Giving up after a total of ${(attempts * waitDuration)/1000} seconds`) |
157 |
| - process.exit(1) // failure |
158 |
| - } |
159 |
| -
|
160 |
| - console.log(`checking again in ${waitDuration}ms`) |
161 |
| - setTimeout(doCheck, waitDuration) |
162 |
| - } |
163 |
| -
|
164 |
| - doCheck() |
| 111 | + run: src/workflows/check-canary-slots.js |
165 | 112 |
|
166 | 113 | - name: 'Swap canary slot to production'
|
167 | 114 | run: |
|
168 |
| - az webapp deployment slot swap --slot canary --target-slot production -n ghdocs-prod -g docs-prod |
| 115 | + az webapp deployment slot swap --slot ${{ env.SLOT_NAME }} --target-slot production -n ${{ env.APP_SERVICE_NAME }} -g ${{ env.RESOURCE_GROUP_NAME }} |
169 | 116 |
|
170 | 117 | - uses: ./.github/actions/slack-alert
|
171 | 118 | if: ${{ failure() && github.event_name != 'workflow_dispatch' }}
|
|
0 commit comments