package org.sonar.server.computation.task.projectanalysis.webhook;
import java.io.StringWriter;
+import java.io.UnsupportedEncodingException;
import java.io.Writer;
+import java.net.URLEncoder;
import java.util.Date;
import javax.annotation.Nullable;
import org.sonar.api.ce.ComputeEngineSide;
import org.sonar.api.utils.System2;
import org.sonar.api.utils.text.JsonWriter;
+import static java.lang.String.format;
import static org.sonar.core.config.WebhookProperties.ANALYSIS_PROPERTY_PREFIX;
@ComputeEngineSide
writeTask(writer, analysis.getCeTask());
writeDates(writer, analysis, system2);
writeProject(analysis, writer, analysis.getProject());
- analysis.getBranch().ifPresent(b -> writeBranch(writer, b));
+ analysis.getBranch().ifPresent(b -> writeBranch(writer, analysis.getProject(), b));
writeQualityGate(writer, analysis.getQualityGate());
writeAnalysisProperties(writer, analysis.getScannerContext());
writer.endObject().close();
.beginObject()
.prop("key", project.getKey())
.prop("name", analysis.getProject().getName())
+ .prop("url", projectUrlOf(project))
.endObject();
}
.prop("status", ceTask.getStatus().toString());
}
- private void writeBranch(JsonWriter writer, Branch branch) {
+ private void writeBranch(JsonWriter writer, Project project, Branch branch) {
writer
.name("branch")
.beginObject()
.prop("name", branch.getName().orElse(null))
.prop("type", branch.getType().name())
.prop("isMain", branch.isMain())
+ .prop("url", branchUrlOf(project, branch))
.endObject();
}
+ private String projectUrlOf(Project project) {
+ return format("%s/project/dashboard?id=%s", server.getPublicRootUrl(), encode(project.getKey()));
+ }
+
+ private String branchUrlOf(Project project, Branch branch) {
+ if (branch.getType() == Branch.Type.LONG) {
+ if (branch.isMain()) {
+ return projectUrlOf(project);
+ }
+ return format("%s/project/dashboard?branch=%s&id=%s",
+ server.getPublicRootUrl(), encode(branch.getName().orElse("")), encode(project.getKey()));
+ } else {
+ return format("%s/project/issues?branch=%s&id=%s&resolved=false",
+ server.getPublicRootUrl(), encode(branch.getName().orElse("")), encode(project.getKey()));
+ }
+ }
+
private static void writeQualityGate(JsonWriter writer, @Nullable QualityGate gate) {
if (gate != null) {
writer
.endObject();
}
}
+
+ private static String encode(String toEncode) {
+ try {
+ return URLEncoder.encode(toEncode, "UTF-8");
+ } catch (UnsupportedEncodingException e) {
+ throw new IllegalStateException("Encoding not supported", e);
+ }
+ }
}
" \"changedAt\": \"2017-07-14T04:40:00+0200\"," +
" \"project\": {" +
" \"key\": \"P1\"," +
- " \"name\": \"Project One\"" +
+ " \"name\": \"Project One\"," +
+ " \"url\": \"http://foo/project/dashboard?id=P1\"" +
" }," +
" \"qualityGate\": {" +
" \"name\": \"Gate One\"," +
" \"changedAt\": \"2017-07-14T04:40:00+0200\"," +
" \"project\": {" +
" \"key\": \"P1\"," +
- " \"name\": \"Project One\"" +
+ " \"name\": \"Project One\"," +
+ " \"url\": \"http://foo/project/dashboard?id=P1\"" +
" }," +
" \"qualityGate\": {" +
" \"name\": \"Gate One\"," +
" \"changedAt\": \"2017-07-14T04:40:00+0200\"," +
" \"project\": {" +
" \"key\": \"P1\"," +
- " \"name\": \"Project One\"" +
+ " \"name\": \"Project One\"," +
+ " \"url\": \"http://foo/project/dashboard?id=P1\"" +
" }," +
" \"qualityGate\": {" +
" \"name\": \"Gate One\"," +
" \"changedAt\": \"2017-07-14T04:40:00+0200\"," +
" \"project\": {" +
" \"key\": \"P1\"," +
- " \"name\": \"Project One\"" +
+ " \"name\": \"Project One\"," +
+ " \"url\": \"http://foo/project/dashboard?id=P1\"" +
" }," +
" \"properties\": {" +
" }" +
}
@Test
- public void create_payload_on_branch() {
+ public void create_payload_on_short_branch() {
CeTask task = newCeTaskBuilder()
.setStatus(CeTask.Status.SUCCESS)
.setId("#1")
PostProjectAnalysisTask.ProjectAnalysis analysis = newAnalysis(task, null, new BranchImpl(false, "feature/foo", Branch.Type.SHORT), 1_500_000_000_000L, emptyMap());
WebhookPayload payload = underTest.create(analysis);
- assertJson(payload.getJson()).isSimilarTo("{" +
- "\"branch\": {" +
- " \"name\": \"feature/foo\"" +
- " \"type\": \"SHORT\"" +
- " \"isMain\": false" +
- "}" +
- "}");
+ assertJson(payload.getJson())
+ .isSimilarTo("{" +
+ "\"branch\": {" +
+ " \"name\": \"feature/foo\"" +
+ " \"type\": \"SHORT\"" +
+ " \"isMain\": false," +
+ " \"url\": \"http://foo/project/issues?branch=feature%2Ffoo&id=P1&resolved=false\"" +
+ "}" +
+ "}");
+ }
+
+ @Test
+ public void create_payload_on_long_branch() {
+ CeTask task = newCeTaskBuilder()
+ .setStatus(CeTask.Status.SUCCESS)
+ .setId("#1")
+ .build();
+ PostProjectAnalysisTask.ProjectAnalysis analysis = newAnalysis(task, null, new BranchImpl(false, "feature/foo", Branch.Type.LONG), 1_500_000_000_000L, emptyMap());
+
+ WebhookPayload payload = underTest.create(analysis);
+ assertJson(payload.getJson())
+ .isSimilarTo("{" +
+ "\"branch\": {" +
+ " \"name\": \"feature/foo\"" +
+ " \"type\": \"LONG\"" +
+ " \"isMain\": false," +
+ " \"url\": \"http://foo/project/dashboard?branch=feature%2Ffoo&id=P1\"" +
+ "}" +
+ "}");
}
@Test
PostProjectAnalysisTask.ProjectAnalysis analysis = newAnalysis(task, null, new BranchImpl(true, null, Branch.Type.LONG), 1_500_000_000_000L, emptyMap());
WebhookPayload payload = underTest.create(analysis);
- assertJson(payload.getJson()).isSimilarTo("{" +
- "\"branch\": {" +
- " \"type\": \"LONG\"" +
- " \"isMain\": true" +
- "}" +
- "}");
+ assertJson(payload.getJson())
+ .isSimilarTo("{" +
+ "\"branch\": {" +
+ " \"type\": \"LONG\"" +
+ " \"isMain\": true," +
+ " \"url\": \"http://foo/project/dashboard?id=P1\"" +
+ "}" +
+ "}");
}
private static PostProjectAnalysisTask.ProjectAnalysis newAnalysis(CeTask task, @Nullable QualityGate gate,