diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9963f57..f82fb8c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -27,5 +27,7 @@ jobs: - name: Build uses: eskatos/gradle-command-action@v1.3.3 - with: - arguments: build + env: + TEST_UPLOAD_TOKEN: ${{secrets.TEST_UPLOAD_TOKEN}} + with: + arguments: build -i diff --git a/README.md b/README.md index 37ffdfe..798a543 100644 --- a/README.md +++ b/README.md @@ -130,8 +130,14 @@ apply(plugin = "at.schrottner.gitlab-repositories") The plugin offers you a nice helper method inspired by `gradle-jruby-plugin` to easily add repositories. ```groovy -gitLab.maven(projectOrGroupId) -gitLab.maven(projectOrGroupId) { +gitLab.project(projectId) +gitLab.project(projectId) { + name = "custom name" + tokenSelektor = "" // a name of a configured token + tokenSelectors = [] // a list of configured tokens, which will be checked based on their order in this set +} +gitLab.group(groupId) +gitLab.group(groupId) { name = "custom name" tokenSelektor = "" // a name of a configured token tokenSelectors = [] // a list of configured tokens, which will be checked based on their order in this set @@ -139,13 +145,13 @@ gitLab.maven(projectOrGroupId) { ``` For adding a repository to the maven-publish repositories please use following method. The `owner` needs to be provided -and is a reference to the `repositories`. +and is a reference to the `repositories`. Be aware that this has to be a groupId ```groovy publishing { repositories { - gitLab.upload(owner, projectOrGroupId) - gitLab.upload(owner, projectOrGroupId) { + gitLab.upload(owner, projectId) + gitLab.upload(owner, projectId) { name = "custom name" tokenSelektor = "" // a name of a configured token tokenSelectors = [] // a list of configured tokens, which will be checked based on their order in this set @@ -159,7 +165,8 @@ publishing { This will add a repository and will apply conditions for the first token matching, and not being empty. ```groovy -gitLab.maven(1) +gitLab.project(1) +gitLab.group(1) ``` ### Adding a repository with specific tokens @@ -167,7 +174,10 @@ gitLab.maven(1) We can define which tokens should be taken into account (currently order of parameter is ignored) ```groovy -gitLab.maven(1) { +gitLab.project(1) { + tokenSelectors = ['private', 'deploy'] +} +gitLab.group(1) { tokenSelectors = ['private', 'deploy'] } ``` @@ -175,7 +185,8 @@ gitLab.maven(1) { Additionally, we can provide one specific token to be used, if the token is not set, or empty, nothing will be done. ```groovy -gitLab.maven(1) { tokenSelector = 'deploy' } +gitLab.project(1) { tokenSelector = 'deploy' } +gitLab.group(1) { tokenSelector = 'deploy' } ``` ## Comparison @@ -202,7 +213,7 @@ gitLab { } repositories { - gitLab.maven("ID") + gitLab.group("ID") } publishing { diff --git a/src/functionalTest/groovy/at/schrottner/gradle/GitlabRepositoriesPluginFunctionalTests.groovy b/src/functionalTest/groovy/at/schrottner/gradle/GitlabRepositoriesPluginFunctionalTests.groovy index 10319b6..8dc2c73 100644 --- a/src/functionalTest/groovy/at/schrottner/gradle/GitlabRepositoriesPluginFunctionalTests.groovy +++ b/src/functionalTest/groovy/at/schrottner/gradle/GitlabRepositoriesPluginFunctionalTests.groovy @@ -8,10 +8,16 @@ import org.gradle.testkit.runner.GradleRunner import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test import org.junit.jupiter.api.io.TempDir +import org.slf4j.Logger +import org.slf4j.LoggerFactory + +import java.nio.file.Files import static org.assertj.core.api.Assertions.assertThat class GitlabRepositoriesPluginFunctionalTests { + + private static final Logger logger = LoggerFactory.getLogger(GitlabRepositoriesPluginFunctionalTests.class) private pluginClasspath = getClass().classLoader.findResource("plugin-classpath.txt") .readLines() .collect { it.replace('\\\\', '\\\\\\\\') } // escape backslashes in Windows paths @@ -103,7 +109,28 @@ class GitlabRepositoriesPluginFunctionalTests { @Test void "used in settings and project"() { + + if (!System.getenv('TEST_UPLOAD_TOKEN')) { + + logger.warn """ +########################################################## +########################################################## +########################################################## +########################################################## + This tests runs without an attempt of uploading + Please configure a TEST_UPLOAD_TOKEN which has + upload rights. +########################################################## +########################################################## +########################################################## +########################################################## +""" + } //given: + def file = new File(getClass().getResource('/test.xml').toURI()) + + Files.copy(file.toPath(), projectDir.toPath().resolve(file.name)) + settingsGradle << """ $apply gitLab { @@ -124,6 +151,10 @@ class GitlabRepositoriesPluginFunctionalTests { apply plugin: at.schrottner.gradle.GitlabRepositoriesPlugin gitLab { ${generateToken('PrivateToken', 'PrivateToken')} + token(PrivateToken) { + it.key = 'testToken' + it.value = '${System.getenv('TEST_UPLOAD_TOKEN')}' + } } publishing { repositories { @@ -132,9 +163,9 @@ class GitlabRepositoriesPluginFunctionalTests { name = "NotAdded" tokenSelector = "jobToken" } - gitLab.upload(owner, "testAdded") { + gitLab.upload(owner, "24974077") { name = "GitLab" - tokenSelector = "token1" + tokenSelector = "testToken" } gitLab.upload(owner, "testAdded") { name = "GitLabSettingsToken" @@ -144,10 +175,24 @@ class GitlabRepositoriesPluginFunctionalTests { name = "GitLabAnyToken" } } + + publications { + test(MavenPublication) { + artifactId 'test-file' + groupId 'at.schrottner.test.gitlab-repositories' + version 'test-SNAPSHOT' + artifact source: 'test.xml', classifier: 'features' + } + } } """ //when: - BuildResult result = runTest() + def runner = GradleRunner.create() + runner.forwardOutput() + runner.withPluginClasspath() + runner.withArguments("tasks", "-i", "-s") + runner.withProjectDir(projectDir) + def result = runner.build() //then: assertThat(result.output) @@ -160,12 +205,23 @@ class GitlabRepositoriesPluginFunctionalTests { "Settings evaluated", "replaced Job-Token: jobToken", "replaced Private-Token: token0", - "replaced Private-Token: token1" + "replaced Private-Token: token1", + "added Private-Token: testToken" ) .contains("publishAllPublicationsToGitLabSettingsTokenRepository") .contains("publishAllPublicationsToGitLabAnyTokenRepository") .contains("publishAllPublicationsToGitLabRepository") .contains("Maven Repository NotAdded was not added, as no token could be applied!\n") + + if (System.getenv('TEST_UPLOAD_TOKEN')) { + def uploadRunner = GradleRunner.create() + uploadRunner.forwardOutput() + uploadRunner.withPluginClasspath() + uploadRunner.withArguments("publishTestPublicationToGitLabRepository", "-i", "-s") + uploadRunner.withProjectDir(projectDir) + def uploadResult = uploadRunner.build() + assertThat(uploadResult.output).contains("Publishing to repository 'GitLab'") + } } def getApply() { diff --git a/src/functionalTest/resources/test.xml b/src/functionalTest/resources/test.xml new file mode 100644 index 0000000..1237337 --- /dev/null +++ b/src/functionalTest/resources/test.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/src/main/groovy/at/schrottner/gradle/GitlabRepositoriesExtension.groovy b/src/main/groovy/at/schrottner/gradle/GitlabRepositoriesExtension.groovy index e4d88c3..fbff3c6 100644 --- a/src/main/groovy/at/schrottner/gradle/GitlabRepositoriesExtension.groovy +++ b/src/main/groovy/at/schrottner/gradle/GitlabRepositoriesExtension.groovy @@ -2,6 +2,8 @@ package at.schrottner.gradle import at.schrottner.gradle.auths.JobToken import at.schrottner.gradle.auths.Token +import at.schrottner.gradle.mavenConfigs.GroupMavenConfig +import at.schrottner.gradle.mavenConfigs.ProjectMavenConfig import org.gradle.api.Action import org.gradle.api.Project import org.gradle.api.artifacts.dsl.RepositoryHandler @@ -10,35 +12,30 @@ import org.gradle.api.artifacts.repositories.MavenArtifactRepository import org.gradle.api.credentials.HttpHeaderCredentials import org.gradle.api.initialization.Settings import org.gradle.authentication.http.HttpHeaderAuthentication -import org.slf4j.Logger import org.slf4j.LoggerFactory -public class GitlabRepositoriesExtension { +public class GitlabRepositoriesExtension implements LogHandler { public static final String NAME = "gitLab" public static final String REPOSITORY_PREFIX = "GITLAB-" - public static final String LOG_PREFIX = "GitLab Repositories" - private final Logger logger private final RepositoryHandler repositories private int afterPosition - protected String logPrefix String baseUrl = "gitlab.com" String afterRepository = 'MavenLocal' boolean applyToProject = true - boolean applySettingTokens = true Map tokens = [:] public static final def artifacts = [:] GitlabRepositoriesExtension(Settings settings) { - logPrefix = "$LOG_PREFIX :: Settings ::" + this.logPrefix = "Settings" this.logger = LoggerFactory.getLogger(GitlabRepositoriesExtension.class) this.repositories = settings.pluginManagement.repositories setup() } GitlabRepositoriesExtension(Project project) { - logPrefix = "$LOG_PREFIX :: Project ($project.name) ::" + this.logPrefix = "Project ($project.name)" this.logger = project.logger this.repositories = project.repositories migrateSettingsTokens(project) @@ -57,10 +54,6 @@ public class GitlabRepositoriesExtension { } } - def getLogger() { - logger ?: LoggerFactory.getLogger(GitlabRepositoriesExtension.class) - } - void setup() { logger.info("$logPrefix initializing") token(JobToken, { @@ -84,67 +77,53 @@ public class GitlabRepositoriesExtension { } MavenArtifactRepository upload(def delegate, String id, Action configAction = null) { - if (!id) { - logger.info("$logPrefix: No ID provided nothing will happen here :)") - return null + mavenInternal(new ProjectMavenConfig(id), configAction) { repo -> + delegate.maven(repo) } - def mavenConfig = new MavenConfig(id) + } - configAction?.execute(mavenConfig) + MavenArtifactRepository group(String id, Action configAction = null) { + mavenInternal(new GroupMavenConfig(id), configAction) + } - Map applicableTokens = getApplicableTokens(mavenConfig) + MavenArtifactRepository project(String id, Action configAction = null) { - def artifactRepo = generateMavenArtifactRepositoryAction( - mavenConfig.name, - id, - applicableTokens) - if (artifactRepo) - (delegate as RepositoryHandler).maven(artifactRepo) + mavenInternal(new ProjectMavenConfig(id), configAction) } + /** - * Generates a MavenArtifactRepository and adds it to the maven repositories. - * - * Additionally the generated Repository will be stored in a static variable, - * which can later be used to be applied to evaluated projects. - * - * @param id id of the GitLab Group or Project, where you want to fetch from - * @param configAction to configure the MavenConfiguration - * @return + * @deprecated use{@link #group(id, configAction)} or {@link #project(id, configAction)} */ + @Deprecated MavenArtifactRepository maven(String id, Action configAction = null) { - if (!id) { + group(id, configAction) + } + + MavenArtifactRepository mavenInternal(MavenConfig mavenConfig, + Action configAction = null, + Closure action = null) { + + if (!mavenConfig.id) { logger.info("$logPrefix: No ID provided nothing will happen here :)") return null } - def mavenConfig = new MavenConfig(id) configAction?.execute(mavenConfig) - def repoName = mavenConfig.name - if (!repositories.findByName(repoName)) { - - Map applicableTokens = getApplicableTokens(mavenConfig) + Map applicableTokens = getApplicableTokens(mavenConfig) - def artifactRepo = generateMavenArtifactRepositoryAction( - repoName, - id, - applicableTokens) + def artifactRepo = generateMavenArtifactRepositoryAction( + mavenConfig, + applicableTokens) - return applyMaven(artifactRepo) - } else { - def existingRepo = repositories.getByName(repoName) - if (existingRepo instanceof MavenArtifactRepository) { - logger.info("$logPrefix: Maven Repository with $repoName already exists!") - return existingRepo - } else { - logger.info("$logPrefix: Repository with $repoName already exists - but it is not a Maven Repository!") - return null - } - } + if (artifactRepo) + if (action) + action(artifactRepo) + else + applyMaven(artifactRepo) } private MavenArtifactRepository applyMaven(Action artifactRepo) { - if (!artifactRepo) return null def repo = repositories.maven(artifactRepo) repositories.remove(repo) @@ -154,7 +133,7 @@ public class GitlabRepositoriesExtension { } private Map getApplicableTokens(MavenConfig mavenConfig) { - Map applicableTokens = mavenConfig.tokenSelectors.collectEntries { + Map applicableTokens = (mavenConfig.tokenSelectors ?: tokens.keySet()).collectEntries { def token = tokens.get(it) if (token) [{ it }: token] @@ -164,17 +143,17 @@ public class GitlabRepositoriesExtension { applicableTokens } - private Action generateMavenArtifactRepositoryAction(repoName, id, Map tokens) { + private Action generateMavenArtifactRepositoryAction(mavenConfig, Map tokens) { Token token = tokens.values().find { token -> token.value } if (token) { - logger.info("$logPrefix: Maven Repository $repoName is using '${token.key}'") + logger.info("$logPrefix: Maven Repository $mavenConfig.name is using '${token.key}'") def artifactRepo = new Action() { @Override void execute(MavenArtifactRepository mvn) { - mvn.url = "https://$baseUrl/api/v4/groups/$id/-/packages/maven" - mvn.name = repoName + mvn.url = mavenConfig.buildUrl(baseUrl) + mvn.name = mavenConfig.name mvn.credentials(HttpHeaderCredentials) { it.name = token.name @@ -189,51 +168,25 @@ public class GitlabRepositoriesExtension { } } - artifacts[repoName] = artifactRepo + artifacts[mavenConfig] = artifactRepo return artifactRepo } else { - logger.error("$LOG_PREFIX: Maven Repository $repoName was not added, as no token could be applied!\n\t" - + "\n\t" - + "#################################################################################### \n\t" - + "#################################################################################### \n\t" - + "#################################################################################### \n\t" - + "Currently you have configured following tokens, but non seem to resolve to an value: \n\t" - + "\t- ${tokens.keySet().join("\n\t\t- ")} \n\t" - + "\n\t" - + " Please verify your configuration - Thank you! \n\t" - + "\n\t" - + "#################################################################################### \n\t" - + "#################################################################################### \n\t" - + "#################################################################################### \n\t" - + "") + logger.error("$logPrefix Maven Repository $mavenConfig.name was not added, as no token could be applied!\n\t" + + "\n\t" + + "#################################################################################### \n\t" + + "#################################################################################### \n\t" + + "#################################################################################### \n\t" + + "Currently you have configured following tokens, but non seem to resolve to an value: \n\t" + + "\t- ${tokens.keySet().join("\n\t\t- ")} \n\t" + + "\n\t" + + " Please verify your configuration - Thank you! \n\t" + + "\n\t" + + "#################################################################################### \n\t" + + "#################################################################################### \n\t" + + "#################################################################################### \n\t" + + "") return null } } - - private class MavenConfig { - String tokenSelector - Set tokenSelectors - String name - String id - - MavenConfig(String id) { - this.id = id - tokenSelectors = tokens.keySet() - } - - String getName() { - name ? "$name" : "$REPOSITORY_PREFIX$id" - } - - Set getTokenSelectors() { - if (tokenSelector) { - logger.info("$logPrefix: Maven Repository $name is using Single Token Selector '$tokenSelector' - other tokens will be ignored") - - [tokenSelector].toSet() - } else { - tokenSelectors - } - } - } } \ No newline at end of file diff --git a/src/main/groovy/at/schrottner/gradle/LogHandler.groovy b/src/main/groovy/at/schrottner/gradle/LogHandler.groovy new file mode 100644 index 0000000..0fae350 --- /dev/null +++ b/src/main/groovy/at/schrottner/gradle/LogHandler.groovy @@ -0,0 +1,17 @@ +package at.schrottner.gradle + +import org.slf4j.LoggerFactory + +trait LogHandler { + public static final String LOG_PREFIX = "GitLab Repositories" + static org.slf4j.Logger logger + String logPrefix + + def getLogger() { + logger ?: LoggerFactory.getLogger(GitlabRepositoriesExtension.class) + } + + def getLogPrefix() { + "$LOG_PREFIX :: $logPrefix ::" + } +} \ No newline at end of file diff --git a/src/main/groovy/at/schrottner/gradle/MavenConfig.groovy b/src/main/groovy/at/schrottner/gradle/MavenConfig.groovy new file mode 100644 index 0000000..a4faa2b --- /dev/null +++ b/src/main/groovy/at/schrottner/gradle/MavenConfig.groovy @@ -0,0 +1,29 @@ +package at.schrottner.gradle; + +import java.util.Set; + +trait MavenConfig implements LogHandler { + String tokenSelector + Set tokenSelectors + String name + String id + String endpoint + + String getName() { + name ? "$name" : "$GitlabRepositoriesExtension.REPOSITORY_PREFIX$id" + } + + Set getTokenSelectors() { + if (tokenSelector) { + logger.info("$logPrefix: Maven Repository $name is using Single Token Selector '$tokenSelector' - other tokens will be ignored") + + [tokenSelector].toSet() + } else { + tokenSelectors + } + } + + String buildUrl(String baseUrl) { + "https://$baseUrl/api/v4/$endpoint/$id/-/packages/maven" + } +} \ No newline at end of file diff --git a/src/main/groovy/at/schrottner/gradle/mavenConfigs/GroupMavenConfig.groovy b/src/main/groovy/at/schrottner/gradle/mavenConfigs/GroupMavenConfig.groovy new file mode 100644 index 0000000..4167c31 --- /dev/null +++ b/src/main/groovy/at/schrottner/gradle/mavenConfigs/GroupMavenConfig.groovy @@ -0,0 +1,11 @@ +package at.schrottner.gradle.mavenConfigs + +import at.schrottner.gradle.MavenConfig + +class GroupMavenConfig implements MavenConfig { + + GroupMavenConfig(String id) { + this.id = id + this.endpoint = "groups" + } +} \ No newline at end of file diff --git a/src/main/groovy/at/schrottner/gradle/mavenConfigs/ProjectMavenConfig.groovy b/src/main/groovy/at/schrottner/gradle/mavenConfigs/ProjectMavenConfig.groovy new file mode 100644 index 0000000..ac7dff9 --- /dev/null +++ b/src/main/groovy/at/schrottner/gradle/mavenConfigs/ProjectMavenConfig.groovy @@ -0,0 +1,16 @@ +package at.schrottner.gradle.mavenConfigs + +import at.schrottner.gradle.MavenConfig + +class ProjectMavenConfig implements MavenConfig { + + ProjectMavenConfig(String id) { + this.id = id + this.endpoint = "projects" + } + + @Override + String buildUrl(String baseUrl) { + "https://$baseUrl/api/v4/$endpoint/$id/packages/maven" + } +} \ No newline at end of file