You've already forked sonarqube-community-branch-plugin
mirror of
https://github.com/mc1arke/sonarqube-community-branch-plugin.git
synced 2025-10-08 22:52:13 +02:00
#1115: Differentiate Gitlab pipelines on monorepos
The Gitlab decorator used a constant name for the pipeline which meant the last executed pipeline in a monorepo may allow a Merge Request to be marked as successful even if other projects in the repository had failed their pipelines. To overcome this the decorator has been altered to include the project key in the pipeline name if the project is a monorepo to ensure that the pipeline is unique across all projects in the monorepo.
This commit is contained in:
committed by
Michael Clarke
parent
7085d58013
commit
9e5caf732b
@@ -111,7 +111,7 @@ public abstract class DiscussionAwarePullRequestDecorator<C, P, U, D, N> impleme
|
||||
|
||||
AnalysisSummary analysisSummary = reportGenerator.createAnalysisSummary(analysis);
|
||||
submitSummaryNote(client, pullRequest, analysis, analysisSummary);
|
||||
submitPipelineStatus(client, pullRequest, analysis, analysisSummary);
|
||||
submitPipelineStatus(client, pullRequest, analysis, analysisSummary, projectAlmSettingDto);
|
||||
|
||||
DecorationResult.Builder builder = DecorationResult.builder();
|
||||
createFrontEndUrl(pullRequest, analysis).ifPresent(builder::withPullRequestUrl);
|
||||
@@ -130,7 +130,7 @@ public abstract class DiscussionAwarePullRequestDecorator<C, P, U, D, N> impleme
|
||||
|
||||
protected abstract List<String> getCommitIdsForPullRequest(C client, P pullRequest);
|
||||
|
||||
protected abstract void submitPipelineStatus(C client, P pullRequest, AnalysisDetails analysis, AnalysisSummary analysisSummary);
|
||||
protected abstract void submitPipelineStatus(C client, P pullRequest, AnalysisDetails analysis, AnalysisSummary analysisSummary, ProjectAlmSettingDto projectAlmSettingDto);
|
||||
|
||||
protected abstract void submitCommitNoteForIssue(C client, P pullRequest, PostAnalysisIssueVisitor.ComponentIssue issue, String filePath,
|
||||
AnalysisDetails analysis, AnalysisIssueSummary analysisIssueSummary);
|
||||
|
@@ -144,7 +144,7 @@ public class AzureDevOpsPullRequestDecorator extends DiscussionAwarePullRequestD
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void submitPipelineStatus(AzureDevopsClient client, PullRequest pullRequest, AnalysisDetails analysis, AnalysisSummary analysisSummary) {
|
||||
protected void submitPipelineStatus(AzureDevopsClient client, PullRequest pullRequest, AnalysisDetails analysis, AnalysisSummary analysisSummary, ProjectAlmSettingDto projectAlmSettingDto) {
|
||||
try {
|
||||
GitPullRequestStatus gitPullRequestStatus = new GitPullRequestStatus(
|
||||
GitStatusStateMapper.toGitStatusState(analysis.getQualityGateStatus()),
|
||||
|
@@ -122,14 +122,15 @@ public class GitlabMergeRequestDecorator extends DiscussionAwarePullRequestDecor
|
||||
|
||||
@Override
|
||||
protected void submitPipelineStatus(GitlabClient gitlabClient, MergeRequest mergeRequest, AnalysisDetails analysis,
|
||||
AnalysisSummary analysisSummary) {
|
||||
AnalysisSummary analysisSummary, ProjectAlmSettingDto projectAlmSettingDto) {
|
||||
Long pipelineId = analysis.getScannerProperty(PULLREQUEST_GITLAB_PIPELINE_ID)
|
||||
.map(Long::parseLong)
|
||||
.orElse(null);
|
||||
|
||||
try {
|
||||
PipelineStatus pipelineStatus = new PipelineStatus("SonarQube",
|
||||
"SonarQube Status",
|
||||
boolean isMonorepo = Boolean.TRUE.equals(projectAlmSettingDto.getMonorepo());
|
||||
PipelineStatus pipelineStatus = new PipelineStatus("SonarQube" + (isMonorepo ? " - " + analysis.getAnalysisProjectKey() : ""),
|
||||
"SonarQube Status" + (isMonorepo ? " - " + analysis.getAnalysisProjectName() : ""),
|
||||
analysis.getQualityGateStatus() == QualityGate.Status.OK ? PipelineStatus.State.SUCCESS : PipelineStatus.State.FAILED,
|
||||
analysisSummary.getDashboardUrl(),
|
||||
analysisSummary.getNewCoverage(),
|
||||
|
@@ -73,20 +73,21 @@ class GitlabMergeRequestDecoratorIntegrationTest {
|
||||
|
||||
@Test
|
||||
void decorateQualityGateStatusOk() {
|
||||
decorateQualityGateStatus(QualityGate.Status.OK);
|
||||
decorateQualityGateStatus(QualityGate.Status.OK, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
void decorateQualityGateStatusError() {
|
||||
decorateQualityGateStatus(QualityGate.Status.ERROR);
|
||||
decorateQualityGateStatus(QualityGate.Status.ERROR, true);
|
||||
}
|
||||
|
||||
private void decorateQualityGateStatus(QualityGate.Status status) {
|
||||
private void decorateQualityGateStatus(QualityGate.Status status, boolean isMonorepo) {
|
||||
String user = "sonar_user";
|
||||
String repositorySlug = "repo/slug";
|
||||
String commitSha = "commitSha";
|
||||
long mergeRequestIid = 6;
|
||||
String projectKey = "projectKey";
|
||||
String projectName = "project name";
|
||||
String sonarRootUrl = "http://sonar:9000/sonar";
|
||||
String discussionId = "6a9c1750b37d513a43987b574953fceb50b03ce7";
|
||||
String noteId = "1126";
|
||||
@@ -95,16 +96,18 @@ class GitlabMergeRequestDecoratorIntegrationTest {
|
||||
int lineNumber = 5;
|
||||
|
||||
ProjectAlmSettingDto projectAlmSettingDto = mock();
|
||||
when(projectAlmSettingDto.getAlmRepo()).thenReturn(repositorySlug);
|
||||
when(projectAlmSettingDto.getMonorepo()).thenReturn(isMonorepo);
|
||||
|
||||
AlmSettingDto almSettingDto = mock();
|
||||
when(almSettingDto.getDecryptedPersonalAccessToken(any())).thenReturn("token");
|
||||
when(almSettingDto.getUrl()).thenReturn(wireMockExtension.baseUrl() + "/api/v4");
|
||||
|
||||
AnalysisDetails analysisDetails = mock();
|
||||
when(almSettingDto.getUrl()).thenReturn(wireMockExtension.baseUrl() + "/api/v4");
|
||||
when(projectAlmSettingDto.getAlmRepo()).thenReturn(repositorySlug);
|
||||
when(projectAlmSettingDto.getMonorepo()).thenReturn(true);
|
||||
when(analysisDetails.getQualityGateStatus()).thenReturn(status);
|
||||
when(analysisDetails.getAnalysisProjectKey()).thenReturn(projectKey);
|
||||
when(analysisDetails.getAnalysisProjectName()).thenReturn(projectName);
|
||||
when(analysisDetails.getPullRequestId()).thenReturn(Long.toString(mergeRequestIid));
|
||||
when(analysisDetails.getCommitSha()).thenReturn(commitSha);
|
||||
|
||||
@@ -215,9 +218,15 @@ class GitlabMergeRequestDecoratorIntegrationTest {
|
||||
.withRequestBody(equalTo("body=" + urlEncode("This issue no longer exists in SonarQube, but due to other comments being present in this discussion, the discussion is not being being closed automatically. Please manually resolve this discussion once the other comments have been reviewed.")))
|
||||
.willReturn(created()));
|
||||
|
||||
wireMockExtension.stubFor(post(urlEqualTo("/api/v4/projects/" + sourceProjectId + "/statuses/" + commitSha + "?state=" + (status == QualityGate.Status.OK ? "success" : "failed")))
|
||||
.withRequestBody(equalTo("name=SonarQube&target_url=" + urlEncode(sonarRootUrl + "/dashboard?id=" + projectKey + "&pullRequest=" + mergeRequestIid) + "&description=SonarQube+Status&coverage=10"))
|
||||
.willReturn(created()));
|
||||
if (isMonorepo) {
|
||||
wireMockExtension.stubFor(post(urlEqualTo("/api/v4/projects/" + sourceProjectId + "/statuses/" + commitSha + "?state=" + (status == QualityGate.Status.OK ? "success" : "failed")))
|
||||
.withRequestBody(equalTo("name=SonarQube+-+projectKey&target_url=" + urlEncode(sonarRootUrl + "/dashboard?id=" + projectKey + "&pullRequest=" + mergeRequestIid) + "&description=SonarQube+Status+-+project+name&coverage=10"))
|
||||
.willReturn(created()));
|
||||
} else {
|
||||
wireMockExtension.stubFor(post(urlEqualTo("/api/v4/projects/" + sourceProjectId + "/statuses/" + commitSha + "?state=" + (status == QualityGate.Status.OK ? "success" : "failed")))
|
||||
.withRequestBody(equalTo("name=SonarQube&target_url=" + urlEncode(sonarRootUrl + "/dashboard?id=" + projectKey + "&pullRequest=" + mergeRequestIid) + "&description=SonarQube+Status&coverage=10"))
|
||||
.willReturn(created()));
|
||||
}
|
||||
|
||||
wireMockExtension.stubFor(post(urlPathEqualTo("/api/v4/projects/" + sourceProjectId + "/merge_requests/" + mergeRequestIid + "/discussions"))
|
||||
.withRequestBody(equalTo("body=summary+comm%C3%A9nt%0A%0A%5Blink+text%5D"))
|
||||
@@ -244,6 +253,13 @@ class GitlabMergeRequestDecoratorIntegrationTest {
|
||||
.willReturn(ok())
|
||||
);
|
||||
|
||||
if (!isMonorepo) {
|
||||
wireMockExtension.stubFor(put(urlPathEqualTo("/api/v4/projects/" + sourceProjectId + "/merge_requests/" + mergeRequestIid + "/discussions/" + discussionId + 7))
|
||||
.withQueryParam("resolved", equalTo("true"))
|
||||
.willReturn(ok())
|
||||
);
|
||||
}
|
||||
|
||||
LinkHeaderReader linkHeaderReader = mock();
|
||||
Settings settings = mock();
|
||||
Encryption encryption = mock();
|
||||
|
Reference in New Issue
Block a user