diff --git a/.circleci/config.yml b/.circleci/config.yml index b8666d879..76992feca 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -160,6 +160,7 @@ workflows: requires: - prep-deps - prep-build + - prep-build-flask - all-tests-pass - job-publish-storybook: filters: @@ -371,7 +372,7 @@ jobs: root: . paths: - storybook-build - + test-storybook: executor: node-browsers steps: @@ -718,8 +719,11 @@ jobs: - attach_workspace: at: . - run: - name: sentry sourcemaps upload - command: SENTRY_ORG=metamask SENTRY_PROJECT=metamask yarn sentry:publish + name: Publish main release to Sentry + command: yarn sentry:publish + - run: + name: Publish Flask release to Sentry + command: yarn sentry:publish --build-type flask - run: name: Create GitHub release command: | diff --git a/.circleci/scripts/release-create-gh-release.sh b/.circleci/scripts/release-create-gh-release.sh index 93303f576..54d3946a9 100755 --- a/.circleci/scripts/release-create-gh-release.sh +++ b/.circleci/scripts/release-create-gh-release.sh @@ -26,25 +26,53 @@ function install_github_cli () popd } +function print_flask_version () +{ + local flask_filename + flask_filename="$(find ./builds-flask -type f -name 'metamask-flask-chrome-*.zip' -exec basename {} .zip \;)" + + local flask_build_filename_prefix + flask_build_filename_prefix='metamask-flask-chrome-' + local flask_build_filename_prefix_size + flask_build_filename_prefix_size="${#flask_build_filename_prefix}" + + # Use substring parameter expansion to remove the filename prefix, leaving just the version + echo "${flask_filename:$flask_build_filename_prefix_size}" +} + +function publish_flask_tag () +{ + local flask_version="${1}"; shift + + git config user.email "metamaskbot@users.noreply.github.com" + git config user.name "MetaMask Bot" + git tag -a "v${flask_version}" -m "Flask version ${flask_version}" + repo_slug="$CIRCLE_PROJECT_USERNAME/$CIRCLE_PROJECT_REPONAME" + git push "https://$GITHUB_TOKEN@github.com/$repo_slug" "v${flask_version}" +} + current_commit_msg=$(git show -s --format='%s' HEAD) if [[ $current_commit_msg =~ Version[-[:space:]](v[[:digit:]]+.[[:digit:]]+.[[:digit:]]+) ]] then tag="${BASH_REMATCH[1]}" + flask_version="$(print_flask_version)" install_github_cli printf '%s\n' 'Creating GitHub Release' release_body="$(awk -v version="${tag##v}" -f .circleci/scripts/show-changelog.awk CHANGELOG.md)" - pushd builds - hub release create \ - --attach metamask-chrome-*.zip \ - --attach metamask-firefox-*.zip \ - --message "Version ${tag##v}" \ - --message "$release_body" \ - --commitish "$CIRCLE_SHA1" \ - "$tag" - popd + hub release create \ + --attach builds/metamask-chrome-*.zip \ + --attach builds/metamask-firefox-*.zip \ + --attach builds-flask/metamask-flask-chrome-*.zip \ + --attach builds-flask/metamask-flask-firefox-*.zip \ + --message "Version ${tag##v}" \ + --message "$release_body" \ + --commitish "$CIRCLE_SHA1" \ + "$tag" + + publish_flask_tag "${flask_version}" else printf '%s\n' 'Version not found in commit message; skipping GitHub Release' exit 0 diff --git a/development/metamaskbot-build-announce.js b/development/metamaskbot-build-announce.js index 2d09a93d1..8f1a0bece 100755 --- a/development/metamaskbot-build-announce.js +++ b/development/metamaskbot-build-announce.js @@ -3,7 +3,7 @@ const { promises: fs } = require('fs'); const path = require('path'); const fetch = require('node-fetch'); const glob = require('fast-glob'); -const VERSION = require('../dist/chrome/manifest.json').version; // eslint-disable-line import/no-unresolved +const VERSION = require('../package.json').version; const { getHighlights } = require('./highlights'); start().catch(console.error); diff --git a/development/sentry-publish.js b/development/sentry-publish.js index 81fa58790..5a988c65b 100644 --- a/development/sentry-publish.js +++ b/development/sentry-publish.js @@ -1,6 +1,11 @@ #!/usr/bin/env node -const VERSION = require('../dist/chrome/manifest.json').version; // eslint-disable-line import/no-unresolved + +const yargs = require('yargs/yargs'); +const { hideBin } = require('yargs/helpers'); + const { runCommand, runInShell } = require('./lib/run-command'); +const { getVersion } = require('./lib/get-version'); +const { BuildType } = require('./lib/build-type'); start().catch((error) => { console.error(error); @@ -8,34 +13,63 @@ start().catch((error) => { }); async function start() { - if (!process.env.SENTRY_ORG) { - throw new Error('Missing required "SENTRY_ORG" environment variable'); - } else if (!process.env.SENTRY_PROJECT) { - throw new Error('Missing required "SENTRY_PROJECT" environment variable'); - } + const { argv } = yargs(hideBin(process.argv)).usage( + '$0 [options]', + 'Publish a release to Sentry', + (_yargs) => + _yargs + .option('org', { + default: 'metamask', + description: 'The Sentry organization', + type: 'string', + }) + .option('project', { + default: 'metamask', + description: 'The Sentry project to publish', + type: 'string', + }) + .option('build-type', { + default: BuildType.main, + description: 'The MetaMask extension build type', + choices: Object.values(BuildType), + }) + .option('build-version', { + default: 0, + description: 'The MetaMask extension build version', + type: 'number', + }), + ); + + const { buildType, buildVersion, org, project } = argv; + + process.env.SENTRY_ORG = org; + process.env.SENTRY_PROJECT = project; const authWorked = await checkIfAuthWorks(); if (!authWorked) { throw new Error(`Sentry auth failed`); } + + const version = getVersion(buildType, buildVersion); + // check if version exists or not - const versionAlreadyExists = await checkIfVersionExists(); + const versionAlreadyExists = await checkIfVersionExists(version); // abort if versions exists if (versionAlreadyExists) { console.log( - `Version "${VERSION}" already exists on Sentry, skipping version creation`, + `Version "${version}" already exists on Sentry, skipping version creation`, ); } else { // create sentry release - console.log(`creating Sentry release for "${VERSION}"...`); - await runCommand('sentry-cli', ['releases', 'new', VERSION]); + console.log(`creating Sentry release for "${version}"...`); + await runCommand('sentry-cli', ['releases', 'new', version]); console.log( - `removing any existing files from Sentry release "${VERSION}"...`, + `removing any existing files from Sentry release "${version}"...`, ); await runCommand('sentry-cli', [ 'releases', 'files', - VERSION, + version, 'delete', '--all', ]); @@ -43,18 +77,23 @@ async function start() { // check if version has artifacts or not const versionHasArtifacts = - versionAlreadyExists && (await checkIfVersionHasArtifacts()); + versionAlreadyExists && (await checkIfVersionHasArtifacts(version)); if (versionHasArtifacts) { console.log( - `Version "${VERSION}" already has artifacts on Sentry, skipping sourcemap upload`, + `Version "${version}" already has artifacts on Sentry, skipping sourcemap upload`, ); return; } + const additionalUploadArgs = []; + if (buildType !== BuildType.main) { + additionalUploadArgs.push('--dist-directory', `dist-${buildType}`); + } // upload sentry source and sourcemaps await runInShell('./development/sentry-upload-artifacts.sh', [ '--release', - VERSION, + version, + ...additionalUploadArgs, ]); } @@ -64,17 +103,17 @@ async function checkIfAuthWorks() { ); } -async function checkIfVersionExists() { +async function checkIfVersionExists(version) { return await doesNotFail(() => - runCommand('sentry-cli', ['releases', 'info', VERSION]), + runCommand('sentry-cli', ['releases', 'info', version]), ); } -async function checkIfVersionHasArtifacts() { +async function checkIfVersionHasArtifacts(version) { const [artifact] = await runCommand('sentry-cli', [ 'releases', 'files', - VERSION, + version, 'list', ]); // When there's no artifacts, we get a response from the shell like this ['', ''] diff --git a/development/sentry-upload-artifacts.sh b/development/sentry-upload-artifacts.sh index 673e1dd73..9d2fd32b4 100755 --- a/development/sentry-upload-artifacts.sh +++ b/development/sentry-upload-artifacts.sh @@ -23,17 +23,20 @@ Upload JavaScript bundles and sourcemaps to Sentry Options: -h, --help Show help text -r, --release Sentry release to upload files to (defaults to 'VERSION' environment variable) + --dist-directory The 'dist' directory to use. Defaults to 'dist'. EOF } function upload_sourcemaps { local release="${1}"; shift + local dist_directory="${1}"; shift - sentry-cli releases files "${release}" upload-sourcemaps ./dist/chrome/*.js ./dist/sourcemaps/ --rewrite --url-prefix 'metamask' + sentry-cli releases files "${release}" upload-sourcemaps "${dist_directory}"/chrome/*.js "${dist_directory}"/sourcemaps/ --rewrite --url-prefix 'metamask' } function main { local release=VERSION + local dist_directory='dist' while :; do case "${1-default}" in @@ -51,6 +54,16 @@ function main { release="${2}" shift ;; + --dist-directory) + if [[ -z $2 ]] + then + printf "'dist-directory' option requires an argument.\\n" >&2 + printf '%s\n' "${__SEE_HELP_MESSAGE__}" >&2 + exit 1 + fi + dist_directory="${2}" + shift + ;; *) break esac @@ -70,7 +83,7 @@ function main { fi printf 'uploading source files and sourcemaps for Sentry release "%s"...\n' "${release}" - upload_sourcemaps "${release}" + upload_sourcemaps "${release}" "${dist_directory}" printf 'all done!\n' }