Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

♻️[RUMF-1500] tweak deployment scripts #2046

Merged
merged 4 commits into from
Mar 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
12 changes: 6 additions & 6 deletions .gitlab-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -252,8 +252,8 @@ deploy-staging:
- export BUILD_MODE=canary
- yarn
- yarn build:bundle
- ./scripts/deploy.sh staging staging
- node ./scripts/upload-source-maps.js datad0g.com,datadoghq.com staging
- node ./scripts/deploy.js staging staging
- node ./scripts/upload-source-maps.js staging

deploy-prod-canary:
stage: deploy:canary
Expand All @@ -264,8 +264,8 @@ deploy-prod-canary:
- export BUILD_MODE=canary
- yarn
- yarn build:bundle
- ./scripts/deploy.sh prod canary
- node ./scripts/upload-source-maps.js datadoghq.com canary
- node ./scripts/deploy.js prod canary
- node ./scripts/upload-source-maps.js canary

deploy-prod-stable:
stage: deploy
Expand All @@ -279,8 +279,8 @@ deploy-prod-stable:
- VERSION=$(node -p -e "require('./lerna.json').version")
- yarn
- yarn build:bundle
- ./scripts/deploy.sh prod v${VERSION%%.*}
- node ./scripts/upload-source-maps.js datadoghq.com,datadoghq.eu,us3.datadoghq.com,us5.datadoghq.com,ap1.datadoghq.com v${VERSION%%.*}
- node ./scripts/deploy.js prod v${VERSION%%.*}
- node ./scripts/upload-source-maps.js v${VERSION%%.*}

publish-npm:
stage: deploy
Expand Down
75 changes: 75 additions & 0 deletions scripts/deploy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
'use strict'

const { printLog, command, runMain } = require('./utils')

const ONE_MINUTE_IN_SECOND = 60
const ONE_HOUR_IN_SECOND = 60 * ONE_MINUTE_IN_SECOND
const AWS_CONFIG = {
prod: {
accountId: 464622532012,
bucketName: 'browser-agent-artifacts-prod',
distributionId: 'EGB08BYCT1DD9',
},
staging: {
accountId: 727006795293,
bucketName: 'browser-agent-artifacts-staging',
distributionId: 'E2FP11ZSCFD3EU',
},
}
/**
* Deploy SDK files to CDN
* Usage:
* node deploy.js staging|prod staging|canary|vXXX
*/
const env = process.argv[2]
const version = process.argv[3]

const bundles = {
'packages/rum/bundle/datadog-rum.js': `datadog-rum-${version}.js`,
'packages/rum-slim/bundle/datadog-rum-slim.js': `datadog-rum-slim-${version}.js`,
'packages/logs/bundle/datadog-logs.js': `datadog-logs-${version}.js`,
}

runMain(() => {
uploadToS3(AWS_CONFIG[env])
invalidateCloudfront(AWS_CONFIG[env])
})

function uploadToS3(awsConfig) {
const accessToS3 = generateEnvironmentForRole(awsConfig.accountId, 'build-stable-browser-agent-artifacts-s3-write')
const browserCache =
version === 'staging' || version === 'canary' ? 15 * ONE_MINUTE_IN_SECOND : 4 * ONE_HOUR_IN_SECOND
const cacheControl = `max-age=${browserCache}, s-maxage=60`

for (const [filePath, bundleName] of Object.entries(bundles)) {
printLog(`Upload ${filePath} to s3://${awsConfig.bucketName}/${bundleName}`)
command`
aws s3 cp --cache-control ${cacheControl} ${filePath} s3://${awsConfig.bucketName}/${bundleName}`
.withEnvironment(accessToS3)
.run()
}
}

function invalidateCloudfront(awsConfig) {
const accessToCloudfront = generateEnvironmentForRole(awsConfig.accountId, 'build-stable-cloudfront-invalidation')
const pathsToInvalidate = Object.values(bundles).map((path) => `/${path}`)

printLog(`Trigger invalidation on ${awsConfig.distributionId} for: ${pathsToInvalidate.join(', ')}`)
command`
aws cloudfront create-invalidation --distribution-id ${awsConfig.distributionId} --paths ${pathsToInvalidate}`
.withEnvironment(accessToCloudfront)
.run()
}

function generateEnvironmentForRole(awsAccountId, roleName) {
const rawCredentials = command`
aws sts assume-role
--role-arn arn:aws:iam::${awsAccountId}:role/${roleName}
--role-session-name AWSCLI-Session`.run()
const credentials = JSON.parse(rawCredentials)['Credentials']
return {
AWS_ACCESS_KEY_ID: credentials['AccessKeyId'],
AWS_SECRET_ACCESS_KEY: credentials['SecretAccessKey'],
AWS_SESSION_TOKEN: credentials['SessionToken'],
}
}
88 changes: 0 additions & 88 deletions scripts/deploy.sh

This file was deleted.

46 changes: 25 additions & 21 deletions scripts/upload-source-maps.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,43 @@ const { SDK_VERSION } = require('./build-env')
/**
* Upload source maps to datadog
* Usage:
* BUILD_MODE=canary|release node upload-source-maps.js site1,site2,... staging|canary|vXXX
* BUILD_MODE=canary|release node upload-source-maps.js staging|canary|vXXX
*/

const sites = process.argv[2].split(',')
const suffix = process.argv[3]
const version = process.argv[2]
const packages = [
{ name: 'logs', service: 'browser-logs-sdk' },
{ name: 'rum', service: 'browser-rum-sdk' },
{ name: 'rum-slim', service: 'browser-rum-sdk' },
]
const sitesByVersion = {
staging: ['datad0g.com', 'datadoghq.com'],
canary: ['datadoghq.com'],
v4: ['datadoghq.com', 'datadoghq.eu', 'us3.datadoghq.com', 'us5.datadoghq.com', 'ap1.datadoghq.com'],
}

runMain(() => {
for (const { name, service } of packages) {
const bundleFolder = `packages/${name}/bundle`
renameFilesWithVersionSuffix(bundleFolder, name)
for (const site of sitesByVersion[version]) {
const normalizedSite = site.replaceAll('.', '-')
const apiKey = getSecretKey(`ci.browser-sdk.source-maps.${normalizedSite}.ci_api_key`)

uploadSourceMaps(site, apiKey, name, service, bundleFolder)
}
}
printLog('Source maps upload done.')
})

function renameFiles(bundleFolder, packageName) {
function renameFilesWithVersionSuffix(bundleFolder, packageName) {
// The datadog-ci CLI is taking a directory as an argument. It will scan every source map files in
// it and upload those along with the minified bundle. The file names must match the one from the
// CDN, thus we need to rename the bundles with the right suffix.
for (const ext of ['js', 'js.map']) {
const filePath = `${bundleFolder}/datadog-${packageName}.${ext}`
const suffixedFilePath = `${bundleFolder}/datadog-${packageName}-${suffix}.${ext}`
command`mv ${filePath} ${suffixedFilePath}`.run()
const sourceFilePath = `${bundleFolder}/datadog-${packageName}.${ext}`
const targetFilePath = `${bundleFolder}/datadog-${packageName}-${version}.${ext}`
command`mv ${sourceFilePath} ${targetFilePath}`.run()
}
}

Expand All @@ -45,17 +63,3 @@ function uploadSourceMaps(site, apiKey, packageName, service, bundleFolder) {
})
.run()
}

runMain(() => {
for (const { name, service } of packages) {
const bundleFolder = `packages/${name}/bundle`
renameFiles(bundleFolder, name)
for (const site of sites) {
const normalizedSite = site.replaceAll('.', '-')
const apiKey = getSecretKey(`ci.browser-sdk.source-maps.${normalizedSite}.ci_api_key`)

uploadSourceMaps(site, apiKey, name, service, bundleFolder)
}
}
printLog('Source maps upload done.')
})
14 changes: 12 additions & 2 deletions scripts/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,11 @@ function command(...templateArguments) {
*
* parseCommandTemplateArguments`foo ${'bar baz'}` == ['foo', 'bar baz']
*
* To pass template variables as different command arguments use an array as template argument:
*
* parseCommandTemplateArguments`foo ${['bar', 'baz']}` == ['foo', 'bar', 'baz']
*
*
* const commitMessage = 'my commit message'
* parseCommandTemplateArguments`git commit -c ${commitMessage}` == ['git', 'commit', '-c', 'my commit message']
*
Expand All @@ -175,8 +180,13 @@ function parseCommandTemplateArguments(templateStrings, ...templateVariables) {
if (i > 0) {
// Interleave variables with template strings
if (!parsedArguments.length || templateStrings[i - 1].match(/\s$/)) {
// If the latest string ends with a space, consider the variable as a separate argument
parsedArguments.push(templateVariables[i - 1])
// If the latest string ends with a space, consider the variable as separate argument(s)
const variable = templateVariables[i - 1]
if (Array.isArray(variable)) {
parsedArguments.push(...variable)
} else {
parsedArguments.push(variable)
}
} else {
// Else, append the variable to the latest argument
parsedArguments[parsedArguments.length - 1] += templateVariables[i - 1]
Expand Down