Skip to content

Commit

Permalink
Allow configuring credentials for gradle plugin repository (#127)
Browse files Browse the repository at this point in the history
* Allow configuring credentials for gradle plugin repository

* Fix failing migrator test

* Fix failing json configuration test

* Provide a list of available credentials for choosing

* Fix browser tests
  • Loading branch information
welandaz authored Apr 2, 2024
1 parent 2b5e69c commit 56a138a
Show file tree
Hide file tree
Showing 15 changed files with 181 additions and 49 deletions.
2 changes: 2 additions & 0 deletions src/main/i18n/develocity-bamboo-plugin.properties
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ develocity.config.maven-extension.enabled=Enables Develocity Maven extension aut
develocity.config.maven-settings.title=Maven settings
develocity.config.plugin-repository.description=The URL of the repository to use when resolving the Develocity and Common Custom User Data plugins. Defaults to the Gradle Plugin Portal.
develocity.config.plugin-repository=Gradle plugin repository URL
develocity.config.plugin-repository-credential-name=Gradle plugin repository credential name
develocity.config.plugin-repository-credential-name.description=The name of the plugin repository credential of type ‘Username and password’ containing the username and password for authenticating with the Gradle Plugin Repository.
develocity.config.server.description=The URL of the Develocity server.
develocity.config.server=Develocity server URL
develocity.config.shared-credential-name.description=The name of the shared credential of type ‘Username and password’ containing the access key for authenticating with the Develocity server.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
import com.gradle.develocity.bamboo.config.GradleConfiguration;
import com.gradle.develocity.bamboo.config.PersistentConfiguration;
import com.gradle.develocity.bamboo.config.PersistentConfigurationManager;
import com.gradle.develocity.bamboo.config.UsernameAndPassword;
import com.gradle.develocity.bamboo.config.UsernameAndPasswordCredentialsProvider;
import com.gradle.develocity.bamboo.utils.Objects;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
Expand Down Expand Up @@ -45,29 +47,32 @@ public class GradleBuildScanInjector extends AbstractBuildScanInjector<GradleCon
public static final String ARTIFACTORY_GRADLE_TASK_KEY_SUFFIX = "artifactoryGradleTask";

private static final Set<Predicate<String>> GRADLE_BUILDERS =
ImmutableSet.of(
eq(SCRIPT_PLUGIN_KEY),
eq(COMMAND_PLUGIN_KEY),
eq(BOB_SWIFT_GROOVY_TASKS_PLUGIN_GRADLE_KEY),
eq(BOB_SWIFT_GROOVY_TASKS_PLUGIN_GRADLE_WRAPPER_KEY),
eq(BOB_SWIFT_GROOVY_TASKS_PLUGIN_GRADLEW_KEY),
endsWith(ARTIFACTORY_GRADLE_TASK_KEY_SUFFIX)
);
ImmutableSet.of(
eq(SCRIPT_PLUGIN_KEY),
eq(COMMAND_PLUGIN_KEY),
eq(BOB_SWIFT_GROOVY_TASKS_PLUGIN_GRADLE_KEY),
eq(BOB_SWIFT_GROOVY_TASKS_PLUGIN_GRADLE_WRAPPER_KEY),
eq(BOB_SWIFT_GROOVY_TASKS_PLUGIN_GRADLEW_KEY),
endsWith(ARTIFACTORY_GRADLE_TASK_KEY_SUFFIX)
);

private final EnvironmentVariableAccessor environmentVariableAccessor;
private final DevelocityAccessKeyExporter accessKeyExporter;
private final UsernameAndPasswordCredentialsProvider credentialsProvider;
private final GradleEmbeddedResources gradleEmbeddedResources = new GradleEmbeddedResources();

@Autowired
public GradleBuildScanInjector(
@ComponentImport BuildLoggerManager buildLoggerManager,
PersistentConfigurationManager configurationManager,
@ComponentImport EnvironmentVariableAccessor environmentVariableAccessor,
DevelocityAccessKeyExporter accessKeyExporter
@ComponentImport BuildLoggerManager buildLoggerManager,
PersistentConfigurationManager configurationManager,
@ComponentImport EnvironmentVariableAccessor environmentVariableAccessor,
DevelocityAccessKeyExporter accessKeyExporter,
UsernameAndPasswordCredentialsProvider credentialsProvider
) {
super(buildLoggerManager, configurationManager);
this.environmentVariableAccessor = environmentVariableAccessor;
this.accessKeyExporter = accessKeyExporter;
this.credentialsProvider = credentialsProvider;
}

@Override
Expand Down Expand Up @@ -114,7 +119,7 @@ private void inject(BuildContext buildContext, Collection<RuntimeTaskDefinition>
File initScript = gradleEmbeddedResources.copyInitScript(home);
LOGGER.debug("Gradle init script: {}", initScript.getAbsolutePath());

prepareEnvironment(buildContext, config);
prepareEnvironment(buildContext, config, tasks);
registerDevelocityResources(buildContext, initScript);
setupBuildScansLogInterceptor(buildContext);

Expand All @@ -123,13 +128,30 @@ private void inject(BuildContext buildContext, Collection<RuntimeTaskDefinition>
LOGGER.debug("Develocity Gradle auto-injection completed");
}

private void prepareEnvironment(BuildContext buildContext, GradleConfiguration config) {
private void prepareEnvironment(BuildContext buildContext, GradleConfiguration config, Collection<RuntimeTaskDefinition> tasks) {
VariableContext variableContext = buildContext.getVariableContext();

Objects.runIfNotNull(config.server, s -> variableContext.addLocalVariable("DEVELOCITY_PLUGIN_DEVELOCITY_URL", s));
Objects.runIfNotNull(config.server, it -> variableContext.addLocalVariable("DEVELOCITY_PLUGIN_DEVELOCITY_URL", it));
Objects.runIfTrue(config.allowUntrustedServer, () -> variableContext.addLocalVariable("DEVELOCITY_PLUGIN_DEVELOCITY_ALLOW_UNTRUSTED_SERVER", "true"));
Objects.runIfNotNull(config.develocityPluginVersion, v -> variableContext.addLocalVariable("DEVELOCITY_PLUGIN_DEVELOCITY_PLUGIN_VERSION", v));
Objects.runIfNotNull(config.ccudPluginVersion, v -> variableContext.addLocalVariable("DEVELOCITY_PLUGIN_CCUD_PLUGIN_VERSION", v));
Objects.runIfNotNull(config.pluginRepository, r -> variableContext.addLocalVariable("DEVELOCITY_PLUGIN_GRADLE_PLUGIN_REPOSITORY_URL", r));
Objects.runIfNotNull(config.develocityPluginVersion, it -> variableContext.addLocalVariable("DEVELOCITY_PLUGIN_DEVELOCITY_PLUGIN_VERSION", it));
Objects.runIfNotNull(config.ccudPluginVersion, it -> variableContext.addLocalVariable("DEVELOCITY_PLUGIN_CCUD_PLUGIN_VERSION", it));
Objects.runIfNotNull(config.pluginRepository, it -> variableContext.addLocalVariable("DEVELOCITY_PLUGIN_GRADLE_PLUGIN_REPOSITORY_URL", it));

Objects.runIfNotNull(
config.pluginRepositoryCredentialName,
it -> {
UsernameAndPassword credentials = credentialsProvider.findByName(it).orElse(null);
if (credentials == null) {
LOGGER.warn("Plugin repository credentials with the name {} are not found.", it);
} else {
if (credentials.getUsername() == null || credentials.getPassword() == null) {
LOGGER.warn("Plugin repository credentials {} do not have username or password set.", it);
} else {
variableContext.addLocalVariable("DEVELOCITY_PLUGIN_GRADLE_PLUGIN_REPOSITORY_USERNAME", credentials.getUsername());
variableContext.addLocalVariable("DEVELOCITY_PLUGIN_GRADLE_PLUGIN_REPOSITORY_PASSWORD", credentials.getPassword());
}
}
}
);
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.gradle.develocity.bamboo.admin;

import com.atlassian.bamboo.configuration.GlobalAdminAction;
import com.atlassian.bamboo.repository.NameValuePair;
import com.gradle.develocity.bamboo.MavenCoordinates;
import com.gradle.develocity.bamboo.config.PersistentConfiguration;
import com.gradle.develocity.bamboo.config.PersistentConfigurationManager;
Expand All @@ -10,7 +11,9 @@

import java.net.MalformedURLException;
import java.net.URL;
import java.util.List;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

public class BuildScansConfigAction extends GlobalAdminAction {

Expand All @@ -26,6 +29,7 @@ public class BuildScansConfigAction extends GlobalAdminAction {
private String develocityPluginVersion;
private String ccudPluginVersion;
private String pluginRepository;
private String pluginRepositoryCredentialName;

/* Maven specific parameters */
private boolean injectMavenExtension;
Expand All @@ -52,6 +56,7 @@ public String input() {
develocityPluginVersion = config.getDevelocityPluginVersion();
ccudPluginVersion = config.getCcudPluginVersion();
pluginRepository = config.getPluginRepository();
pluginRepositoryCredentialName = config.getPluginRepositoryCredentialName();
injectMavenExtension = config.isInjectMavenExtension();
injectCcudExtension = config.isInjectCcudExtension();
mavenExtensionCustomCoordinates = config.getMavenExtensionCustomCoordinates();
Expand Down Expand Up @@ -94,6 +99,13 @@ public void validate() {
addFieldError("pluginRepository", "Please specify a valid URL of the Gradle plugins repository.");
}

if (StringUtils.isNotBlank(pluginRepositoryCredentialName)) {
UsernameAndPassword credentials = credentialsProvider.findByName(pluginRepositoryCredentialName).orElse(null);
if (credentials == null) {
addFieldError("pluginRepositoryCredentialName", "Please specify the name of the existing repository credential of type 'Username and password'.");
}
}

if (!isBlankOrValidGavc(mavenExtensionCustomCoordinates)) {
addFieldError("mavenExtensionCustomCoordinates", "Please specify a valid Maven groupId:artifactId(:version).");
}
Expand All @@ -104,6 +116,17 @@ public void validate() {

}

public List<NameValuePair> getUsernameAndPasswordCredentialNames() {
List<NameValuePair> usernameAndPasswordCredentials = credentialsProvider.getAllUsernameAndPasswordCredentials()
.stream()
.map(credentialName -> new NameValuePair(credentialName, credentialName))
.collect(Collectors.toList());

usernameAndPasswordCredentials.add(0, new NameValuePair("", "None"));

return usernameAndPasswordCredentials;
}

private boolean isBlankOrValidGavc(String coordinates) {
if (StringUtils.isBlank(coordinates)) {
return true;
Expand Down Expand Up @@ -138,6 +161,7 @@ public String save() {
.setSharedCredentialName(sharedCredentialName)
.setEnforceUrl(enforceUrl)
.setPluginRepository(pluginRepository)
.setPluginRepositoryCredentialName(pluginRepositoryCredentialName)
.setDevelocityPluginVersion(develocityPluginVersion)
.setCcudPluginVersion(ccudPluginVersion)
.setInjectMavenExtension(injectMavenExtension)
Expand Down Expand Up @@ -204,6 +228,14 @@ public void setPluginRepository(String pluginRepository) {
this.pluginRepository = pluginRepository;
}

public String getPluginRepositoryCredentialName() {
return pluginRepositoryCredentialName;
}

public void setPluginRepositoryCredentialName(String pluginRepositoryCredentialName) {
this.pluginRepositoryCredentialName = pluginRepositoryCredentialName;
}

public boolean isInjectMavenExtension() {
return injectMavenExtension;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,24 @@ public final class GradleConfiguration extends BuildToolConfiguration {
public final String ccudPluginVersion;
@Nullable
public final String pluginRepository;
@Nullable
public final String pluginRepositoryCredentialName;

private GradleConfiguration(@Nullable String server,
boolean allowUntrustedServer,
@Nullable String sharedCredentialName,
@Nullable String develocityPluginVersion,
@Nullable String ccudPluginVersion,
@Nullable String pluginRepository,
boolean enforceUrl) {
private GradleConfiguration(
@Nullable String server,
boolean allowUntrustedServer,
@Nullable String sharedCredentialName,
@Nullable String develocityPluginVersion,
@Nullable String ccudPluginVersion,
@Nullable String pluginRepository,
@Nullable String pluginRepositoryCredentialName,
boolean enforceUrl
) {
super(server, allowUntrustedServer, sharedCredentialName, enforceUrl);
this.develocityPluginVersion = develocityPluginVersion;
this.ccudPluginVersion = ccudPluginVersion;
this.pluginRepository = pluginRepository;
this.pluginRepositoryCredentialName = pluginRepositoryCredentialName;
}

public static GradleConfiguration of(PersistentConfiguration configuration) {
Expand All @@ -32,7 +38,9 @@ public static GradleConfiguration of(PersistentConfiguration configuration) {
configuration.getDevelocityPluginVersion(),
configuration.getCcudPluginVersion(),
configuration.getPluginRepository(),
configuration.isEnforceUrl());
configuration.getPluginRepositoryCredentialName(),
configuration.isEnforceUrl()
);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ public class PersistentConfiguration {
private String ccudPluginVersion;
@Nullable
private String pluginRepository;
@Nullable
private String pluginRepositoryCredentialName;

private boolean injectMavenExtension;
private boolean injectCcudExtension;
Expand Down Expand Up @@ -99,6 +101,16 @@ public PersistentConfiguration setPluginRepository(String pluginRepository) {
return this;
}

@Nullable
public String getPluginRepositoryCredentialName() {
return pluginRepositoryCredentialName;
}

public PersistentConfiguration setPluginRepositoryCredentialName(@Nullable String pluginRepositoryCredentialName) {
this.pluginRepositoryCredentialName = StringUtils.trimToNull(pluginRepositoryCredentialName);
return this;
}

public boolean isInjectMavenExtension() {
return injectMavenExtension;
}
Expand Down Expand Up @@ -147,6 +159,7 @@ public String toString() {
.append("develocityPluginVersion", develocityPluginVersion)
.append("ccudPluginVersion", ccudPluginVersion)
.append("pluginRepository", pluginRepository)
.append("pluginRepositoryCredentialName", pluginRepositoryCredentialName)
.append("injectMavenExtension", injectMavenExtension)
.append("injectCcudExtension", injectCcudExtension)
.append("customMavenExtension", mavenExtensionCustomCoordinates)
Expand All @@ -168,13 +181,14 @@ public boolean equals(Object o) {
Objects.equals(develocityPluginVersion, that.develocityPluginVersion) &&
Objects.equals(ccudPluginVersion, that.ccudPluginVersion) &&
Objects.equals(pluginRepository, that.pluginRepository) &&
Objects.equals(pluginRepositoryCredentialName, that.pluginRepositoryCredentialName) &&
Objects.equals(mavenExtensionCustomCoordinates, that.mavenExtensionCustomCoordinates) &&
Objects.equals(ccudExtensionCustomCoordinates, that.ccudExtensionCustomCoordinates);
}

@Override
public int hashCode() {
return Objects.hash(server, allowUntrustedServer, sharedCredentialName, enforceUrl, develocityPluginVersion, ccudPluginVersion,
pluginRepository, injectMavenExtension, injectCcudExtension, mavenExtensionCustomCoordinates, ccudExtensionCustomCoordinates);
pluginRepository, pluginRepositoryCredentialName, injectMavenExtension, injectCcudExtension, mavenExtensionCustomCoordinates, ccudExtensionCustomCoordinates);
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
package com.gradle.develocity.bamboo.config;

import com.atlassian.bamboo.credentials.CredentialsAccessor;
import com.atlassian.bamboo.credentials.CredentialsData;
import com.atlassian.plugin.spring.scanner.annotation.imports.ComponentImport;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;

import static com.gradle.develocity.bamboo.config.UsernameAndPassword.SHARED_USERNAME_PASSWORD_PLUGIN_KEY;

@Component
public class UsernameAndPasswordCredentialsProvider {
Expand All @@ -19,6 +25,14 @@ public UsernameAndPasswordCredentialsProvider(@ComponentImport CredentialsAccess

public Optional<UsernameAndPassword> findByName(String name) {
return Optional.ofNullable(credentialsAccessor.getCredentialsByName(name))
.map(UsernameAndPassword::of);
.map(UsernameAndPassword::of);
}

public List<String> getAllUsernameAndPasswordCredentials() {
return StreamSupport.stream(credentialsAccessor.getAllCredentials().spliterator(), false)
.filter(it -> SHARED_USERNAME_PASSWORD_PLUGIN_KEY.equals(it.getPluginKey()))
.map(CredentialsData::getName)
.collect(Collectors.toList());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,5 @@ public static void runIfTrue(boolean shouldRun, Runnable action) {
action.run();
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ initscript {
}

def pluginRepositoryUrl = getInputParam('develocity-plugin.gradle.plugin-repository.url')
def pluginRepositoryUsername = getInputParam('develocity-plugin.gradle.plugin-repository.username')
def pluginRepositoryPassword = getInputParam('develocity-plugin.gradle.plugin-repository.password')
def develocityPluginVersion = getInputParam('develocity-plugin.develocity.plugin.version')
def ccudPluginVersion = getInputParam('develocity-plugin.ccud.plugin.version')

Expand All @@ -26,7 +28,19 @@ initscript {
logger.lifecycle("Develocity plugins resolution: $pluginRepositoryUrl")

repositories {
maven { url pluginRepositoryUrl }
maven {
url pluginRepositoryUrl
if (pluginRepositoryUsername && pluginRepositoryPassword) {
logger.lifecycle("Using credentials for plugin repository")
credentials {
username(pluginRepositoryUsername)
password(pluginRepositoryPassword)
}
authentication {
basic(BasicAuthentication)
}
}
}
// TODO remove before merge
maven {
url "https://repo.grdev.net/artifactory/public"
Expand Down
13 changes: 12 additions & 1 deletion src/main/resources/templates/views/admin/buildScansConfig.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,12 @@
[@ww.textfield labelKey="develocity.config.server" name="server" autofocus=true/]
[@ww.checkbox labelKey="develocity.config.allow-untrusted-server" name="allowUntrustedServer" toggle="true"/]
[@ww.checkbox labelKey="develocity.config.enforce-url" name="enforceUrl" toggle="true"/]
[@ww.textfield labelKey="develocity.config.shared-credential-name" name="sharedCredentialName"/]
[@ww.select labelKey='develocity.config.shared-credential-name' name='sharedCredentialName'
toggle='true'
list=usernameAndPasswordCredentialNames
listKey='name'
listValue='label']
[/@ww.select]
<div class="field-group">
<div style="display: inline-block;">
[@ui.messageBox type="info"]
Expand All @@ -32,6 +37,12 @@
[@ww.textfield labelKey="develocity.config.develocity-plugin.version" name="develocityPluginVersion"/]
[@ww.textfield labelKey="develocity.config.ccud-plugin.version" name="ccudPluginVersion"/]
[@ww.textfield labelKey="develocity.config.plugin-repository" name="pluginRepository"/]
[@ww.select labelKey='develocity.config.plugin-repository-credential-name' name='pluginRepositoryCredentialName'
toggle='true'
list=usernameAndPasswordCredentialNames
listKey='name'
listValue='label']
[/@ww.select]
[/@ui.bambooSection]

[@ui.bambooSection titleKey="develocity.config.maven-settings.title" headerWeight="h2"]
Expand Down
Loading

0 comments on commit 56a138a

Please sign in to comment.