@@ -455,6 +455,82 @@ describe('sentry-xcode.sh', () => {
455455 expect ( result . stdout ) . toContain ( 'skipping sourcemaps upload' ) ;
456456 } ) ;
457457
458+ describe ( 'SENTRY_PROJECT_ROOT override' , ( ) => {
459+ it ( 'resolves SOURCEMAP_FILE relative to SENTRY_PROJECT_ROOT instead of PROJECT_DIR/..' , ( ) => {
460+ const customRoot = path . join ( tempDir , 'monorepo-package' ) ;
461+ fs . mkdirSync ( customRoot , { recursive : true } ) ;
462+
463+ const echoScript = path . join ( tempDir , 'mock-sentry-cli-echo-sourcemap.js' ) ;
464+ fs . writeFileSync (
465+ echoScript ,
466+ `
467+ const sourcemapFile = process.env.SOURCEMAP_FILE || 'not-set';
468+ console.log('SOURCEMAP_FILE=' + sourcemapFile);
469+ process.exit(0);
470+ ` ,
471+ ) ;
472+
473+ const result = runScript ( {
474+ SENTRY_PROJECT_ROOT : customRoot ,
475+ SENTRY_CLI_EXECUTABLE : echoScript ,
476+ SOURCEMAP_FILE : 'relative/path.map' ,
477+ } ) ;
478+
479+ const expectedPath = path . join ( customRoot , 'relative/path.map' ) ;
480+ expect ( result . exitCode ) . toBe ( 0 ) ;
481+ expect ( result . stdout ) . toContain ( `SOURCEMAP_FILE=${ expectedPath } ` ) ;
482+ } ) ;
483+
484+ it ( 'resolves SOURCEMAP_FILE relative to PROJECT_DIR/.. when SENTRY_PROJECT_ROOT is not set' , ( ) => {
485+ const echoScript = path . join ( tempDir , 'mock-sentry-cli-echo-sourcemap.js' ) ;
486+ fs . writeFileSync (
487+ echoScript ,
488+ `
489+ const sourcemapFile = process.env.SOURCEMAP_FILE || 'not-set';
490+ console.log('SOURCEMAP_FILE=' + sourcemapFile);
491+ process.exit(0);
492+ ` ,
493+ ) ;
494+
495+ const result = runScript ( {
496+ SENTRY_CLI_EXECUTABLE : echoScript ,
497+ SOURCEMAP_FILE : 'relative/path.map' ,
498+ } ) ;
499+
500+ // Without SENTRY_PROJECT_ROOT, falls back to PROJECT_DIR/..
501+ const projectRoot = path . dirname ( tempDir ) ;
502+ const expectedPath = path . join ( projectRoot , 'relative/path.map' ) ;
503+ expect ( result . exitCode ) . toBe ( 0 ) ;
504+ expect ( result . stdout ) . toContain ( `SOURCEMAP_FILE=${ expectedPath } ` ) ;
505+ } ) ;
506+
507+ it ( 'finds sentry.options.json in SENTRY_PROJECT_ROOT' , ( ) => {
508+ const customRoot = path . join ( tempDir , 'monorepo-package' ) ;
509+ fs . mkdirSync ( customRoot , { recursive : true } ) ;
510+
511+ const optionsContent = JSON . stringify ( { dsn : 'https://key@sentry.io/123' } ) ;
512+ fs . writeFileSync ( path . join ( customRoot , 'sentry.options.json' ) , optionsContent ) ;
513+
514+ const buildDir = path . join ( tempDir , 'build' ) ;
515+ const resourcesPath = 'Resources' ;
516+ fs . mkdirSync ( path . join ( buildDir , resourcesPath ) , { recursive : true } ) ;
517+
518+ const result = runScript ( {
519+ SENTRY_PROJECT_ROOT : customRoot ,
520+ SENTRY_DISABLE_AUTO_UPLOAD : 'true' ,
521+ SENTRY_COPY_OPTIONS_FILE : 'true' ,
522+ CONFIGURATION_BUILD_DIR : buildDir ,
523+ UNLOCALIZED_RESOURCES_FOLDER_PATH : resourcesPath ,
524+ } ) ;
525+
526+ expect ( result . exitCode ) . toBe ( 0 ) ;
527+ expect ( result . stdout ) . toContain ( 'Copied' ) ;
528+ const destPath = path . join ( buildDir , resourcesPath , 'sentry.options.json' ) ;
529+ const copied = JSON . parse ( fs . readFileSync ( destPath , 'utf8' ) ) ;
530+ expect ( copied . dsn ) . toBe ( 'https://key@sentry.io/123' ) ;
531+ } ) ;
532+ } ) ;
533+
458534 describe ( 'sentry.options.json SENTRY_ENVIRONMENT override' , ( ) => {
459535 it ( 'copies file without modification when SENTRY_ENVIRONMENT is not set' , ( ) => {
460536 const optionsContent = JSON . stringify ( { dsn : 'https://key@sentry.io/123' , environment : 'production' } ) ;
0 commit comments