Skip to content

Commit

Permalink
Add a custom value for the detected CI provider
Browse files Browse the repository at this point in the history
Closes gh-77
  • Loading branch information
wilkinsona committed Apr 25, 2024
1 parent e830ee8 commit 709fc65
Show file tree
Hide file tree
Showing 3 changed files with 156 additions and 59 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,6 @@
*/
class BuildScanConventions implements Action<BuildScanConfiguration> {

private static final String BAMBOO_RESULTS_ENV_VAR = "bamboo_resultsUrl";

private static final String CIRCLECI_BUILD_URL_ENV_VAR = "CIRCLE_BUILD_URL";

private final DevelocityConfiguration develocity;

private final ProcessRunner processRunner;
Expand All @@ -64,10 +60,11 @@ public void execute(BuildScanConfiguration buildScan) {
buildScan.obfuscation((obfuscation) -> obfuscation
.ipAddresses((addresses) -> addresses.stream().map((address) -> "0.0.0.0").collect(Collectors.toList())));
configurePublishing(buildScan);
tagBuildScan(buildScan);
ContinuousIntegration ci = ContinuousIntegration.detect(this.env);
tagBuildScan(buildScan, ci);
buildScan.background(this::addGitMetadata);
addCiMetadata(buildScan);
buildScan.getUploadInBackground().set(!isCi());
addCiMetadata(buildScan, ci);
buildScan.getUploadInBackground().set(ci == null);
buildScan.capture((settings) -> settings.getFileFingerprints().set(true));
}

Expand All @@ -82,41 +79,14 @@ protected void configurePublishing(BuildScanConfiguration buildScan) {
this.develocity.getServer().set("https://ge.spring.io");
}

private void tagBuildScan(BuildScanConfiguration buildScan) {
tagCiOrLocal(buildScan);
private void tagBuildScan(BuildScanConfiguration buildScan, ContinuousIntegration ci) {
tagCiOrLocal(buildScan, ci);
tagJdk(buildScan);
tagOperatingSystem(buildScan);
}

private void tagCiOrLocal(BuildScanConfiguration buildScan) {
buildScan.tag(isCi() ? "CI" : "Local");
}

private boolean isCi() {
if (isBamboo() || isCircleCi() || isConcourse() || isJenkins() || isGitHubActions()) {
return true;
}
return false;
}

private boolean isBamboo() {
return this.env.containsKey(BAMBOO_RESULTS_ENV_VAR);
}

private boolean isCircleCi() {
return this.env.containsKey(CIRCLECI_BUILD_URL_ENV_VAR);
}

private boolean isConcourse() {
return this.env.containsKey("CI");
}

private boolean isJenkins() {
return this.env.containsKey("JENKINS_URL");
}

private boolean isGitHubActions() {
return this.env.containsKey("GITHUB_ACTIONS");
private void tagCiOrLocal(BuildScanConfiguration buildScan, ContinuousIntegration ci) {
buildScan.tag((ci != null) ? "CI" : "Local");
}

private void tagJdk(BuildScanConfiguration buildScan) {
Expand Down Expand Up @@ -151,25 +121,15 @@ private void addGitMetadata(BuildScanConfiguration buildScan) {
});
}

private void addCiMetadata(BuildScanConfiguration buildScan) {
if (isBamboo()) {
buildScan.link("CI build", this.env.get(BAMBOO_RESULTS_ENV_VAR));
}
else if (isJenkins()) {
String buildUrl = this.env.get("BUILD_URL");
if (hasText(buildUrl)) {
buildScan.link("CI build", buildUrl);
}
}
else if (isCircleCi()) {
buildScan.link("CI build", this.env.get(CIRCLECI_BUILD_URL_ENV_VAR));
private void addCiMetadata(BuildScanConfiguration buildScan, ContinuousIntegration ci) {
if (ci == null) {
return;
}
else if (isGitHubActions()) {
String server = this.env.get("GITHUB_SERVER_URL");
String repository = this.env.get("GITHUB_REPOSITORY");
String runId = this.env.get("GITHUB_RUN_ID");
buildScan.link("CI build", server + "/" + repository + "/actions/runs/" + runId);
String buildUrl = ci.buildUrlFrom(this.env);
if (hasText(buildUrl)) {
buildScan.link("CI build", buildUrl);
}
buildScan.value("CI provider", ci.toString());
}

private RunResult getBranch() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/*
* Copyright 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package io.spring.ge.conventions.gradle;

import java.util.Map;
import java.util.function.Function;

/**
* Known continuous integration environments.
*
* @author Andy Wilkinson
*/
enum ContinuousIntegration {

BAMBOO("Bamboo", "bamboo_resultsUrl"),

CIRCLE_CI("CircleCI", "CIRCLE_BUILD_URL"),

CONCOURSE("Concourse", "CI", (env) -> null),

JENKINS("Jenkins", "JENKINS_URL", (env) -> env.get("BUILD_URL")),

GITHUB_ACTIONS("GitHub Actions", "GITHUB_ACTIONS", (env) -> {
String server = env.get("GITHUB_SERVER_URL");
String repository = env.get("GITHUB_REPOSITORY");
String runId = env.get("GITHUB_RUN_ID");
return server + "/" + repository + "/actions/runs/" + runId;
});

private final String name;

private final String environmentVariable;

private final Function<Map<String, String>, String> buildUrl;

ContinuousIntegration(String name, String environmentVariable) {
this(name, environmentVariable, (env) -> env.get(environmentVariable));
}

ContinuousIntegration(String name, String environmentVariable, Function<Map<String, String>, String> buildUrl) {
this.name = name;
this.environmentVariable = environmentVariable;
this.buildUrl = buildUrl;
}

String buildUrlFrom(Map<String, String> env) {
return this.buildUrl.apply(env);
}

@Override
public String toString() {
return this.name;
}

static ContinuousIntegration detect(Map<String, String> env) {
for (ContinuousIntegration ci : values()) {
if (env.containsKey(ci.environmentVariable)) {
return ci;
}
}
return null;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,22 @@ void whenBambooResultEnvVarIsPresentThenBuildScanHasACiBuildLinkToIt() {
assertThat(this.buildScan.links).containsEntry("CI build", "https://bamboo.example.com");
}

@Test
void whenBambooResultEnvVarIsPresentThenBuildScanHasBambooAsTheCiProviderValue() {
new BuildScanConventions(this.develocity, this.processRunner,
Collections.singletonMap("bamboo_resultsUrl", "https://bamboo.example.com"))
.execute(this.buildScan);
assertThat(this.buildScan.values).containsEntry("CI provider", "Bamboo");
}

@Test
void whenCircleBuildUrlEnvVarIsPresentThenBuildScanIsTaggedWithCiNotLocal() {
new BuildScanConventions(this.develocity, this.processRunner,
Collections.singletonMap("CIRCLE_BUILD_URL", "https://circleci.example.com/gh/org/project/123"))
.execute(this.buildScan);
assertThat(this.buildScan.tags).contains("CI").doesNotContain("Local");
}

@Test
void whenCircleBuildUrlEnvVarIsPresentThenBuildScanHasACiBuildLinkToIt() {
new BuildScanConventions(this.develocity, this.processRunner,
Expand All @@ -99,6 +115,22 @@ void whenCircleBuildUrlEnvVarIsPresentThenBuildScanHasACiBuildLinkToIt() {
assertThat(this.buildScan.links).containsEntry("CI build", "https://circleci.example.com/gh/org/project/123");
}

@Test
void whenCircleBuildUrlEnvVarIsPresentThenBuildScanHasCircleCiAsTheCiProviderValue() {
new BuildScanConventions(this.develocity, this.processRunner,
Collections.singletonMap("CIRCLE_BUILD_URL", "https://circleci.example.com/gh/org/project/123"))
.execute(this.buildScan);
assertThat(this.buildScan.values).containsEntry("CI provider", "CircleCI");
}

@Test
void whenJenkinsUrlEnvVarIsPresentThenBuildScanIsTaggedWithCiNotLocal() {
new BuildScanConventions(this.develocity, this.processRunner,
Collections.singletonMap("JENKINS_URL", "https://jenkins.example.com"))
.execute(this.buildScan);
assertThat(this.buildScan.tags).contains("CI").doesNotContain("Local");
}

@Test
void whenJenkinsUrlAndBuildUrlEnvVarsArePresentThenBuildScanHasACiBuildLinkToBuildUrl() {
Map<String, String> env = new HashMap<>();
Expand All @@ -108,6 +140,14 @@ void whenJenkinsUrlAndBuildUrlEnvVarsArePresentThenBuildScanHasACiBuildLinkToBui
assertThat(this.buildScan.links).containsEntry("CI build", "https://jenkins.example.com/builds/123");
}

@Test
void whenJenkinsUrlEnvVarIsPresentThenBuildScanHasJenkinsAsTheCiProviderValue() {
new BuildScanConventions(this.develocity, this.processRunner,
Collections.singletonMap("JENKINS_URL", "https://jenkins.example.com"))
.execute(this.buildScan);
assertThat(this.buildScan.values).containsEntry("CI provider", "Jenkins");
}

@Test
void whenCiEnvVarIsPresentThenBuildScanIsTaggedWithCiNotLocal() {
new BuildScanConventions(this.develocity, this.processRunner, Collections.singletonMap("CI", null))
Expand All @@ -116,11 +156,10 @@ void whenCiEnvVarIsPresentThenBuildScanIsTaggedWithCiNotLocal() {
}

@Test
void whenJenkinsUrlEnvVarIsPresentThenBuildScanIsTaggedWithCiNotLocal() {
new BuildScanConventions(this.develocity, this.processRunner,
Collections.singletonMap("JENKINS_URL", "https://jenkins.example.com"))
void whenCiEnvVarIsPresentThenBuildScanHasConcourseAsTheCiProviderValue() {
new BuildScanConventions(this.develocity, this.processRunner, Collections.singletonMap("CI", null))
.execute(this.buildScan);
assertThat(this.buildScan.tags).contains("CI").doesNotContain("Local");
assertThat(this.buildScan.values).containsEntry("CI provider", "Concourse");
}

@Test
Expand All @@ -143,12 +182,32 @@ void whenGitHubActionsEnvVarsArePresentThenBuildScanHasACiBuildLinkToIt() {
"https://github.com/spring-projects/spring-boot/actions/runs/1234567890");
}

@Test
void whenGitHubActionsEnvVarIsPresentThenBuildScanHasGitHubActionsAsTheCiProviderValue() {
new BuildScanConventions(this.develocity, this.processRunner,
Collections.singletonMap("GITHUB_ACTIONS", "true"))
.execute(this.buildScan);
assertThat(this.buildScan.values).containsEntry("CI provider", "GitHub Actions");
}

@Test
void whenNoCiIndicatorsArePresentThenBuildScanIsTaggedWithLocalNotCi() {
new BuildScanConventions(this.develocity, this.processRunner, Collections.emptyMap()).execute(this.buildScan);
assertThat(this.buildScan.tags).contains("Local").doesNotContain("CI");
}

@Test
void whenNoCiIndicatorsArePresentThenBuildScanHasNoCiBuildLink() {
new BuildScanConventions(this.develocity, this.processRunner, Collections.emptyMap()).execute(this.buildScan);
assertThat(this.buildScan.links).doesNotContainKey("CI build");
}

@Test
void whenNoCiIndicatorsArePresentThenBuildScanHasNoCiProviderValue() {
new BuildScanConventions(this.develocity, this.processRunner, Collections.emptyMap()).execute(this.buildScan);
assertThat(this.buildScan.values).doesNotContainKey("CI provider");
}

@Test
void buildScanIsTaggedWithJdkVersion() {
new BuildScanConventions(this.develocity, this.processRunner).execute(this.buildScan);
Expand Down

0 comments on commit 709fc65

Please sign in to comment.