diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index ed72b2873f..249ac8cead 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -22,7 +22,6 @@ stages: - after-tests - browserstack - pre-deploy - - pre-deploy-notify - deploy:canary - notify:canary - deploy @@ -306,67 +305,21 @@ deploy-prod-canary: - node ./scripts/deploy/deploy.js prod canary root - node ./scripts/deploy/upload-source-maps.js canary root -.deploy-prod: +deploy-manual: stage: deploy extends: - - .base-configuration - .tags - when: manual - allow_failure: false - script: - - export BUILD_MODE=release - - VERSION=$(node -p -e "require('./lerna.json').version") - - yarn - - yarn build:bundle - - node ./scripts/deploy/check-monitors.js $UPLOAD_PATH - - node ./scripts/deploy/deploy.js prod v${VERSION%%.*} $UPLOAD_PATH - - node ./scripts/deploy/upload-source-maps.js v${VERSION%%.*} $UPLOAD_PATH - -step-1_deploy-prod-minor-dcs: - extends: - - .deploy-prod - variables: - UPLOAD_PATH: us3,us5,ap1 - -step-2_deploy-prod-eu1: - extends: - - .deploy-prod - variables: - UPLOAD_PATH: eu1 - -step-3_deploy-prod-us1: - extends: - - .deploy-prod - variables: - UPLOAD_PATH: us1 - -step-4_deploy-prod-gov: - extends: - - .deploy-prod - variables: - UPLOAD_PATH: root - -step-5_publish-npm: - stage: deploy - extends: - - .base-configuration - - .tags - when: manual - allow_failure: false - script: - - yarn - - node ./scripts/deploy/publish-npm.js + trigger: + include: + - local: .gitlab/deploy-manual.yml -step-6_publish-developer-extension: +deploy-auto: stage: deploy extends: - - .base-configuration - .tags - when: manual - allow_failure: false - script: - - yarn - - node ./scripts/deploy/publish-developer-extension.js + trigger: + include: + - local: .gitlab/deploy-auto.yml ######################################################################################################################## # Notify @@ -395,15 +348,6 @@ notify-staging-failure: - 'MESSAGE_TEXT=":host-red: $CI_PROJECT_NAME main pipeline for <$BUILD_URL|$COMMIT_MESSAGE> failed."' - postmessage "#browser-sdk-deploy" "$MESSAGE_TEXT" -notify-release-ready: - stage: pre-deploy-notify - extends: - - .prepare_notification - - .tags - script: - - 'MESSAGE_TEXT=":i: $CI_PROJECT_NAME <$BUILD_URL|$COMMIT_MESSAGE> ready to be deployed to :datadog:"' - - postmessage "#browser-sdk-deploy" "$MESSAGE_TEXT" - notify-prod-canary-success: stage: notify:canary extends: @@ -424,24 +368,6 @@ notify-prod-canary-failure: - 'MESSAGE_TEXT=":host-red: $CI_PROJECT_NAME release pipeline <$BUILD_URL|$COMMIT_MESSAGE> failed."' - postmessage "#browser-sdk-deploy" "$MESSAGE_TEXT" -notify-prod-stable-success: - extends: - - .prepare_notification - - .tags - script: - - 'MESSAGE_TEXT=":rocket: $CI_PROJECT_NAME <$COMMIT_URL|$COMMIT_MESSAGE> deployed to :earth_americas:."' - - postmessage "#browser-sdk-deploy" "$MESSAGE_TEXT" - - postmessage "#rum-browser-sdk-ops" "$MESSAGE_TEXT" - -notify-prod-stable-failure: - extends: - - .prepare_notification - - .tags - when: on_failure - script: - - 'MESSAGE_TEXT=":host-red: $CI_PROJECT_NAME release pipeline <$BUILD_URL|$COMMIT_MESSAGE> failed."' - - postmessage "#browser-sdk-deploy" "$MESSAGE_TEXT" - ######################################################################################################################## # To staging CI ######################################################################################################################## diff --git a/.gitlab/deploy-auto.yml b/.gitlab/deploy-auto.yml new file mode 100644 index 0000000000..c6009b40ab --- /dev/null +++ b/.gitlab/deploy-auto.yml @@ -0,0 +1,116 @@ +stages: + - pre-notify + - deploy + - post-notify + +.base-configuration: + tags: ['runner:main', 'size:large'] + image: $CI_IMAGE + +.deploy-prod: + stage: deploy + script: + - export BUILD_MODE=release + - VERSION=$(node -p -e "require('./lerna.json').version") + - yarn + - yarn build:bundle + - node ./scripts/deploy/deploy-prod-dc.js v${VERSION%%.*} $UPLOAD_PATH true + +step-1_deploy-prod-minor-dcs: + when: manual + allow_failure: false + extends: + - .base-configuration + - .deploy-prod + variables: + UPLOAD_PATH: us3,us5,ap1 + +step-2_deploy-prod-eu1: + needs: + - step-1_deploy-prod-minor-dcs + extends: + - .base-configuration + - .deploy-prod + variables: + UPLOAD_PATH: eu1 + +step-3_deploy-prod-us1: + needs: + - step-2_deploy-prod-eu1 + extends: + - .base-configuration + - .deploy-prod + variables: + UPLOAD_PATH: us1 + +step-4_deploy-prod-gov: + needs: + - step-3_deploy-prod-us1 + extends: + - .base-configuration + - .deploy-prod + variables: + UPLOAD_PATH: root + +step-5_publish-npm: + needs: + - step-4_deploy-prod-gov + stage: deploy + extends: + - .base-configuration + allow_failure: false + script: + - yarn + - node ./scripts/deploy/publish-npm.js + +step-6_publish-developer-extension: + needs: + - step-5_publish-npm + stage: deploy + extends: + - .base-configuration + allow_failure: false + script: + - yarn + - node ./scripts/deploy/publish-developer-extension.js + +######################################################################################################################## +# Notify +######################################################################################################################## + +include: 'https://gitlab-templates.ddbuild.io/slack-notifier/v1/template.yml' + +.prepare_notification: + extends: .slack-notifier-base + before_script: + - COMMIT_MESSAGE=`git show-branch --no-name HEAD` + - BUILD_URL="$CI_PROJECT_URL/pipelines/$CI_PIPELINE_ID" + - COMMIT_URL="$CI_PROJECT_URL/commits/$CI_COMMIT_SHA" + +notify-deploy-ready: + stage: pre-notify + extends: + - .prepare_notification + script: + - 'MESSAGE_TEXT=":i: $CI_PROJECT_NAME <$BUILD_URL|$COMMIT_MESSAGE> ready to be deployed *automatically* to :datadog:"' + - postmessage "#browser-sdk-deploy" "$MESSAGE_TEXT" + +notify-deploy-success: + stage: post-notify + needs: + - step-6_publish-developer-extension + extends: + - .prepare_notification + script: + - 'MESSAGE_TEXT=":rocket: $CI_PROJECT_NAME <$COMMIT_URL|$COMMIT_MESSAGE> *automatically* deployed to :earth_americas:."' + - postmessage "#browser-sdk-deploy" "$MESSAGE_TEXT" + - postmessage "#rum-browser-sdk-ops" "$MESSAGE_TEXT" + +notify-deploy-failure: + stage: post-notify + extends: + - .prepare_notification + when: on_failure + script: + - 'MESSAGE_TEXT=":host-red: $CI_PROJECT_NAME *automatic* deployment of <$BUILD_URL|$COMMIT_MESSAGE> failed."' + - postmessage "#browser-sdk-deploy" "$MESSAGE_TEXT" diff --git a/.gitlab/deploy-manual.yml b/.gitlab/deploy-manual.yml new file mode 100644 index 0000000000..504cbab3d7 --- /dev/null +++ b/.gitlab/deploy-manual.yml @@ -0,0 +1,106 @@ +stages: + - pre-notify + - deploy + - post-notify + +.base-configuration: + tags: ['runner:main', 'size:large'] + image: $CI_IMAGE + +.deploy-prod: + stage: deploy + when: manual + allow_failure: false + script: + - export BUILD_MODE=release + - VERSION=$(node -p -e "require('./lerna.json').version") + - yarn + - yarn build:bundle + - node ./scripts/deploy/deploy-prod-dc.js v${VERSION%%.*} $UPLOAD_PATH false + +step-1_deploy-prod-minor-dcs: + extends: + - .base-configuration + - .deploy-prod + variables: + UPLOAD_PATH: us3,us5,ap1 + +step-2_deploy-prod-eu1: + extends: + - .base-configuration + - .deploy-prod + variables: + UPLOAD_PATH: eu1 + +step-3_deploy-prod-us1: + extends: + - .base-configuration + - .deploy-prod + variables: + UPLOAD_PATH: us1 + +step-4_deploy-prod-gov: + extends: + - .base-configuration + - .deploy-prod + variables: + UPLOAD_PATH: root + +step-5_publish-npm: + stage: deploy + extends: + - .base-configuration + when: manual + allow_failure: false + script: + - yarn + - node ./scripts/deploy/publish-npm.js + +step-6_publish-developer-extension: + stage: deploy + extends: + - .base-configuration + when: manual + allow_failure: false + script: + - yarn + - node ./scripts/deploy/publish-developer-extension.js + +######################################################################################################################## +# Notify +######################################################################################################################## + +include: 'https://gitlab-templates.ddbuild.io/slack-notifier/v1/template.yml' + +.prepare_notification: + extends: .slack-notifier-base + before_script: + - COMMIT_MESSAGE=`git show-branch --no-name HEAD` + - BUILD_URL="$CI_PROJECT_URL/pipelines/$CI_PIPELINE_ID" + - COMMIT_URL="$CI_PROJECT_URL/commits/$CI_COMMIT_SHA" + +notify-deploy-ready: + stage: pre-notify + extends: + - .prepare_notification + script: + - 'MESSAGE_TEXT=":i: $CI_PROJECT_NAME <$BUILD_URL|$COMMIT_MESSAGE> ready to be deployed *manually* to :datadog:"' + - postmessage "#browser-sdk-deploy" "$MESSAGE_TEXT" + +notify-deploy-success: + stage: post-notify + extends: + - .prepare_notification + script: + - 'MESSAGE_TEXT=":rocket: $CI_PROJECT_NAME <$COMMIT_URL|$COMMIT_MESSAGE> *manually* deployed to :earth_americas:."' + - postmessage "#browser-sdk-deploy" "$MESSAGE_TEXT" + - postmessage "#rum-browser-sdk-ops" "$MESSAGE_TEXT" + +notify-deploy-failure: + stage: post-notify + extends: + - .prepare_notification + when: on_failure + script: + - 'MESSAGE_TEXT=":host-red: $CI_PROJECT_NAME *manual* deployment of <$BUILD_URL|$COMMIT_MESSAGE> failed."' + - postmessage "#browser-sdk-deploy" "$MESSAGE_TEXT" diff --git a/scripts/deploy/deploy-prod-dc.js b/scripts/deploy/deploy-prod-dc.js new file mode 100644 index 0000000000..6a95918fda --- /dev/null +++ b/scripts/deploy/deploy-prod-dc.js @@ -0,0 +1,35 @@ +const { printLog, runMain, timeout } = require('../lib/execution-utils') +const { command } = require('../lib/command') + +/** + * Orchestrate the deployments of the artifacts for specific DCs + * Usage: + * node deploy-prod-dc.js vXXX us1,eu1,... true|false + */ +const ONE_MINUTE_IN_SECOND = 60 +const GATE_DURATION = 30 * ONE_MINUTE_IN_SECOND +const GATE_INTERVAL = ONE_MINUTE_IN_SECOND + +const version = process.argv[2] +const uploadPath = process.argv[3] +const withGateMonitors = process.argv[4] === 'true' + +runMain(async () => { + command`node ./scripts/deploy/check-monitors.js ${uploadPath}`.withLogs().run() + command`node ./scripts/deploy/deploy.js prod v${version} ${uploadPath}`.withLogs().run() + command`node ./scripts/deploy/upload-source-maps.js prod v${version} ${uploadPath}`.withLogs().run() + + if (withGateMonitors && uploadPath !== 'root') { + await gateMonitors(uploadPath) + } +}) + +async function gateMonitors(uploadPath) { + printLog(`Check monitors for ${uploadPath} during ${GATE_DURATION / ONE_MINUTE_IN_SECOND} minutes`) + for (let i = 0; i < GATE_DURATION; i += GATE_INTERVAL) { + command`node ./scripts/deploy/check-monitors.js ${uploadPath}`.run() + process.stdout.write('.') // progress indicator + await timeout(GATE_INTERVAL * 1000) + } + printLog() // new line +} diff --git a/scripts/lib/command.js b/scripts/lib/command.js index 7670ccb05d..821c1b8d78 100644 --- a/scripts/lib/command.js +++ b/scripts/lib/command.js @@ -21,7 +21,7 @@ function command(...templateArguments) { let input = '' let env - let currentWorkingDirectory + const extraOptions = {} return { withInput(newInput) { @@ -35,7 +35,12 @@ function command(...templateArguments) { }, withCurrentWorkingDirectory(newCurrentWorkingDirectory) { - currentWorkingDirectory = newCurrentWorkingDirectory + extraOptions.cwd = newCurrentWorkingDirectory + return this + }, + + withLogs() { + extraOptions.stdio = 'inherit' return this }, @@ -43,8 +48,8 @@ function command(...templateArguments) { const commandResult = childProcess.spawnSync(commandName, commandArguments, { input, env: { ...process.env, ...env }, - cwd: currentWorkingDirectory, encoding: 'utf-8', + ...extraOptions, }) if (commandResult.status !== 0) {