diff --git a/src/cli/core.ts b/src/cli/core.ts index 213ef04..2c0ef9c 100644 --- a/src/cli/core.ts +++ b/src/cli/core.ts @@ -57,7 +57,7 @@ export class Cli { this.sonarURL = this.argv.sonar.url ? this.argv.sonar.url : process.env.SONAR_URL; this.sonarToken = this.argv.sonar.token ? this.argv.sonar.token : process.env.SONAR_TOKEN; this.sonarProjectKey = this.argv.sonar.project_key ? this.argv.sonar.project_key : process.env.SONAR_PROJECT_KEY; - + if (!this.validate()) { process.exit(1); } @@ -124,7 +124,9 @@ export class Cli { const sonar = new Sonar({ tokenKey: this.sonarToken, host: this.sonarURL, - projectKey: this.sonarProjectKey + projectKey: this.sonarProjectKey, + branchPluginEnabled: this.argv.sonarBranchPlugin, + branchPluginMergeId: parseInt(this.gitMergeID) }); let gitMerge: GitMerge; diff --git a/src/cli/options.ts b/src/cli/options.ts index 7bcd42c..5b30118 100644 --- a/src/cli/options.ts +++ b/src/cli/options.ts @@ -13,6 +13,7 @@ export enum Provide { export interface Arguments { _: ArgsOutput; provide: Provide; + sonarBranchPlugin?: boolean; skipScanner?: boolean; define: (string | number)[] | undefined; git: { [key: string]: string }; @@ -41,6 +42,12 @@ export function createOptions() { desc: "Skip run sonar-scanner", default: false }) + .option("sonar-branch-plugin", { + alias: "b", + group: "Global Options:", + desc: "Enable SonarQube Community-Branch-Plugin support. Please make sure, that you've properly installed the plugin in SonarQube: https://github.com/mc1arke/sonarqube-community-branch-plugin", + default: false + }) .option("define", { alias: "D", requiresArg: true, diff --git a/src/quality-gate/core.ts b/src/quality-gate/core.ts index e050b2f..1b38e1a 100644 --- a/src/quality-gate/core.ts +++ b/src/quality-gate/core.ts @@ -1,7 +1,7 @@ import { Git, GitMerge, GitReviewParam } from "../git"; import { Sonar } from "../sonar"; -const INTERVAL_SECONDS = 60; +const INTERVAL_SECONDS = 300; declare global { interface Date { diff --git a/src/sonar/core.ts b/src/sonar/core.ts index f93132e..cf4d1b6 100644 --- a/src/sonar/core.ts +++ b/src/sonar/core.ts @@ -17,7 +17,13 @@ export class Sonar { qualityGate: SonarReport; config?: SonarProperties; - constructor(opt: { tokenKey: string; host: string; projectKey: string }) { + constructor(opt: { + tokenKey: string; + host: string; + projectKey: string; + branchPluginEnabled?: boolean; + branchPluginMergeId?: number; + }) { try { this.config = new SonarProperties({ projectDir: process.cwd() }); this.host = this.config.getSonarURL(); @@ -30,6 +36,8 @@ export class Sonar { this.qualityGate = new SonarReport({ host: this.host, projectKey: this.projectKey, + branchPluginEnabled: opt.branchPluginEnabled, + branchPluginMergeId: opt.branchPluginMergeId, }); const headers = { @@ -39,10 +47,18 @@ export class Sonar { } async getQualityStatus() { + const parameters: entity.SonarApiRequestParameters = { + projectKey: this.projectKey, + } + + if (this.qualityGate.branchPluginEnabled) { + parameters.pullRequest = this.qualityGate.branchPluginMergeId; + } + Log.debug("sonar get quality status", SONAR_QUALITY_API); const response = await this.http.get( SONAR_QUALITY_API, - { projectKey: this.projectKey } + parameters ); return response.data; } @@ -57,13 +73,19 @@ export class Sonar { } private async findIssuesByPage(fromTime: string, page: number) { - const response = await this.http.get(SONAR_ISSUE_API, { + const parameters: entity.SonarApiRequestParameters = { componentKeys: this.projectKey, - createdAfter: fromTime, // sinceLeakPeriod: true, // get issues of new code on sonar p: page, ps: PAGE_SIZE, - }); + createdAfter: fromTime, + }; + + if (this.qualityGate.branchPluginEnabled) { + parameters.pullRequest = this.qualityGate.branchPluginMergeId; + } + + const response = await this.http.get(SONAR_ISSUE_API, parameters); return response.data; } diff --git a/src/sonar/entity.ts b/src/sonar/entity.ts index 23bc5a5..f440602 100644 --- a/src/sonar/entity.ts +++ b/src/sonar/entity.ts @@ -55,3 +55,13 @@ export interface Task { export interface Tasks { tasks: Task[]; } + +export interface SonarApiRequestParameters { + projectKey?: string; + componentKeys?: string; + sinceLeakPeriod?: boolean; + createdAfter?: string; + pullRequest?: number; + p?: number; + ps?: number; +} diff --git a/src/sonar/report.ts b/src/sonar/report.ts index 7a36ea6..11cef82 100644 --- a/src/sonar/report.ts +++ b/src/sonar/report.ts @@ -6,12 +6,18 @@ const IMAGE_DIR_LINK = "https://hsonar.s3.ap-southeast-1.amazonaws.com/images/"; export class SonarReport { host?: string; projectKey?: string; + branchPluginEnabled?: boolean; + branchPluginMergeId?: number; constructor(opt: { host?: string; projectKey?: string; + branchPluginEnabled?: boolean; + branchPluginMergeId?: number; }) { this.host = opt.host; this.projectKey = opt.projectKey; + this.branchPluginEnabled = opt.branchPluginEnabled; + this.branchPluginMergeId = opt.branchPluginMergeId; } private capitalize(text: string) { @@ -57,12 +63,22 @@ export class SonarReport { return level[val]; } + private appendPullRequestIdIfBranchPluginEnabled(url: string) { + if (this.branchPluginEnabled) { + return `${url}&pullRequest=${this.branchPluginMergeId}` + } + + return url; + } + private getIssueURL(type: string) { - return this.host + `/project/issues?id=${this.projectKey}&resolved=false&sinceLeakPeriod=true&types=${type}`; + const url = this.host + `/project/issues?id=${this.projectKey}&resolved=false&sinceLeakPeriod=true&types=${type}`; + return this.appendPullRequestIdIfBranchPluginEnabled(url); } private getMetricURL(metric: string) { - return this.host + `/project/issues?id=${this.projectKey}&metric=${metric}&view=list`; + const url = this.host + `/project/issues?id=${this.projectKey}&metric=${metric}&view=list`; + return this.appendPullRequestIdIfBranchPluginEnabled(url); } private getIssueSecurity(projectStatus: ProjectStatus) { @@ -121,7 +137,7 @@ export class SonarReport { status = "failed"; } - const report = `# SonarQube Code Analytics + const report = `# SonarQube Code Analytics ## Quality Gate ${status} ${this.icon(status)}