Undeploy from staging manually using a script (#19875)
* Add skeleton workflow and module for undeploying * Remove commented out code * Update undeployment module * Add '--destroy' flag to 'script/deploy' options * Add timeout and concurrency key for undeployment * Remove dangling unneeded function declaration * Add ant-man preview for inactive deployment state setting * Fix reference to pull request number * Refactor to extract more properties from the PR object * Fix reference to pull request number * Remove workflow * Add a README comment about '--destroy' usage * Fix grammar * Add missing 'ant-man' preview to createDeploymentStatus calls * Add missing preview to createDeploymentStatus calls * Find the latest existing deployment instead of creating a new one * Remove unused variable * Deactivate ALL deployments * Update copy * Add missing colons
This commit is contained in:
100
script/deployment/undeploy-from-staging.js
Normal file
100
script/deployment/undeploy-from-staging.js
Normal file
@@ -0,0 +1,100 @@
|
||||
const Heroku = require('heroku-client')
|
||||
const createStagingAppName = require('./create-staging-app-name')
|
||||
|
||||
module.exports = async function undeployFromStaging ({
|
||||
herokuToken,
|
||||
octokit,
|
||||
pullRequest
|
||||
}) {
|
||||
// Start a timer so we can report how long the deployment takes
|
||||
const startTime = Date.now()
|
||||
|
||||
// Extract some important properties from the PR
|
||||
const {
|
||||
number: pullNumber,
|
||||
base: {
|
||||
repo: {
|
||||
name: repo,
|
||||
owner: { login: owner }
|
||||
}
|
||||
},
|
||||
head: {
|
||||
ref: branch
|
||||
}
|
||||
} = pullRequest
|
||||
|
||||
const appName = createStagingAppName({ repo, pullNumber, branch })
|
||||
|
||||
try {
|
||||
const title = `from the 'staging' environment as '${appName}'`
|
||||
|
||||
console.log(`About to undeploy ${title}...`)
|
||||
|
||||
// Time to talk to Heroku...
|
||||
const heroku = new Heroku({ token: herokuToken })
|
||||
|
||||
// Is there already a Heroku App for this PR?
|
||||
let appExists = true
|
||||
try {
|
||||
await heroku.get(`/apps/${appName}`)
|
||||
} catch (error) {
|
||||
appExists = false
|
||||
}
|
||||
|
||||
// If there is an existing app, delete it
|
||||
if (appExists) {
|
||||
try {
|
||||
await heroku.delete(`/apps/${appName}`)
|
||||
|
||||
console.log(`Heroku app '${appName}' deleted`)
|
||||
} catch (error) {
|
||||
throw new Error(`Failed to delete Heroku app '${appName}'. Error: ${error}`)
|
||||
}
|
||||
}
|
||||
|
||||
// Get the latest deployment environment to signal its deactivation
|
||||
const { data: deployments } = await octokit.repos.listDeployments({
|
||||
owner,
|
||||
repo,
|
||||
|
||||
// In the GitHub API, there can only be one active deployment per environment.
|
||||
// For our many staging apps, we must use the unique appName as the environment.
|
||||
environment: appName
|
||||
})
|
||||
|
||||
if (deployments.length === 0) {
|
||||
console.log('🚀 No deployments to deactivate!')
|
||||
console.log(`Finished undeploying after ${Math.round((Date.now() - startTime) / 1000)} seconds`)
|
||||
return
|
||||
}
|
||||
|
||||
console.log(`Found ${deployments.length} GitHub Deployments`, deployments)
|
||||
|
||||
// Deactivate ALL of the deployments
|
||||
for (const deployment of deployments) {
|
||||
const { data: deploymentStatus } = await octokit.repos.createDeploymentStatus({
|
||||
owner,
|
||||
repo,
|
||||
deployment_id: deployment.id,
|
||||
state: 'inactive',
|
||||
description: 'The app was undeployed',
|
||||
// The 'ant-man' preview is required for `state` values of 'inactive', as well as
|
||||
// the use of the `log_url`, `environment_url`, and `auto_inactive` parameters.
|
||||
// The 'flash' preview is required for `state` values of 'in_progress' and 'queued'.
|
||||
mediaType: {
|
||||
previews: ['ant-man', 'flash']
|
||||
}
|
||||
})
|
||||
console.log(`🚀 Deployment status (ID: ${deployment.id}): ${deploymentStatus.state} - ${deploymentStatus.description}`)
|
||||
}
|
||||
|
||||
console.log(`Finished undeploying after ${Math.round((Date.now() - startTime) / 1000)} seconds`)
|
||||
} catch (error) {
|
||||
// Report failure!
|
||||
const failureMessage = `Undeployment failed after ${Math.round((Date.now() - startTime) / 1000)} seconds. See logs for more information.`
|
||||
console.error(failureMessage)
|
||||
|
||||
// Re-throw the error to bubble up
|
||||
throw error
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user