-
Notifications
You must be signed in to change notification settings - Fork 50
feat(core): Allow multi-project sourcemaps upload #813
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
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -94,7 +94,8 @@ function createCliInstance(options: NormalizedOptions): SentryCli { | |||||
| return new SentryCli(null, { | ||||||
| authToken: options.authToken, | ||||||
| org: options.org, | ||||||
| project: options.project, | ||||||
| // Default to the first project if multiple projects are specified | ||||||
| project: Array.isArray(options.project) ? options.project[0] : options.project, | ||||||
| silent: options.silent, | ||||||
| url: options.url, | ||||||
| vcsRemote: options.release.vcsRemote, | ||||||
|
|
@@ -360,7 +361,12 @@ export function createSentryBuildPluginManager( | |||||
| if (typeof options.moduleMetadata === "function") { | ||||||
| const args = { | ||||||
| org: options.org, | ||||||
| project: options.project, | ||||||
| project: Array.isArray(options.project) ? options.project[0] : options.project, | ||||||
| projects: Array.isArray(options.project) | ||||||
| ? options.project | ||||||
| : options.project | ||||||
| ? [options.project] | ||||||
| : undefined, | ||||||
| release: options.release.name, | ||||||
| }; | ||||||
| // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment | ||||||
|
|
@@ -444,7 +450,10 @@ export function createSentryBuildPluginManager( | |||||
| getTurborepoEnvPassthroughWarning("SENTRY_ORG") | ||||||
| ); | ||||||
| return; | ||||||
| } else if (!options.project) { | ||||||
| } else if ( | ||||||
| !options.project || | ||||||
| (Array.isArray(options.project) && options.project.length === 0) | ||||||
| ) { | ||||||
| logger.warn( | ||||||
| "No project provided. Will not create release. Please set the `project` option to your Sentry project slug." + | ||||||
| getTurborepoEnvPassthroughWarning("SENTRY_PROJECT") | ||||||
|
|
@@ -481,6 +490,9 @@ export function createSentryBuildPluginManager( | |||||
| await cliInstance.releases.uploadSourceMaps(options.release.name, { | ||||||
| include: normalizedInclude, | ||||||
| dist: options.release.dist, | ||||||
| // @ts-expect-error - projects is not a valid option for uploadSourceMaps but is implemented in the CLI | ||||||
| // Remove once https://github.com/getsentry/sentry-cli/pull/2856 is released | ||||||
| projects: Array.isArray(options.project) ? options.project : [options.project], | ||||||
| // We want this promise to throw if the sourcemaps fail to upload so that we know about it. | ||||||
| // see: https://github.com/getsentry/sentry-cli/pull/2605 | ||||||
| live: "rejectOnError", | ||||||
|
|
@@ -625,6 +637,9 @@ export function createSentryBuildPluginManager( | |||||
| }, | ||||||
| ], | ||||||
| ignore: ignorePaths, | ||||||
| // @ts-expect-error - projects is not a valid option for uploadSourceMaps but is implemented in the CLI | ||||||
| // Remove once https://github.com/getsentry/sentry-cli/pull/2856 is released | ||||||
| projects: Array.isArray(options.project) ? options.project : [options.project], | ||||||
| live: "rejectOnError", | ||||||
| }); | ||||||
| }); | ||||||
|
|
@@ -735,6 +750,11 @@ export function createSentryBuildPluginManager( | |||||
| dist: options.release.dist, | ||||||
| }, | ||||||
| ], | ||||||
| // @ts-expect-error - projects is not a valid option for uploadSourceMaps but is implemented in the CLI | ||||||
| // Remove once https://github.com/getsentry/sentry-cli/pull/2856 is released | ||||||
| projects: Array.isArray(options.project) | ||||||
| ? options.project | ||||||
| : [options.project], | ||||||
| live: "rejectOnError", | ||||||
| } | ||||||
| ); | ||||||
|
|
@@ -843,7 +863,7 @@ function canUploadSourceMaps( | |||||
| ); | ||||||
| return false; | ||||||
| } | ||||||
| if (!options.project) { | ||||||
| if (!options.project || (Array.isArray(options.project) && options.project.length === 0)) { | ||||||
|
||||||
| if (!options.project || (Array.isArray(options.project) && options.project.length === 0)) { | |
| if (!getFirstProject(options.project)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated to use !getProjects(options.project)?.[0]
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -12,7 +12,7 @@ import { determineReleaseName } from "./utils"; | |
|
|
||
| export type NormalizedOptions = { | ||
| org: string | undefined; | ||
| project: string | undefined; | ||
| project: string | string[] | undefined; | ||
| authToken: string | undefined; | ||
| url: string; | ||
| headers: Record<string, string> | undefined; | ||
|
|
@@ -89,7 +89,9 @@ export const SENTRY_SAAS_URL = "https://sentry.io"; | |
| export function normalizeUserOptions(userOptions: UserOptions): NormalizedOptions { | ||
| const options = { | ||
| org: userOptions.org ?? process.env["SENTRY_ORG"], | ||
| project: userOptions.project ?? process.env["SENTRY_PROJECT"], | ||
| project: userOptions.project ?? (process.env["SENTRY_PROJECT"]?.includes(',') | ||
| ? process.env["SENTRY_PROJECT"].split(',').map(p => p.trim()) | ||
| : process.env["SENTRY_PROJECT"]), | ||
| authToken: userOptions.authToken ?? process.env["SENTRY_AUTH_TOKEN"], | ||
| url: userOptions.url ?? process.env["SENTRY_URL"] ?? SENTRY_SAAS_URL, | ||
| headers: userOptions.headers, | ||
|
Comment on lines
89
to
99
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Potential bug: An invalid
|
||
|
|
@@ -209,5 +211,26 @@ export function validateOptions(options: NormalizedOptions, logger: Logger): boo | |
| return false; | ||
| } | ||
|
|
||
| if (options.project) { | ||
|
||
| if (Array.isArray(options.project)) { | ||
| if (options.project.length === 0) { | ||
| logger.error( | ||
| "The `project` option was specified as an array but is empty.", | ||
| "Please provide at least one project slug." | ||
| ); | ||
| return false; | ||
| } | ||
| // Check each project is a non-empty string | ||
| const invalidProjects = options.project.filter(p => typeof p !== 'string' || p.trim() === ''); | ||
| if (invalidProjects.length > 0) { | ||
| logger.error( | ||
| "The `project` option contains invalid project slugs.", | ||
| "All projects must be non-empty strings." | ||
| ); | ||
| return false; | ||
| } | ||
| } | ||
| } | ||
|
|
||
| return true; | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
l: There is a lot of code duplication like that, which would make future development harder as we need to know to implement it like that. We could make a function for that, reuse it and write a simple unit test for it (btw this line already differs from the ones below).
E.g.
getProjectsandgetFirstProjectThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, good point. I added
getProjectsbut opted to just use optionals for the first project.