@@ -7,6 +7,7 @@ import * as chalk from 'chalk';
77import * as fs from 'fs' ;
88import * as path from 'path' ;
99import { sync as resolveSync } from 'resolve' ;
10+ import type { Compiler } from 'webpack' ;
1011
1112import type { VercelCronsConfig } from '../common/types' ;
1213// Note: If you need to import a type from Webpack, do it in `types.ts` and export it from there. Otherwise, our
@@ -22,6 +23,7 @@ import type {
2223 WebpackConfigObjectWithModuleRules ,
2324 WebpackEntryProperty ,
2425 WebpackModuleRule ,
26+ WebpackPluginInstance ,
2527} from './types' ;
2628
2729const RUNTIME_TO_SDK_ENTRYPOINT_MAP = {
@@ -35,8 +37,8 @@ const RUNTIME_TO_SDK_ENTRYPOINT_MAP = {
3537let showedMissingAuthTokenErrorMsg = false ;
3638let showedMissingOrgSlugErrorMsg = false ;
3739let showedMissingProjectSlugErrorMsg = false ;
38- let showedMissingCLiBinaryErrorMsg = false ;
3940let showedHiddenSourceMapsWarningMsg = false ;
41+ let showedMissingCliBinaryWarningMsg = false ;
4042
4143// TODO: merge default SentryWebpackPlugin ignore with their SentryWebpackPlugin ignore or ignoreFile
4244// TODO: merge default SentryWebpackPlugin include with their SentryWebpackPlugin include
@@ -376,6 +378,7 @@ export function constructWebpackConfigFunction(
376378 const SentryWebpackPlugin = loadModule < SentryCliPlugin > ( '@sentry/webpack-plugin' ) ;
377379 if ( SentryWebpackPlugin ) {
378380 newConfig . plugins = newConfig . plugins || [ ] ;
381+ newConfig . plugins . push ( new SentryCliDownloadPlugin ( ) ) ;
379382 newConfig . plugins . push (
380383 // @ts -expect-error - this exists, the dynamic import just doesn't know about it
381384 new SentryWebpackPlugin (
@@ -739,6 +742,19 @@ export function getWebpackPluginOptions(
739742 if ( err ) {
740743 const errorMessagePrefix = `${ chalk . red ( 'error' ) } -` ;
741744
745+ if ( err . message . includes ( 'ENOENT' ) ) {
746+ if ( ! showedMissingCliBinaryWarningMsg ) {
747+ // eslint-disable-next-line no-console
748+ console . error (
749+ `\n${ errorMessagePrefix } ${ chalk . bold (
750+ 'The Sentry binary to upload sourcemaps could not be found.' ,
751+ ) } Source maps will not be uploaded. Please check that post-install scripts are enabled in your package manager when installing your dependencies and please run your build once without any caching to avoid caching issues of dependencies.\n`,
752+ ) ;
753+ showedMissingCliBinaryWarningMsg = true ;
754+ }
755+ return ;
756+ }
757+
742758 // Hardcoded way to check for missing auth token until we have a better way of doing this.
743759 if ( err . message . includes ( 'Authentication credentials were not provided.' ) ) {
744760 let msg ;
@@ -835,30 +851,6 @@ function shouldEnableWebpackPlugin(buildContext: BuildContext, userSentryOptions
835851 const { isServer } = buildContext ;
836852 const { disableServerWebpackPlugin, disableClientWebpackPlugin } = userSentryOptions ;
837853
838- /** Non-negotiable */
839-
840- // This check is necessary because currently, `@sentry/cli` uses a post-install script to download an
841- // architecture-specific version of the `sentry-cli` binary. If `yarn install`, `npm install`, or `npm ci` are run
842- // with the `--ignore-scripts` option, this will be blocked and the missing binary will cause an error when users
843- // try to build their apps.
844- const SentryWebpackPlugin = loadModule < SentryCliPlugin > ( '@sentry/webpack-plugin' ) ;
845-
846- // @ts -expect-error - this exists, the dynamic import just doesn't know it
847- if ( ! SentryWebpackPlugin || ! SentryWebpackPlugin . cliBinaryExists ( ) ) {
848- if ( ! showedMissingCLiBinaryErrorMsg ) {
849- // eslint-disable-next-line no-console
850- console . error (
851- `${ chalk . red ( 'error' ) } - ${ chalk . bold (
852- 'Sentry CLI binary not found.' ,
853- ) } Source maps will not be uploaded. Please check that postinstall scripts are enabled in your package manager when installing your dependencies and please run your build once without any caching to avoid caching issues of dependencies.\n`,
854- ) ;
855- showedMissingCLiBinaryErrorMsg = true ;
856- }
857- return false ;
858- }
859-
860- /** User override */
861-
862854 if ( isServer && disableServerWebpackPlugin !== undefined ) {
863855 return ! disableServerWebpackPlugin ;
864856 } else if ( ! isServer && disableClientWebpackPlugin !== undefined ) {
@@ -1047,3 +1039,54 @@ function getRequestAsyncStorageModuleLocation(
10471039
10481040 return undefined ;
10491041}
1042+
1043+ let downloadingCliAttempted = false ;
1044+
1045+ class SentryCliDownloadPlugin implements WebpackPluginInstance {
1046+ public apply ( compiler : Compiler ) : void {
1047+ compiler . hooks . beforeRun . tapAsync ( 'SentryCliDownloadPlugin' , ( compiler , callback ) => {
1048+ const SentryWebpackPlugin = loadModule < SentryCliPlugin > ( '@sentry/webpack-plugin' ) ;
1049+ if ( ! SentryWebpackPlugin ) {
1050+ // Pretty much an invariant.
1051+ return callback ( ) ;
1052+ }
1053+
1054+ // @ts -expect-error - this exists, the dynamic import just doesn't know it
1055+ if ( SentryWebpackPlugin . cliBinaryExists ( ) ) {
1056+ return callback ( ) ;
1057+ }
1058+
1059+ if ( ! downloadingCliAttempted ) {
1060+ downloadingCliAttempted = true ;
1061+ // eslint-disable-next-line no-console
1062+ console . log (
1063+ `\n${ chalk . cyan ( 'info' ) } - ${ chalk . bold (
1064+ 'Sentry binary to upload source maps not found.' ,
1065+ ) } Package manager post-install scripts are likely disabled or there is a caching issue. Manually downloading instead...`,
1066+ ) ;
1067+
1068+ // @ts -expect-error - this exists, the dynamic import just doesn't know it
1069+ const cliDownloadPromise : Promise < void > = SentryWebpackPlugin . downloadCliBinary ( {
1070+ log : ( ) => {
1071+ // No logs from directly from CLI
1072+ } ,
1073+ } ) ;
1074+
1075+ cliDownloadPromise . then (
1076+ ( ) => {
1077+ // eslint-disable-next-line no-console
1078+ console . log ( `${ chalk . cyan ( 'info' ) } - Sentry binary was successfully downloaded.\n` ) ;
1079+ return callback ( ) ;
1080+ } ,
1081+ e => {
1082+ // eslint-disable-next-line no-console
1083+ console . error ( `${ chalk . red ( 'error' ) } - Sentry binary download failed:` , e ) ;
1084+ return callback ( ) ;
1085+ } ,
1086+ ) ;
1087+ } else {
1088+ return callback ( ) ;
1089+ }
1090+ } ) ;
1091+ }
1092+ }
0 commit comments