Skip to content
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

[Internal] CICD provider #404

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
package com.databricks.sdk.core;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class UserAgent {
private static final Logger log = LoggerFactory.getLogger(UserAgent.class);
private static String product = "unknown";
private static String productVersion = "0.0.0";

Expand Down Expand Up @@ -121,6 +128,10 @@ public static String asString() {
segments.add(String.format("databricks-sdk-java/%s", version));
segments.add(String.format("jvm/%s", jvmVersion()));
segments.add(String.format("os/%s", osName()));
String ciProvider = cicdProvider();
if (!ciProvider.isEmpty()) {
segments.add(String.format("ci/%s", ciProvider));
}
// Concurrent iteration over ArrayList must be guarded with synchronized.
synchronized (otherInfo) {
segments.addAll(
Expand All @@ -130,4 +141,60 @@ public static String asString() {
}
return segments.stream().collect(Collectors.joining(" "));
}

// Map of CI/CD providers that are used to detect them.
private static final Map<String, List<EnvVar>> PROVIDERS = new HashMap<>();

static {
PROVIDERS.put("github", Collections.singletonList(new EnvVar("GITHUB_ACTIONS", "true")));
PROVIDERS.put("gitlab", Collections.singletonList(new EnvVar("GITLAB_CI", "true")));
PROVIDERS.put("jenkins", Collections.singletonList(new EnvVar("JENKINS_URL", "")));
PROVIDERS.put("azure-devops", Collections.singletonList(new EnvVar("TF_BUILD", "True")));
PROVIDERS.put("circle", Collections.singletonList(new EnvVar("CIRCLECI", "true")));
PROVIDERS.put("travis", Collections.singletonList(new EnvVar("TRAVIS", "true")));
PROVIDERS.put("bitbucket", Collections.singletonList(new EnvVar("BITBUCKET_BUILD_NUMBER", "")));
PROVIDERS.put(
"google-cloud-build",
Arrays.asList(
new EnvVar("PROJECT_ID", ""),
new EnvVar("BUILD_ID", ""),
new EnvVar("PROJECT_NUMBER", ""),
new EnvVar("LOCATION", "")));
PROVIDERS.put(
"aws-code-build", Collections.singletonList(new EnvVar("CODEBUILD_BUILD_ARN", "")));
PROVIDERS.put("tf-cloud", Collections.singletonList(new EnvVar("TFC_RUN_ID", "")));
}

// This is a static private variable to store the CI/CD provider.
// This is thread-safe because static initializers are executed
// in a thread-safe manner by the Java ClassLoader.
private static final String cicdProvider = lookupCiCdProvider();

private static class EnvVar {
private final String name;
private final String expectedValue;

public EnvVar(String name, String expectedValue) {
this.name = name;
this.expectedValue = expectedValue;
}

public boolean detect() {
String value = System.getenv(name);
return value != null && (expectedValue.isEmpty() || value.equals(expectedValue));
}
}

private static String lookupCiCdProvider() {
for (Map.Entry<String, List<EnvVar>> entry : PROVIDERS.entrySet()) {
if (entry.getValue().stream().allMatch(EnvVar::detect)) {
return entry.getKey();
}
}
return "";
}

public static String cicdProvider() {
return cicdProvider;
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
package com.databricks.sdk.core;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import java.util.Properties;
import org.junit.jupiter.api.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class UserAgentTest {
private static final Logger log = LoggerFactory.getLogger(UserAgentTest.class);

@Test
public void testUserAgent() {
UserAgent.withProduct("product", "productVersion");
Expand Down Expand Up @@ -56,4 +60,36 @@ public void testUserAgentWithSemverValue() {
String userAgent = UserAgent.asString();
Assertions.assertTrue(userAgent.contains("key1/1.0.0-dev+metadata"));
}

private Properties originalProperties;

@BeforeEach
public void saveProperties() {
// Save original system properties
originalProperties = (Properties) System.getProperties().clone();
}

@AfterEach
public void restoreProperties() {
// Restore original system properties
System.setProperties(originalProperties);
}

@Test
public void testUserAgentCicdNoProvider() {
Assertions.assertEquals("", UserAgent.cicdProvider());
}

@Test
public void testUserAgentCicdOneProvider() {
System.setProperty("GITHUB_ACTIONS", "true");
Assertions.assertEquals("github", UserAgent.cicdProvider());
}

@Test
public void testUserAgentCicdMultipleProviders() {
System.setProperty("GITHUB_ACTIONS", "true");
System.setProperty("GITLAB_CI", "true");
Assertions.assertEquals("github", UserAgent.cicdProvider());
}
}
Loading