1
0
mirror of synced 2026-01-09 06:03:09 -05:00
Files
docs/script/deployment/purge-edge-cache.js
Grace Park 9c9d47f508 Prod deployment workflow (#21223)
* add production deployment

* updating existing build

* remove state

* remove PR_URL and switch to main branch

* break out into build, prepare, and deploy

* update to download-artifact

* update staging to prod

* Actions production deployment redux (#21238)

* Simplify production deployment into a single Actions job

* Force esm to install

* Switch flag ordering to match staging deploy

* Use 'npm install' for the second installation to avoid deleting the prodDeps

* Apply Heroku upload fixes

* Include `.npmrc` file in builds to omit `optionalDeps`

* Remove download-artifact action

Co-authored-by: Grace Park <gracepark@github.com>

* Script updates to prod deployment (#21247)

* updating script to use latest sha

* changing back workflowRunLog

* remove line

* update error wording

* remove comment - using commit sha

* need release.id

* Update script/deployment/deploy-to-production.js

Co-authored-by: James M. Greene <JamesMGreene@github.com>

* remove hydro

* Update script/deployment/deploy-to-production.js

Co-authored-by: James M. Greene <JamesMGreene@github.com>

* Update .github/workflows/prod-build-deploy-pr.yml

Co-authored-by: James M. Greene <JamesMGreene@github.com>

* Update script/deployment/deploy-to-production.js

Co-authored-by: James M. Greene <JamesMGreene@github.com>

* Update script/deployment/deploy-to-production.js

Co-authored-by: James M. Greene <JamesMGreene@github.com>

* Update script/deployment/deploy-to-production.js

Co-authored-by: James M. Greene <JamesMGreene@github.com>

* updating spacing

* add 404/429 responses while polling Heroku API for prod

* removing nested ifs

* adding SOURCE_BLOB_URL

* update for early access

* add install dotenv

* need to add persist-credentials

* Testing GET request

* update request

* Rename workflow file to remove '-pr'

We are now triggering on pushes to 'main' rather than PR merges

* Remove the unnecessary workflow step to create a failure Status

Because the production deploy is done via a single workflow rather than a 2-part workflow chain, this is thankfully unnecessary

* Install all of the npm dependencies

We'll need them!

* Add the '-z' flag to 'tar' to gzip the tarball

* Pass the Heroku upload URL via env vars for security

Prevents potential injection attacks

* Log the deployment ID and log URL as deploy step outputs

* Take notice of Heroku polling resulting in failure statuses

* Add a note to consider waiting for Heroku Preboot

* Add a script and workflow step to purge Fastly

* update response to get sha

* Switch to Octokit functions instead of 'request' method

Co-authored-by: James M. Greene <JamesMGreene@github.com>
2021-09-24 16:09:08 +00:00

69 lines
2.4 KiB
JavaScript

import sleep from 'await-sleep'
import got from 'got'
const ONE_SECOND = 1000
const ONE_MINUTE = 60 * ONE_SECOND
async function purgeFastlyBySurrogateKey({ apiToken, serviceId, surrogateKey }) {
const key = surrogateKey
const safeServiceId = encodeURIComponent(serviceId)
const headers = {
'fastly-key': apiToken,
accept: 'application/json',
'fastly-soft-purge': '1',
}
const requestPath = `https://api.fastly.com/service/${safeServiceId}/purge/${key}`
return got.post(requestPath, { headers, json: true })
}
// This delay (includeDelayForPreboot) can potentially be removed in the
// future if the deployment workflow is updated to include a delay to offset
// Heroku Preboot before this script runs.
export default async function purgeEdgeCache({ includeDelayForPreboot = true } = {}) {
// If Heroku Preboot is enabled, then there is an additional delay of at
// least 2 minutes before the new dynos are swapped into active serving.
const delayForPrebootSwap = 2 * ONE_MINUTE + 30 * ONE_SECOND
// Give the app some extra time to wake up before the thundering herd of
// Fastly requests.
const delayBeforeFirstPurge = ONE_MINUTE
// Evidence has shown that it's necessary to purge twice to ensure all
// customers see fresh content.
const delayBeforeSecondPurge = 5 * ONE_SECOND
console.log('Fastly purgeEdgeCache initialized...')
const { FASTLY_TOKEN, FASTLY_SERVICE_ID, FASTLY_SURROGATE_KEY } = process.env
if (!FASTLY_TOKEN || !FASTLY_SERVICE_ID || !FASTLY_SURROGATE_KEY) {
console.log('Fastly env vars not detected; skipping purgeEdgeCache step')
return
}
const purgingParams = {
apiToken: FASTLY_TOKEN,
serviceId: FASTLY_SERVICE_ID,
surrogateKey: FASTLY_SURROGATE_KEY,
}
if (includeDelayForPreboot) {
console.log('Waiting for Heroku Preboot to swap dynos...')
await sleep(delayForPrebootSwap)
}
console.log('Waiting extra time to prevent a Thundering Herd problem...')
await sleep(delayBeforeFirstPurge)
console.log('Attempting first Fastly purge...')
const firstPurge = await purgeFastlyBySurrogateKey(purgingParams)
console.log('First Fastly purge result:', firstPurge.body || firstPurge)
console.log('Waiting to purge a second time...')
await sleep(delayBeforeSecondPurge)
console.log('Attempting second Fastly purge...')
const secondPurge = await purgeFastlyBySurrogateKey(purgingParams)
console.log('Second Fastly purge result:', secondPurge.body || secondPurge)
}