diff --git a/.circleci/config.yml b/.circleci/config.yml index f38bd8c5ab46..8f16e0922448 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1657,9 +1657,15 @@ jobs: - run: name: Publish main release to Sentry command: yarn sentry:publish + - run: + name: Publish main MV2 release to Sentry + command: yarn sentry:publish --dist mv2 - run: name: Publish Flask release to Sentry command: yarn sentry:publish --build-type flask + - run: + name: Publish Flask MV2 release to Sentry + command: yarn sentry:publish --build-type flask --dist mv2 - run: name: Publish MMI release to Sentry command: yarn sentry:publish --build-type mmi diff --git a/app/scripts/lib/setupSentry.js b/app/scripts/lib/setupSentry.js index 47f06a6c2edf..d496ff805810 100644 --- a/app/scripts/lib/setupSentry.js +++ b/app/scripts/lib/setupSentry.js @@ -1,6 +1,7 @@ import * as Sentry from '@sentry/browser'; import { Dedupe, ExtraErrorData } from '@sentry/integrations'; import browser from 'webextension-polyfill'; +import { isManifestV3 } from '../../../shared/modules/mv3.utils'; import { FilterEvents } from './sentry-filter-events'; import extractEthjsErrorMessage from './extractEthjsErrorMessage'; @@ -191,6 +192,7 @@ export default function setupSentry({ release, getState }) { Sentry.init({ dsn: sentryTarget, debug: METAMASK_DEBUG, + dist: isManifestV3 ? 'mv3' : 'mv2', /** * autoSessionTracking defaults to true and operates by sending a session * packet to sentry. This session packet does not appear to be filtered out diff --git a/development/sentry-publish.js b/development/sentry-publish.js index 3645e04b6771..22ff6156a243 100755 --- a/development/sentry-publish.js +++ b/development/sentry-publish.js @@ -37,10 +37,15 @@ async function start() { default: 0, description: 'The MetaMask extension build version', type: 'number', + }) + .option('dist', { + description: + 'The MetaMask extension build distribution (typically for MV2 builds, omit for MV3)', + type: 'string', }), ); - const { buildType, buildVersion, org, project } = argv; + const { buildType, buildVersion, dist, org, project } = argv; process.env.SENTRY_ORG = org; process.env.SENTRY_PROJECT = project; @@ -75,19 +80,17 @@ async function start() { ]); } - // check if version has artifacts or not - const versionHasArtifacts = - versionAlreadyExists && (await checkIfVersionHasArtifacts(version)); - if (versionHasArtifacts) { - console.log( - `Version "${version}" already has artifacts on Sentry, skipping sourcemap upload`, - ); - return; - } - const additionalUploadArgs = []; + if (dist) { + additionalUploadArgs.push('--dist', dist); + } if (buildType !== loadBuildTypesConfig().default) { - additionalUploadArgs.push('--dist-directory', `dist-${buildType}`); + additionalUploadArgs.push( + '--dist-directory', + dist ? `dist-${buildType}-${dist}` : `dist-${buildType}`, + ); + } else if (dist) { + additionalUploadArgs.push('--dist-directory', `dist-${dist}`); } // upload sentry source and sourcemaps await runInShell('./development/sentry-upload-artifacts.sh', [ @@ -109,17 +112,6 @@ async function checkIfVersionExists(version) { ); } -async function checkIfVersionHasArtifacts(version) { - const [artifact] = await runCommand('sentry-cli', [ - 'releases', - 'files', - version, - 'list', - ]); - // When there's no artifacts, we get a response from the shell like this ['', ''] - return artifact?.length > 0; -} - async function doesNotFail(asyncFn) { try { await asyncFn(); diff --git a/development/sentry-upload-artifacts.sh b/development/sentry-upload-artifacts.sh index 7b712f12de31..d55e8172ba3e 100755 --- a/development/sentry-upload-artifacts.sh +++ b/development/sentry-upload-artifacts.sh @@ -23,6 +23,7 @@ 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) + -d, --dist Sentry distribution (typically used to identify MV2 builds) --dist-directory The 'dist' directory to use. Defaults to 'dist'. EOF } @@ -30,13 +31,15 @@ EOF function upload_sourcemaps { local release="${1}"; shift local dist_directory="${1}"; shift + local dist="${1}"; shift - sentry-cli releases files "${release}" upload-sourcemaps "${dist_directory}"/chrome/ "${dist_directory}"/sourcemaps/ --rewrite --url-prefix '/metamask' + sentry-cli releases files "${release}" upload-sourcemaps --dist "${dist}" "${dist_directory}"/chrome/ "${dist_directory}"/sourcemaps/ --rewrite --url-prefix '/metamask' } function main { local release=VERSION local dist_directory='dist' + local dist="mv3" while :; do case "${1-default}" in @@ -54,6 +57,16 @@ function main { release="${2}" shift ;; + -d|--dist) + if [[ -z $2 ]] + then + printf "'dist' option requires an argument.\\n" >&2 + printf '%s\n' "${__SEE_HELP_MESSAGE__}" >&2 + exit 1 + fi + dist="${2}" + shift + ;; --dist-directory) if [[ -z $2 ]] then @@ -83,7 +96,7 @@ function main { fi printf 'uploading source files and sourcemaps for Sentry release "%s"...\n' "${release}" - upload_sourcemaps "${release}" "${dist_directory}" + upload_sourcemaps "${release}" "${dist_directory}" "${dist}" printf 'all done!\n' } diff --git a/shared/modules/mv3.utils.js b/shared/modules/mv3.utils.js index 4307ebbd8920..e969c5b74228 100644 --- a/shared/modules/mv3.utils.js +++ b/shared/modules/mv3.utils.js @@ -1,18 +1,27 @@ -import browser from 'webextension-polyfill'; +const runtimeManifest = + global.chrome?.runtime.getManifest() || global.browser?.runtime.getManifest(); /** - * A boolean indicating whether the manifest of the current extension - * is set to manifest version 3. + * A boolean indicating whether the manifest of the current extension is set to manifest version 3. + * + * We have found that when this is run early in a service worker process, the runtime manifest is + * unavailable. That's why we have a fallback using the ENABLE_MV3 constant. The fallback is also + * used in unit tests. */ -export const isManifestV3 = - browser.runtime.getManifest().manifest_version === 3; +export const isManifestV3 = runtimeManifest + ? runtimeManifest.manifest_version === 3 + : // Our build system sets this as a boolean, but in a Node.js context (e.g. unit tests) it will + // always be a string + process.env.ENABLE_MV3 === true || + process.env.ENABLE_MV3 === 'true' || + process.env.ENABLE_MV3 === undefined; /** * A boolean indicating whether the browser supports the offscreen document api. * This is only available in when the manifest is version 3, and only in chromium * versions 109 and higher. As of June 7, 2024, it is not available in firefox. */ -export const isOffscreenAvailable = Boolean(browser.offscreen); +export const isOffscreenAvailable = Boolean(global.chrome?.offscreen); /** * A boolean indicating whether the current extension's manifest is version 3