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

Support dependency resolution in CI mode #50

Merged
merged 2 commits into from
Aug 23, 2023
Merged
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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ following actions on the project and its submodules:
artifacts, which are the output of the build process, and the accompanying build-info file are stored and organized
in your Artifactory repository for easy access and management.

> **_NOTE:_** The minimum supported Gradle version to use this plugin is v6.9
> **_NOTE:_** The minimum supported Gradle version to use this plugin is v6.8.1

<details>
<summary> 🚚 Migrating from Version 4 to Version 5 of the Plugin</summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;

import static org.jfrog.gradle.plugin.artifactory.Constant.*;

public class GradleFunctionalTestBase {
// ArtifactoryManager
protected ArtifactoryManager artifactoryManager;
Expand All @@ -44,7 +46,7 @@ public class GradleFunctionalTestBase {

@DataProvider
public Object[][] gradleVersions() {
return new Object[][]{{"6.9.3"}, {"7.5.1"}, {"7.6"}, {"8.1"}};
return new Object[][]{{"6.8.1"}, {"7.5.1"}, {"7.6"}, {"8.1"}};
}

@BeforeClass
Expand Down Expand Up @@ -97,6 +99,9 @@ public void runPublishCITest(String gradleVersion, Path sourceDir, boolean clean
testEnvCreator.create();
Map<String, String> extendedEnv = new HashMap<>(envVars) {{
put(BuildInfoConfigProperties.PROP_PROPS_FILE, TestConstant.BUILD_INFO_PROPERTIES_TARGET.toString());
put(RESOLUTION_URL_ENV, getArtifactoryUrl() + virtualRepo);
put(RESOLUTION_USERNAME_ENV, getUsername());
put(RESOLUTION_PASSWORD_ENV, getAdminToken());
}};
// Run Gradle
BuildResult buildResult = Utils.runGradleArtifactoryPublish(gradleVersion, extendedEnv, true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ public class TestConstant {
public static final Path GRADLE_KTS_EXAMPLE_PUBLISH = PROJECTS_ROOT.resolve("gradle-kts-example-publish");
public static final Path GRADLE_EXAMPLE_CI_SERVER = PROJECTS_ROOT.resolve("gradle-example-ci-server");
public static final Path GRADLE_EXAMPLE_CI_SERVER_ARCHIVES = PROJECTS_ROOT.resolve("gradle-example-ci-server-archives");
public static final Path GRADLE_EXAMPLE_VERSION_CATALOG_PRODUCER = PROJECTS_ROOT.resolve("gradle-example-version-catalog").resolve("producer");
public static final Path GRADLE_EXAMPLE_VERSION_CATALOG_CONSUMER = PROJECTS_ROOT.resolve("gradle-example-version-catalog").resolve("consumer");
public static final Path GRADLE_EXAMPLE_DEFAULT_BOM = PROJECTS_ROOT.resolve("gradle-example-default-bom");
public static final Path GRADLE_EXAMPLE_CUSTOM_BOM = PROJECTS_ROOT.resolve("gradle-example-custom-bom");

Expand Down Expand Up @@ -56,6 +58,9 @@ public class TestConstant {
// Android
public static final String GRADLE_ANDROID_VERSION = "8.2.1";

// Version catalog
public static final String MIN_GRADLE_VERSION_CATALOG_VERSION = "7.0";

// Results
public static final String ARTIFACTS_GROUP_ID = "/org/jfrog/test/gradle/publish/";
public static final String[] EXPECTED_ARTIFACTS = {
Expand All @@ -72,11 +77,25 @@ public class TestConstant {
"webservice/1.0-SNAPSHOT/webservice-1.0-SNAPSHOT.pom",
"webservice/1.0-SNAPSHOT/webservice-1.0-SNAPSHOT.properties"
};

public static final String[] EXPECTED_ARCHIVE_ARTIFACTS = {
"api/1.0-SNAPSHOT/api-1.0-SNAPSHOT.jar",
"shared/1.0-SNAPSHOT/shared-1.0-SNAPSHOT.jar",
"webservice/1.0-SNAPSHOT/webservice-1.0-SNAPSHOT.war",
};

public static final String[] EXPECTED_VERSION_CATALOG_PRODUCER_ARTIFACTS = {
"com/jfrog/gradle-version-catalog/1.0.0/gradle-version-catalog-1.0.0.module",
"com/jfrog/gradle-version-catalog/1.0.0/gradle-version-catalog-1.0.0.toml",
"com/jfrog/gradle-version-catalog/1.0.0/gradle-version-catalog-1.0.0.pom",
};

public static final String[] EXPECTED_VERSION_CATALOG_CONSUMER_ARTIFACTS = {
"com/jfrog/gradle-version-catalog-consumer/1.0.0/gradle-version-catalog-consumer-1.0.0.module",
"com/jfrog/gradle-version-catalog-consumer/1.0.0/gradle-version-catalog-consumer-1.0.0.jar",
"com/jfrog/gradle-version-catalog-consumer/1.0.0/gradle-version-catalog-consumer-1.0.0.pom",
};

public static final String[] EXPECTED_MODULE_ARTIFACTS = Stream.concat(
Stream.of(EXPECTED_ARTIFACTS),
Stream.of(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
package org.jfrog.gradle.plugin.artifactory.tests;

import org.jfrog.build.client.Version;
import org.jfrog.gradle.plugin.artifactory.GradleFunctionalTestBase;
import org.jfrog.gradle.plugin.artifactory.TestConstant;
import org.jfrog.gradle.plugin.artifactory.utils.Utils;
import org.jfrog.gradle.plugin.artifactory.utils.ValidationUtils;
import org.testng.SkipException;
import org.testng.annotations.Test;

import java.io.IOException;

import static org.jfrog.gradle.plugin.artifactory.TestConstant.EXPECTED_VERSION_CATALOG_PRODUCER_ARTIFACTS;
import static org.jfrog.gradle.plugin.artifactory.TestConstant.MIN_GRADLE_VERSION_CATALOG_VERSION;

public class PluginCiPublishTest extends GradleFunctionalTestBase {
@Test(dataProvider = "gradleVersions")
public void ciServerTest(String gradleVersion) throws IOException {
Expand Down Expand Up @@ -48,4 +53,20 @@ public void ciServerArchivesTest(String gradleVersion) throws IOException {
buildResult -> ValidationUtils.checkArchivesBuildResults(artifactoryManager, buildResult, localRepo)
);
}

@Test(dataProvider = "gradleVersions")
public void versionCatalogTest(String gradleVersion) throws IOException {
if (!new Version(gradleVersion).isAtLeast(new Version(MIN_GRADLE_VERSION_CATALOG_VERSION))) {
throw new SkipException("Version catalog test requires at least Gradle version " + MIN_GRADLE_VERSION_CATALOG_VERSION);
}
runPublishCITest(gradleVersion, TestConstant.GRADLE_EXAMPLE_VERSION_CATALOG_PRODUCER, false,
() -> Utils.generateBuildInfoProperties(this, "versionCatalogProducer", false, true),
buildResult -> ValidationUtils.verifyArtifacts(artifactoryManager, localRepo + "/", EXPECTED_VERSION_CATALOG_PRODUCER_ARTIFACTS)
);

runPublishCITest(gradleVersion, TestConstant.GRADLE_EXAMPLE_VERSION_CATALOG_CONSUMER, true,
() -> Utils.generateBuildInfoProperties(this, "versionCatalogConsumer", true, true),
buildResult -> ValidationUtils.checkVersionCatalogResults(artifactoryManager, buildResult, virtualRepo)
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ public static BuildResult runGradleArtifactoryPublish(String gradleVersion, Map<
* @return result of the task
*/
public static BuildResult runPluginTask(String gradleVersion, File projectDir, String taskName, Map<String, String> envVars, boolean applyInitScript) throws IOException {
List<String> arguments = new ArrayList<>(Arrays.asList("clean", taskName, "--stacktrace"));
List<String> arguments = new ArrayList<>(Arrays.asList("clean", "build", taskName, "--stacktrace"));
if (applyInitScript) {
generateInitScript();
arguments.add("--init-script=gradle.init");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
import static org.apache.commons.lang3.StringUtils.equalsAny;
import static org.gradle.testkit.runner.TaskOutcome.SUCCESS;
import static org.jfrog.build.extractor.BuildInfoExtractorUtils.jsonStringToBuildInfo;
import static org.jfrog.gradle.plugin.artifactory.Constant.*;
import static org.jfrog.gradle.plugin.artifactory.TestConstant.EXPECTED_VERSION_CATALOG_CONSUMER_ARTIFACTS;
import static org.testng.Assert.*;

public class ValidationUtils {
Expand Down Expand Up @@ -52,26 +54,74 @@ public static void checkArchivesBuildResults(ArtifactoryManager artifactoryManag
checkBuildResults(artifactoryManager, buildResult, localRepo, TestConstant.EXPECTED_ARCHIVE_ARTIFACTS, 1);
}

/**
* Check build results of a Gradle project that uses Gradle Version Catalog to resolve a dependency.
*
* @param artifactoryManager - The ArtifactoryManager client
* @param buildResult - The build results
* @param virtualRepo - Virtual Maven repository in Artifactory
* @throws IOException In case of any IO error
*/
public static void checkVersionCatalogResults(ArtifactoryManager artifactoryManager, BuildResult buildResult, String virtualRepo) throws IOException {
verifyArtifacts(artifactoryManager, virtualRepo + "/", EXPECTED_VERSION_CATALOG_CONSUMER_ARTIFACTS);

// Check build info
BuildInfo buildInfo = getBuildInfo(artifactoryManager, buildResult);
assertNotNull(buildInfo);
Module module = buildInfo.getModule("com.jfrog:gradle_tests_space:1.0.0");
assertNotNull(module);

// Check commons-lang3 in the dependencies list
List<Dependency> dependencies = module.getDependencies();
assertEquals(dependencies.size(), 1);
Dependency dependency = dependencies.get(0);
assertEquals(dependency.getId(), "org.apache.commons:commons-lang3:3.9");
}

private static void checkBuildResults(ArtifactoryManager artifactoryManager, BuildResult buildResult, String localRepo,
String[] expectedArtifacts, int expectedArtifactsPerModule) throws IOException {
// Assert all tasks ended with success outcome
assertProjectsSuccess(buildResult);

// Check that all expected artifacts uploaded to Artifactory
for (String expectedArtifact : expectedArtifacts) {
artifactoryManager.downloadHeaders(localRepo + TestConstant.ARTIFACTS_GROUP_ID + expectedArtifact);
}
verifyArtifacts(artifactoryManager, localRepo + TestConstant.ARTIFACTS_GROUP_ID, expectedArtifacts);

// Check buildInfo info
// Check build info
BuildInfo buildInfo = getBuildInfo(artifactoryManager, buildResult);
assertNotNull(buildInfo);
checkFilteredEnv(buildInfo);
checkBuildInfoModules(buildInfo, 3, expectedArtifactsPerModule);

// Check build info properties on published Artifacts
PropertySearchResult artifacts = artifactoryManager.searchArtifactsByProperties(String.format("build.name=%s;build.number=%s", buildInfo.getName(), buildInfo.getNumber()));
assertTrue(artifacts.getResults().size() >= expectedArtifacts.length);
}

/**
* Make sure the generated build info does not contain any secret environment variables.
*
* @param buildInfo - The build info
*/
private static void checkFilteredEnv(BuildInfo buildInfo) {
buildInfo.getProperties().forEach((key, value) -> assertFalse(StringUtils.containsAny(key.toString(),
RESOLUTION_URL_ENV, RESOLUTION_USERNAME_ENV, RESOLUTION_PASSWORD_ENV,
"password", "psw", "secret", "key", "token")));
}

/**
* Check that all expected artifacts uploaded to Artifactory
*
* @param artifactoryManager - The ArtifactoryManager client
* @param repoPath - Path prefix including the repository name
* @param expectedArtifacts - Expected artifacts relatively to the repoPath
* @throws IOException In case of any IO error
*/
public static void verifyArtifacts(ArtifactoryManager artifactoryManager, String repoPath, String[] expectedArtifacts) throws IOException {
for (String expectedArtifact : expectedArtifacts) {
artifactoryManager.downloadHeaders(repoPath + expectedArtifact);
}
}

private static void assertProjectsSuccess(BuildResult buildResult) {
assertSuccess(buildResult, ":api:artifactoryPublish");
assertSuccess(buildResult, ":shared:artifactoryPublish");
Expand Down Expand Up @@ -123,7 +173,7 @@ private static void checkBuildInfoModules(BuildInfo buildInfo, int expectedModul

switch (module.getId()) {
case "org.jfrog.test.gradle.publish:webservice:1.0-SNAPSHOT":
assertEquals(module.getDependencies().size(), 7);
assertEquals(module.getDependencies().size(), 12);
if (expectedArtifactsPerModule > 0) {
checkWebserviceArtifact(module);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ dependencies {
implementation project(':shared'), 'commons-collections:commons-collections:3.2@jar', 'commons-io:commons-io:1.2', 'org.apache.commons:commons-lang3:3.12.0@jar'
implementation group: 'org.apache.wicket', name: 'wicket', version: '1.3.7'
implementation project(':api')
testImplementation('org.testng:testng:5.14.10')
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ dependencies {
implementation project(':shared'), 'commons-collections:commons-collections:3.2@jar', 'commons-io:commons-io:1.2', 'org.apache.commons:commons-lang3:3.12.0@jar'
implementation group: 'org.apache.wicket', name: 'wicket', version: '1.3.7'
implementation project(':api')
testImplementation('org.testng:testng:5.14.10')
}

war {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ dependencies {
implementation project(':shared'), 'commons-collections:commons-collections:3.2@jar', 'commons-io:commons-io:1.2', 'org.apache.commons:commons-lang3:3.12.0@jar'
implementation group: 'org.apache.wicket', name: 'wicket', version: '1.3.7'
implementation project(':api')
testImplementation('org.testng:testng:5.14.10')
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
plugins {
id 'version-catalog'
id 'maven-publish'
id 'application'
}

group = 'com.jfrog'
version = '1.0.0'
dependencies {
implementation libs.commons.lang3
}

publishing {
publications {
versionCatalogConsumer(MavenPublication) {
from components.java
artifactId = 'gradle-version-catalog-consumer'
}
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
dependencyResolutionManagement {
versionCatalogs {
libs {
from("com.jfrog:gradle-version-catalog:1.0.0")
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.jfrog.main;

import org.apache.commons.lang3.StringUtils;

public class Main {
public static void main(String[] args) {
System.out.println(StringUtils.isBlank(""));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
plugins {
id 'version-catalog'
id 'maven-publish'
id 'base'
}

group = 'com.jfrog'
version = '1.0.0'
catalog {
versionCatalog {
library('commons-lang3', 'org.apache.commons:commons-lang3:3.9')
}
}

publishing {
publications {
versionCatalogProducer(MavenPublication) {
from components.versionCatalog
artifactId = 'gradle-version-catalog'
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@ dependencies {
implementation("org.apache.commons:commons-lang3:3.12.0@jar")
implementation("org.apache.wicket", "wicket", "1.3.7")
implementation(project(":api"))
testImplementation("org.testng:testng:5.14.10")
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# Resolver settings
buildInfoConfig.includeEnvVars = true
resolve.contextUrl=${contextUrl}
resolve.repoKey=${virtualRepo}
resolve.username=${username}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
package org.jfrog.gradle.plugin.artifactory;

import org.gradle.api.GradleException;
import org.gradle.api.Plugin;
import org.gradle.api.Project;
import org.gradle.api.logging.Logger;
import org.gradle.api.logging.Logging;
import org.gradle.api.tasks.TaskProvider;
import org.jfrog.build.client.Version;
import org.jfrog.gradle.plugin.artifactory.dsl.ArtifactoryPluginConvention;
import org.jfrog.gradle.plugin.artifactory.listener.ArtifactoryDependencyResolutionListener;
import org.jfrog.gradle.plugin.artifactory.listener.ProjectsEvaluatedBuildListener;
Expand All @@ -15,6 +13,8 @@
import org.jfrog.gradle.plugin.artifactory.utils.ProjectUtils;
import org.jfrog.gradle.plugin.artifactory.utils.TaskUtils;

import static org.jfrog.gradle.plugin.artifactory.utils.PluginUtils.assertGradleVersionSupported;

public class ArtifactoryPlugin implements Plugin<Project> {
private static final Logger log = Logging.getLogger(ArtifactoryPlugin.class);
private final ArtifactoryDependencyResolutionListener resolutionListener = new ArtifactoryDependencyResolutionListener();
Expand Down Expand Up @@ -57,16 +57,10 @@ private boolean shouldApplyPluginOnProject(Project project) {
log.debug("Artifactory Plugin disabled for {}", project.getPath());
return false;
}
if (!isGradleVersionSupported(project)) {
throw new GradleException("Can't apply Artifactory Plugin on Gradle version " + project.getGradle().getGradleVersion() + ". Minimum supported Gradle version is " + Constant.MIN_GRADLE_VERSION);
}
assertGradleVersionSupported(project.getGradle());
return true;
}

public boolean isGradleVersionSupported(Project project) {
return new Version(project.getGradle().getGradleVersion()).isAtLeast(Constant.MIN_GRADLE_VERSION);
}

public ArtifactoryDependencyResolutionListener getResolutionListener() {
return resolutionListener;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package org.jfrog.gradle.plugin.artifactory;

import org.apache.commons.lang3.StringUtils;
import org.gradle.api.Plugin;
import org.gradle.api.credentials.PasswordCredentials;
import org.gradle.api.initialization.Settings;

import static org.jfrog.gradle.plugin.artifactory.Constant.*;
import static org.jfrog.gradle.plugin.artifactory.utils.PluginUtils.assertGradleVersionSupported;

@SuppressWarnings("unused")
public class ArtifactoryPluginSettings implements Plugin<Settings> {
@Override
public void apply(Settings settings) {
assertGradleVersionSupported(settings.getGradle());
String resolveContextUrl = System.getenv(RESOLUTION_URL_ENV);
if (resolveContextUrl == null) {
return;
}
settings.getDependencyResolutionManagement().getRepositories().maven(mavenArtifactRepository -> {
mavenArtifactRepository.setName("artifactoryResolutionRepository");
mavenArtifactRepository.setUrl(resolveContextUrl);
if (StringUtils.isNoneBlank(System.getenv(RESOLUTION_USERNAME_ENV), System.getenv(RESOLUTION_PASSWORD_ENV))) {
mavenArtifactRepository.credentials(PasswordCredentials.class);
}
});
}
}
Loading
Loading