Skip to content

Commit

Permalink
Add an ability to capture task/goal input files (#400)
Browse files Browse the repository at this point in the history
* Add an ability to capture task/goal input files

* Fix configuration migration test

* Remove explicit help attribute
  • Loading branch information
welandaz authored Mar 4, 2024
1 parent 6439fd2 commit f8dae98
Show file tree
Hide file tree
Showing 13 changed files with 138 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ public class GradleBuildScanInjection implements BuildScanInjection, GradleInjec
JENKINSGRADLEPLUGIN_GRADLE_ENTERPRISE_PLUGIN_VERSION,
JENKINSGRADLEPLUGIN_CCUD_PLUGIN_VERSION,
JENKINSGRADLEPLUGIN_GRADLE_AUTO_INJECTION,
JENKINSGRADLEPLUGIN_GRADLE_ENTERPRISE_GRADLE_INJECTION_ENABLED
JENKINSGRADLEPLUGIN_GRADLE_ENTERPRISE_GRADLE_INJECTION_ENABLED,
JENKINSGRADLEPLUGIN_GRADLE_ENTERPRISE_CAPTURE_TASK_INPUT_FILES
);

private static final String HOME = "HOME";
Expand Down Expand Up @@ -118,6 +119,12 @@ private void injectEnvironmentVariables(InjectionConfig config, Node node) {
EnvUtil.removeEnvVar(node, JENKINSGRADLEPLUGIN_GRADLE_ENTERPRISE_ENFORCE_URL);
}

if (config.isGradleCaptureTaskInputFiles()) {
EnvUtil.setEnvVar(node, JENKINSGRADLEPLUGIN_GRADLE_ENTERPRISE_CAPTURE_TASK_INPUT_FILES, "true");
} else {
EnvUtil.removeEnvVar(node, JENKINSGRADLEPLUGIN_GRADLE_ENTERPRISE_CAPTURE_TASK_INPUT_FILES);
}

String pluginRepositoryUrl = config.getGradlePluginRepositoryUrl();
if (pluginRepositoryUrl != null && InjectionUtil.isValid(InjectionConfig.checkUrl(pluginRepositoryUrl))) {
EnvUtil.setEnvVar(node, JENKINSGRADLEPLUGIN_GRADLE_PLUGIN_REPOSITORY_URL, pluginRepositoryUrl);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ public interface GradleInjectionAware {
String JENKINSGRADLEPLUGIN_GRADLE_ENTERPRISE_URL = "JENKINSGRADLEPLUGIN_GRADLE_ENTERPRISE_URL";
String JENKINSGRADLEPLUGIN_GRADLE_ENTERPRISE_ENFORCE_URL = "JENKINSGRADLEPLUGIN_GRADLE_ENTERPRISE_ENFORCE_URL";
String JENKINSGRADLEPLUGIN_GRADLE_ENTERPRISE_ALLOW_UNTRUSTED_SERVER = "JENKINSGRADLEPLUGIN_GRADLE_ENTERPRISE_ALLOW_UNTRUSTED_SERVER";
String JENKINSGRADLEPLUGIN_GRADLE_ENTERPRISE_CAPTURE_TASK_INPUT_FILES = "JENKINSGRADLEPLUGIN_GRADLE_ENTERPRISE_CAPTURE_TASK_INPUT_FILES";
String JENKINSGRADLEPLUGIN_GRADLE_PLUGIN_REPOSITORY_URL = "JENKINSGRADLEPLUGIN_GRADLE_PLUGIN_REPOSITORY_URL";
String JENKINSGRADLEPLUGIN_GRADLE_PLUGIN_REPOSITORY_USERNAME = "JENKINSGRADLEPLUGIN_GRADLE_PLUGIN_REPOSITORY_USERNAME";
String JENKINSGRADLEPLUGIN_GRADLE_PLUGIN_REPOSITORY_PASSWORD = "JENKINSGRADLEPLUGIN_GRADLE_PLUGIN_REPOSITORY_PASSWORD";
Expand Down
20 changes: 20 additions & 0 deletions src/main/java/hudson/plugins/gradle/injection/InjectionConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -62,13 +62,15 @@ public class InjectionConfig extends GlobalConfiguration {
private Secret gradlePluginRepositoryPassword;
private ImmutableList<NodeLabelItem> gradleInjectionEnabledNodes;
private ImmutableList<NodeLabelItem> gradleInjectionDisabledNodes;
private boolean gradleCaptureTaskInputFiles;

private boolean injectMavenExtension;
private boolean injectCcudExtension;
private String mavenExtensionCustomCoordinates;
private String ccudExtensionCustomCoordinates;
private ImmutableList<NodeLabelItem> mavenInjectionEnabledNodes;
private ImmutableList<NodeLabelItem> mavenInjectionDisabledNodes;
private boolean mavenCaptureGoalInputFiles;

private boolean enforceUrl;
private boolean checkForBuildAgentErrors;
Expand Down Expand Up @@ -228,6 +230,15 @@ public void setGradleInjectionDisabledNodes(List<NodeLabelItem> gradleInjectionD
gradleInjectionDisabledNodes == null ? null : ImmutableList.copyOf(gradleInjectionDisabledNodes);
}

public boolean isGradleCaptureTaskInputFiles() {
return gradleCaptureTaskInputFiles;
}

@DataBoundSetter
public void setGradleCaptureTaskInputFiles(boolean gradleCaptureTaskInputFiles) {
this.gradleCaptureTaskInputFiles = gradleCaptureTaskInputFiles;
}

public boolean isInjectMavenExtension() {
return injectMavenExtension;
}
Expand Down Expand Up @@ -288,6 +299,15 @@ public void setMavenInjectionDisabledNodes(List<NodeLabelItem> mavenInjectionDis
mavenInjectionDisabledNodes == null ? null : ImmutableList.copyOf(mavenInjectionDisabledNodes);
}

public boolean isMavenCaptureGoalInputFiles() {
return mavenCaptureGoalInputFiles;
}

@DataBoundSetter
public void setMavenCaptureGoalInputFiles(boolean mavenCaptureGoalInputFiles) {
this.mavenCaptureGoalInputFiles = mavenCaptureGoalInputFiles;
}

@DataBoundSetter
public void setVcsRepositoryFilter(String vcsRepositoryFilter) {
this.parsedVcsRepositoryFilter = VcsRepositoryFilter.of(vcsRepositoryFilter);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,9 @@ private void inject(InjectionConfig config, Node node, FilePath nodeRootPath) {
if (config.isAllowUntrusted()) {
systemProperties.add(new SystemProperty(GRADLE_ENTERPRISE_ALLOW_UNTRUSTED_SERVER_PROPERTY_KEY, "true"));
}
if (config.isMavenCaptureGoalInputFiles()) {
systemProperties.add(new SystemProperty(GRADLE_ENTERPRISE_CAPTURE_GOAL_INPUT_FILES_PROPERTY_KEY, "true"));
}

EnvUtil.setEnvVar(node, MavenOptsHandler.MAVEN_OPTS, MAVEN_OPTS_HANDLER.merge(node, systemProperties));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,14 @@ public interface MavenInjectionAware {
SystemProperty.Key BUILD_SCAN_UPLOAD_IN_BACKGROUND_PROPERTY_KEY = SystemProperty.Key.required("gradle.scan.uploadInBackground");
SystemProperty.Key MAVEN_EXT_CLASS_PATH_PROPERTY_KEY = SystemProperty.Key.required("maven.ext.class.path");
SystemProperty.Key GRADLE_ENTERPRISE_ALLOW_UNTRUSTED_SERVER_PROPERTY_KEY = SystemProperty.Key.optional("gradle.enterprise.allowUntrustedServer");
SystemProperty.Key GRADLE_ENTERPRISE_CAPTURE_GOAL_INPUT_FILES_PROPERTY_KEY = SystemProperty.Key.optional("gradle.scan.captureGoalInputFiles");

MavenOptsHandler MAVEN_OPTS_HANDLER = new MavenOptsHandler(
MAVEN_EXT_CLASS_PATH_PROPERTY_KEY,
BUILD_SCAN_UPLOAD_IN_BACKGROUND_PROPERTY_KEY,
GRADLE_ENTERPRISE_ALLOW_UNTRUSTED_SERVER_PROPERTY_KEY,
GRADLE_ENTERPRISE_URL_PROPERTY_KEY
GRADLE_ENTERPRISE_URL_PROPERTY_KEY,
GRADLE_ENTERPRISE_CAPTURE_GOAL_INPUT_FILES_PROPERTY_KEY
);

default boolean isInjectionDisabledGlobally(InjectionConfig config) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,9 @@
</f:entry>
</f:repeatableProperty>
</f:entry>
<f:entry field="gradleCaptureTaskInputFiles">
<f:checkbox title="${%Capture Task Input Files}"/>
</f:entry>
</f:section>

<f:section title="${%Maven settings}">
Expand Down Expand Up @@ -133,6 +136,9 @@
</f:entry>
</f:repeatableProperty>
</f:entry>
<f:entry field="mavenCaptureGoalInputFiles">
<f:checkbox title="${%Capture Goal Input Files}"/>
</f:entry>
</f:section>

</f:optionalBlock>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<div>
Enables capturing the paths and content hashes of each individual input file.
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<div>
Enables capturing the paths and content hashes of each individual input file.
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ if (gradleInjectionEnabled == "false") {

def geUrl = getInputParam('jenkinsGradlePlugin.gradle-enterprise.url')
def geAllowUntrustedServer = Boolean.parseBoolean(getInputParam('jenkinsGradlePlugin.gradle-enterprise.allow-untrusted-server'))
def geCaptureTaskInputFiles = Boolean.parseBoolean(getInputParam('jenkinsGradlePlugin.gradle-enterprise.capture-task-input-files'))
def geEnforceUrl = Boolean.parseBoolean(getInputParam('jenkinsGradlePlugin.gradle-enterprise.enforce-url'))
def gePluginVersion = getInputParam('jenkinsGradlePlugin.gradle-enterprise.plugin.version')
def ccudPluginVersion = getInputParam('jenkinsGradlePlugin.ccud.plugin.version')
Expand All @@ -114,21 +115,35 @@ if (GradleVersion.current() < GradleVersion.version('6.0')) {
}
if (!scanPluginComponent) {
logger.lifecycle("Applying $BUILD_SCAN_PLUGIN_CLASS via init script")
logger.lifecycle("Connection to Develocity: $geUrl, allowUntrustedServer: $geAllowUntrustedServer")
logger.lifecycle("Connection to Develocity: $geUrl, allowUntrustedServer: $geAllowUntrustedServer, captureTaskInputFiles: $geCaptureTaskInputFiles")
applyPluginExternally(pluginManager, BUILD_SCAN_PLUGIN_CLASS)
buildScan.server = geUrl
buildScan.allowUntrustedServer = geAllowUntrustedServer
buildScan.publishAlways()
if (isAtLeast(gePluginVersion, '2.1')) {
if (isNotAtLeast(gePluginVersion, '3.7')) {
buildScan.captureTaskInputFiles = geCaptureTaskInputFiles
} else {
buildScan.capture.taskInputFiles = geCaptureTaskInputFiles
}
}
if (buildScan.metaClass.respondsTo(buildScan, 'setUploadInBackground', Boolean)) buildScan.uploadInBackground = false // uploadInBackground not available for build-scan-plugin 1.16
buildScan.value CI_AUTO_INJECTION_CUSTOM_VALUE_NAME, CI_AUTO_INJECTION_CUSTOM_VALUE_VALUE
}

if (geUrl && geEnforceUrl) {
pluginManager.withPlugin(BUILD_SCAN_PLUGIN_ID) {
afterEvaluate {
logger.lifecycle("Enforcing Develocity: $geUrl, allowUntrustedServer: $geAllowUntrustedServer")
logger.lifecycle("Enforcing Develocity: $geUrl, allowUntrustedServer: $geAllowUntrustedServer, captureTaskInputFiles: $geCaptureTaskInputFiles")
buildScan.server = geUrl
buildScan.allowUntrustedServer = geAllowUntrustedServer
if (isAtLeast(gePluginVersion, '2.1')) {
if (isNotAtLeast(gePluginVersion, '3.7')) {
buildScan.captureTaskInputFiles = geCaptureTaskInputFiles
} else {
buildScan.capture.taskInputFiles = geCaptureTaskInputFiles
}
}
}
}
}
Expand All @@ -150,22 +165,36 @@ if (GradleVersion.current() < GradleVersion.version('6.0')) {
if (gePluginVersion) {
if (!settings.pluginManager.hasPlugin(GRADLE_ENTERPRISE_PLUGIN_ID)) {
logger.lifecycle("Applying $GRADLE_ENTERPRISE_PLUGIN_CLASS via init script")
logger.lifecycle("Connection to Develocity: $geUrl, allowUntrustedServer: $geAllowUntrustedServer")
logger.lifecycle("Connection to Develocity: $geUrl, allowUntrustedServer: $geAllowUntrustedServer, captureTaskInputFiles: $geCaptureTaskInputFiles")
applyPluginExternally(settings.pluginManager, GRADLE_ENTERPRISE_PLUGIN_CLASS)
extensionsWithPublicType(settings, GRADLE_ENTERPRISE_EXTENSION_CLASS).collect { settings[it.name] }.each { ext ->
ext.server = geUrl
ext.allowUntrustedServer = geAllowUntrustedServer
ext.buildScan.publishAlways()
ext.buildScan.uploadInBackground = false
if (isAtLeast(gePluginVersion, '2.1')) {
if (isNotAtLeast(gePluginVersion, '3.7')) {
ext.buildScan.captureTaskInputFiles = geCaptureTaskInputFiles
} else {
ext.buildScan.capture.taskInputFiles = geCaptureTaskInputFiles
}
}
ext.buildScan.value CI_AUTO_INJECTION_CUSTOM_VALUE_NAME, CI_AUTO_INJECTION_CUSTOM_VALUE_VALUE
}
}

if (geUrl && geEnforceUrl) {
extensionsWithPublicType(settings, GRADLE_ENTERPRISE_EXTENSION_CLASS).collect { settings[it.name] }.each { ext ->
logger.lifecycle("Enforcing Develocity: $geUrl, allowUntrustedServer: $geAllowUntrustedServer")
logger.lifecycle("Enforcing Develocity: $geUrl, allowUntrustedServer: $geAllowUntrustedServer, captureTaskInputFiles: $geCaptureTaskInputFiles")
ext.server = geUrl
ext.allowUntrustedServer = geAllowUntrustedServer
if (isAtLeast(gePluginVersion, '2.1')) {
if (isNotAtLeast(gePluginVersion, '3.7')) {
ext.buildScan.captureTaskInputFiles = geCaptureTaskInputFiles
} else {
ext.buildScan.capture.taskInputFiles = geCaptureTaskInputFiles
}
}
}
}
}
Expand Down Expand Up @@ -216,5 +245,9 @@ static String escapeChar(char ch) {
}

static boolean isNotAtLeast(String versionUnderTest, String referenceVersion) {
GradleVersion.version(versionUnderTest) < GradleVersion.version(referenceVersion)
!isAtLeast(versionUnderTest, referenceVersion)
}

static boolean isAtLeast(String versionUnderTest, String referenceVersion) {
GradleVersion.version(versionUnderTest) > GradleVersion.version(referenceVersion)
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@ abstract class BaseGradleIntegrationTest extends AbstractIntegrationTest {
def enableBuildInjection(DumbSlave slave,
String gradleVersion,
URI repositoryAddress = null,
Boolean globalAutoInjectionCheckEnabled = false) {
Boolean globalAutoInjectionCheckEnabled = false,
boolean captureTaskInputFiles = false
) {
withGlobalEnvVars {
put("JENKINSGRADLEPLUGIN_BUILD_SCAN_OVERRIDE_GRADLE_HOME", getGradleHome(slave, gradleVersion))
put('GRADLE_OPTS', '-Dscan.uploadInBackground=false')
Expand All @@ -43,8 +45,9 @@ abstract class BaseGradleIntegrationTest extends AbstractIntegrationTest {

withInjectionConfig {
enabled = true
gradlePluginVersion = GRADLE_ENTERPRISE_PLUGIN_VERSION
gradlePluginVersion = gradleVersion < '5.0' ? "1.16" : GRADLE_ENTERPRISE_PLUGIN_VERSION
gradlePluginRepositoryUrl = repositoryAddress?.toString()
gradleCaptureTaskInputFiles = captureTaskInputFiles
}

restartSlave(slave)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -685,6 +685,7 @@ class BuildScanInjectionGradleIntegrationTest extends BaseGradleIntegrationTest
get("JENKINSGRADLEPLUGIN_GRADLE_ENTERPRISE_ENFORCE_URL") == null
get("JENKINSGRADLEPLUGIN_GRADLE_PLUGIN_REPOSITORY_URL") == null
get("JENKINSGRADLEPLUGIN_CCUD_PLUGIN_VERSION") == null
get("JENKINSGRADLEPLUGIN_GRADLE_ENTERPRISE_CAPTURE_TASK_INPUT_FILES") == null
}
}

Expand All @@ -708,6 +709,7 @@ class BuildScanInjectionGradleIntegrationTest extends BaseGradleIntegrationTest
get("JENKINSGRADLEPLUGIN_GRADLE_ENTERPRISE_ENFORCE_URL") == null
get("JENKINSGRADLEPLUGIN_GRADLE_PLUGIN_REPOSITORY_URL") == null
get("JENKINSGRADLEPLUGIN_CCUD_PLUGIN_VERSION") == null
get("JENKINSGRADLEPLUGIN_GRADLE_ENTERPRISE_CAPTURE_TASK_INPUT_FILES") == null
}
}
}
Expand All @@ -734,6 +736,7 @@ class BuildScanInjectionGradleIntegrationTest extends BaseGradleIntegrationTest
gradlePluginVersion = GRADLE_ENTERPRISE_PLUGIN_VERSION
ccudPluginVersion = CCUD_PLUGIN_VERSION
gradlePluginRepositoryUrl = 'http://localhost/repository'
gradleCaptureTaskInputFiles = true
}

restartSlave(agent)
Expand All @@ -749,6 +752,7 @@ class BuildScanInjectionGradleIntegrationTest extends BaseGradleIntegrationTest
get("JENKINSGRADLEPLUGIN_GRADLE_ENTERPRISE_ALLOW_UNTRUSTED_SERVER") == "true"
get("JENKINSGRADLEPLUGIN_GRADLE_PLUGIN_REPOSITORY_URL") == "http://localhost/repository"
get("JENKINSGRADLEPLUGIN_CCUD_PLUGIN_VERSION") == "1.12.1"
get("JENKINSGRADLEPLUGIN_GRADLE_ENTERPRISE_CAPTURE_TASK_INPUT_FILES") == "true"
}
}

Expand All @@ -760,6 +764,7 @@ class BuildScanInjectionGradleIntegrationTest extends BaseGradleIntegrationTest
gradlePluginVersion = null
ccudPluginVersion = null
gradlePluginRepositoryUrl = null
gradleCaptureTaskInputFiles = false
}

restartSlave(agent)
Expand All @@ -774,6 +779,8 @@ class BuildScanInjectionGradleIntegrationTest extends BaseGradleIntegrationTest
get("JENKINSGRADLEPLUGIN_GRADLE_ENTERPRISE_ALLOW_UNTRUSTED_SERVER") == null
get("JENKINSGRADLEPLUGIN_GRADLE_PLUGIN_REPOSITORY_URL") == null
get("JENKINSGRADLEPLUGIN_CCUD_PLUGIN_VERSION") == null
get("JENKINSGRADLEPLUGIN_GRADLE_ENTERPRISE_ALLOW_UNTRUSTED_SERVER") == null
get("JENKINSGRADLEPLUGIN_GRADLE_ENTERPRISE_CAPTURE_TASK_INPUT_FILES") == null
}
}
}
Expand Down Expand Up @@ -908,6 +915,38 @@ class BuildScanInjectionGradleIntegrationTest extends BaseGradleIntegrationTest
quiet << [true, false]
}

def 'capture task input files toggle is processed by init script'(String gradleVersion) {
given:
gradleInstallationRule.gradleVersion = gradleVersion
gradleInstallationRule.addInstallation()

DumbSlave agent = createSlave()

FreeStyleProject project = j.createFreeStyleProject()
project.setAssignedNode(agent)

project.buildersList.add(helloTask())
project.buildersList.add(new Gradle(tasks: 'hello', gradleName: gradleVersion))

when:
// first build to download Gradle
def firstRun = j.buildAndAssertSuccess(project)

then:
j.assertLogNotContains(MSG_INIT_SCRIPT_APPLIED, firstRun)

when:
enableBuildInjection(agent, gradleVersion, null, false, true)
def secondRun = j.buildAndAssertSuccess(project)

then:
def log = JenkinsRule.getLog(secondRun)
log.contains('Connection to Develocity: http://foo.com, allowUntrustedServer: false, captureTaskInputFiles: true')

where:
gradleVersion << GRADLE_VERSIONS
}

private static CreateFileBuilder helloTask(String action = "println 'Hello!'") {
return new CreateFileBuilder('build.gradle', """
task hello {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ class BuildScanInjectionMavenIntegrationTest extends BaseMavenIntegrationTest {
}

when:
turnOnBuildInjectionAndRestart(agent)
turnOnBuildInjectionAndRestart(agent, true, true)

then:
with(getMavenOptsFromNodeProperties(agent).split(" ").iterator()) {
Expand All @@ -203,6 +203,9 @@ class BuildScanInjectionMavenIntegrationTest extends BaseMavenIntegrationTest {
with(it.next()) {
it == '-Dgradle.enterprise.url=https://scans.gradle.com'
}
with(it.next()) {
it == '-Dgradle.scan.captureGoalInputFiles=true'
}
!it.hasNext()
}

Expand Down Expand Up @@ -970,18 +973,20 @@ node {
enabled = true
server = 'https://scans.gradle.com'
injectMavenExtension = false
mavenCaptureGoalInputFiles = false
}

// sync changes
restartSlave(slave)
}

void turnOnBuildInjectionAndRestart(DumbSlave slave, Boolean useCCUD = true) {
void turnOnBuildInjectionAndRestart(DumbSlave slave, Boolean useCCUD = true, boolean captureGoalInputFiles = false) {
withInjectionConfig {
enabled = true
server = 'https://scans.gradle.com'
injectMavenExtension = true
injectCcudExtension = useCCUD
mavenCaptureGoalInputFiles = captureGoalInputFiles
}

// sync changes
Expand Down
Loading

0 comments on commit f8dae98

Please sign in to comment.