-
Notifications
You must be signed in to change notification settings - Fork 119
Fix Scorecard SonarQube "Open Issues" metric pulling #4274
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 all commits
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 |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| --- | ||
| '@red-hat-developer-hub/backstage-plugin-scorecard-backend-module-sonarqube': patch | ||
| --- | ||
|
|
||
| Resolve issue for `sonarqube.openIssues` Scorecard SonarQube metric when the project is inaccessible. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -107,14 +107,29 @@ export class SonarQubeClient { | |
| projectKey: string, | ||
| instanceName?: string, | ||
| ): Promise<number> { | ||
| this.logger.debug(`Fetching open issues count for project ${projectKey}`); | ||
| const data = await this.fetchApi( | ||
| `/api/issues/search?componentKeys=${encodeURIComponent( | ||
| projectKey, | ||
| )}&statuses=OPEN,CONFIRMED,REOPENED&ps=1`, | ||
| instanceName, | ||
| ); | ||
| return data.total; | ||
| this.logger.debug(`Fetching open issues count for project ${projectKey}`); | ||
|
|
||
| // Additional check to ensure the project is accessible | ||
| try { | ||
|
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. [low] indentation The method body of getOpenIssuesCount is indented at 6 spaces, while every other method in this class uses 4 spaces. This inconsistency was introduced by the diff. Suggested fix: Re-indent the entire getOpenIssuesCount method body to use 4-space indentation, matching the sibling methods. 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. [low] intent-clarity The pre-flight call to /api/components/show runs on every invocation, adding latency and load to the happy path. The changeset describes fixing an issue when the project is inaccessible but the implementation adds overhead to all calls. |
||
| await this.fetchApi( | ||
| `/api/components/show?component=${encodeURIComponent(projectKey)}`, | ||
| instanceName, | ||
| ); | ||
| } | ||
| catch { | ||
| throw new Error( | ||
| `SonarQube project '${projectKey}' is not accessible or the project key is missing or invalid`, | ||
|
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. [medium] error handling The bare catch block around the project-access check swallows all errors indiscriminately and replaces them with a misleading project is not accessible message. This catches not only HTTP 4xx responses (the intended case) but also: (1) configuration errors from resolveInstance (e.g., SonarQube instance unknown not found in configuration would be masked), (2) network failures, (3) server errors (HTTP 500/503). For case (1), this is a behavioral regression — before this change, passing an invalid instanceName would throw a clear configuration error; now it throws a misleading project not accessible error. Suggested fix: Narrow the catch to only handle the fetchApi HTTP error case. Check if (error instanceof Error && error.message.includes(SonarQube API error)) and only rethrow the project-accessibility message for that case, re-throwing the original error otherwise. |
||
| ); | ||
| } | ||
|
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. [low] brace placement The catch keyword is placed on a new line after the closing brace. The standard JavaScript/TypeScript convention (and what prettier enforces) is same-line style (} catch {). Suggested fix: Move catch onto the same line as the closing brace: } catch {. |
||
|
|
||
| const data = await this.fetchApi( | ||
| `/api/issues/search?componentKeys=${encodeURIComponent( | ||
| projectKey, | ||
| )}&statuses=OPEN,CONFIRMED,REOPENED&ps=1`, | ||
| instanceName, | ||
| ); | ||
|
|
||
| return data.paging?.total ?? data.total ?? 0; | ||
|
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. [medium] scope-creep The claimed intent is to handle inaccessible projects, but the change also silently alters return-value parsing from data.total to data.paging?.total ?? data.total ?? 0. This is a separate behavioral change not mentioned in the PR title, body, or changeset description. Suggested fix: Either revert the return expression to data.total if the pre-flight check alone solves the bug, or document why the parsing change was needed. |
||
| } | ||
|
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. [low] error handling / silent fallback data.paging?.total ?? data.total ?? 0 silently returns 0 when neither paging.total nor total is present in the API response. If the SonarQube API response structure changes unexpectedly, this will produce a silent 0 rather than a visible failure. |
||
|
|
||
| async getMeasures( | ||
|
|
||
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.
[low] test adequacy
The test throws when project access check fails only tests the HTTP 404 case. There is no test covering the scenario where an invalid instanceName is passed to getOpenIssuesCount — this would reveal the regression where the configuration error (instance not found) is now incorrectly masked as project not accessible.