├── gradle.properties ├── src ├── functionalTest │ ├── resources │ │ ├── _template │ │ │ ├── groovy │ │ │ │ ├── build.gradle │ │ │ │ └── settings.gradle │ │ │ └── kotlin │ │ │ │ ├── build.gradle.kts │ │ │ │ └── settings.gradle.kts │ │ ├── ApplyTest │ │ │ ├── onlyUsedInSettings │ │ │ │ ├── groovy │ │ │ │ │ ├── build.gradle │ │ │ │ │ └── settings.gradle │ │ │ │ └── kotlin │ │ │ │ │ ├── build.gradle.kts │ │ │ │ │ └── settings.gradle.kts │ │ │ ├── onlyUsedInProject │ │ │ │ ├── groovy │ │ │ │ │ ├── settings.gradle │ │ │ │ │ └── build.gradle │ │ │ │ └── kotlin │ │ │ │ │ ├── settings.gradle.kts │ │ │ │ │ └── build.gradle.kts │ │ │ ├── subprojectTest │ │ │ │ ├── groovy │ │ │ │ │ ├── settings.gradle │ │ │ │ │ ├── build.gradle │ │ │ │ │ ├── subproject2 │ │ │ │ │ │ └── build.gradle │ │ │ │ │ └── subproject1 │ │ │ │ │ │ └── build.gradle │ │ │ │ └── kotlin │ │ │ │ │ ├── settings.gradle │ │ │ │ │ ├── build.gradle │ │ │ │ │ ├── subproject2 │ │ │ │ │ └── build.gradle │ │ │ │ │ └── subproject1 │ │ │ │ │ └── build.gradle │ │ │ ├── usedInSettingsAndProjectWithoutApplying │ │ │ │ ├── groovy │ │ │ │ │ ├── build.gradle │ │ │ │ │ └── settings.gradle │ │ │ │ └── kotlin │ │ │ │ │ ├── settings.gradle.kts │ │ │ │ │ └── build.gradle.kts │ │ │ └── usedInSettingsAndProject │ │ │ │ ├── groovy │ │ │ │ ├── settings.gradle │ │ │ │ └── build.gradle │ │ │ │ └── kotlin │ │ │ │ ├── settings.gradle.kts │ │ │ │ └── build.gradle.kts │ │ ├── test.xml │ │ ├── GoogleRecommendationTest │ │ │ └── test │ │ │ │ └── groovy │ │ │ │ ├── app │ │ │ │ └── build.gradle │ │ │ │ ├── build.gradle │ │ │ │ └── settings.gradle │ │ └── UploadTest │ │ │ └── uploadtest │ │ │ ├── groovy │ │ │ ├── settings.gradle │ │ │ └── build.gradle │ │ │ └── kotlin │ │ │ ├── build.gradle.kts │ │ │ └── settings.gradle.kts │ └── groovy │ │ └── at │ │ └── schrottner │ │ └── gradle │ │ ├── testhelper │ │ ├── ReadMe.md │ │ ├── MappedParameterContext.java │ │ └── AfterBeforeParameterResolver.java │ │ ├── GoogleRecommendationTest.groovy │ │ ├── PluginTestParams.java │ │ ├── TestFileUtils.groovy │ │ ├── PluginTest.java │ │ ├── UploadTest.groovy │ │ ├── AbstractFunctionalTests.groovy │ │ └── ApplyTest.groovy ├── main │ └── groovy │ │ └── at │ │ └── schrottner │ │ └── gradle │ │ ├── Config.groovy │ │ ├── auths │ │ ├── Token.groovy │ │ └── GitLabTokenType.groovy │ │ ├── GitLabEntityType.groovy │ │ ├── RepositoryConfiguration.groovy │ │ ├── GitlabRepositoriesPlugin.groovy │ │ ├── GitlabRepositoriesExtension.groovy │ │ └── RepositoryActionHandler.groovy └── test │ └── groovy │ └── at │ └── schrottner │ └── gradle │ └── GitlabRepositoriesPluginTest.groovy ├── .clabot ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── renovate.json ├── .gitignore ├── _config.yml ├── license-header.spotless ├── settings.gradle ├── .github └── workflows │ ├── release.yml │ └── ci.yml ├── gradlew.bat ├── CODE_OF_CONDUCT.md ├── gradlew ├── README.md └── LICENSE.md /gradle.properties: -------------------------------------------------------------------------------- 1 | group=at.schrottner.gradle.gitlab-plugin -------------------------------------------------------------------------------- /src/functionalTest/resources/_template/groovy/build.gradle: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/functionalTest/resources/_template/groovy/settings.gradle: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/functionalTest/resources/_template/kotlin/build.gradle.kts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/functionalTest/resources/_template/kotlin/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/functionalTest/resources/ApplyTest/onlyUsedInSettings/groovy/build.gradle: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/functionalTest/resources/ApplyTest/onlyUsedInProject/groovy/settings.gradle: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/functionalTest/resources/ApplyTest/onlyUsedInProject/kotlin/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/functionalTest/resources/ApplyTest/onlyUsedInSettings/kotlin/build.gradle.kts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/functionalTest/resources/test.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /.clabot: -------------------------------------------------------------------------------- 1 | { 2 | "contributors": ["aepfli","renovate-bot", "renovate", "renovate[bot]"] 3 | } 4 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aepfli/gradle-gitlab-repositories/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | 2 | { 3 | "extends": [ 4 | "config:base", 5 | ":disableDependencyDashboard" 6 | ], 7 | "branchConcurrentLimit": 40, 8 | "prHourlyLimit": 0 9 | } 10 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore Gradle project-specific cache directory 2 | .gradle 3 | .idea 4 | 5 | # Ignore Gradle build output directory 6 | build 7 | out 8 | /bin/ 9 | /.classpath 10 | /.project 11 | /.settings 12 | -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-minimal 2 | title: Gradle GitLab Repositories Plugin 3 | description: Handling Maven GitLab dependencies easy. Define multiple tokens and selectively apply them to repositories. 4 | 5 | -------------------------------------------------------------------------------- /src/functionalTest/resources/GoogleRecommendationTest/test/groovy/app/build.gradle: -------------------------------------------------------------------------------- 1 | 2 | configurations { 3 | testing 4 | } 5 | 6 | dependencies { 7 | testing "at.schrottner.test.gitlab-repositories:test-file:test-SNAPSHOT@xml" 8 | } -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.9.4-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /src/functionalTest/resources/GoogleRecommendationTest/test/groovy/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | } 3 | 4 | configurations { 5 | testing 6 | } 7 | task clean(type: Delete) { 8 | delete rootProject.buildDir 9 | } 10 | subprojects { 11 | task allDeps(type: DependencyReportTask) {} 12 | } -------------------------------------------------------------------------------- /src/functionalTest/groovy/at/schrottner/gradle/testhelper/ReadMe.md: -------------------------------------------------------------------------------- 1 | first implementation in this package is copy pasted from 2 | 3 | https://github.com/lamektomasz/AfterBeforeParameterizedTestExtension/ 4 | 5 | Therefore i want to make a big shoutout to @lamektomasz for this nice piece of code. -------------------------------------------------------------------------------- /license-header.spotless: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2021 the original author or authors. 3 | * 4 | * All rights reserved. This program and the accompanying materials are 5 | * made available under the terms of the Eclipse Public License v2.0 which 6 | * accompanies this distribution and is available at 7 | * 8 | * http://www.eclipse.org/legal/epl-v20.html 9 | */ -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * This file was generated by the Gradle 'init' task. 3 | * 4 | * The settings file is used to specify which projects to include in your build. 5 | * 6 | * Detailed information about configuring a multi-project build in Gradle can be found 7 | * in the user manual at https://docs.gradle.org/5.6.4/userguide/multi_project_builds.html 8 | */ 9 | 10 | rootProject.name = 'gitlab-repositories' 11 | -------------------------------------------------------------------------------- /src/functionalTest/groovy/at/schrottner/gradle/GoogleRecommendationTest.groovy: -------------------------------------------------------------------------------- 1 | package at.schrottner.gradle; 2 | 3 | import org.gradle.testkit.runner.BuildResult; 4 | import org.junit.jupiter.params.ParameterizedTest; 5 | import org.junit.jupiter.params.provider.ValueSource; 6 | 7 | class GoogleRecommendationTest extends AbstractFunctionalTests { 8 | 9 | @ParameterizedTest 10 | @ValueSource(strings = ["groovy"]) 11 | void "test"(String primer) { 12 | //given: 13 | 14 | //when: 15 | BuildResult result = runTest("allDeps","-i","--refresh-dependencies") 16 | 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/groovy/at/schrottner/gradle/Config.groovy: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2021 the original author or authors. 3 | * 4 | * All rights reserved. This program and the accompanying materials are 5 | * made available under the terms of the Eclipse Public License v2.0 which 6 | * accompanies this distribution and is available at 7 | * 8 | * http://www.eclipse.org/legal/epl-v20.html 9 | */ 10 | package at.schrottner.gradle 11 | 12 | class Config { 13 | public static final String LOG_PREFIX = "GitLab Repositories ::" 14 | public static final String GROUP = "Group" 15 | public static final String PROJECT = "Project" 16 | } 17 | -------------------------------------------------------------------------------- /src/functionalTest/groovy/at/schrottner/gradle/PluginTestParams.java: -------------------------------------------------------------------------------- 1 | package at.schrottner.gradle; 2 | 3 | import org.junit.jupiter.api.extension.ExtensionContext; 4 | import org.junit.jupiter.params.provider.Arguments; 5 | import org.junit.jupiter.params.provider.ArgumentsProvider; 6 | 7 | import java.util.stream.Stream; 8 | 9 | public class PluginTestParams implements ArgumentsProvider { 10 | @Override 11 | public Stream provideArguments(ExtensionContext context) { 12 | return Stream.of( 13 | Arguments.of("groovy"), 14 | Arguments.of("kotlin") 15 | ); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/functionalTest/resources/ApplyTest/subprojectTest/groovy/settings.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | dependencies { 3 | classpath files(pluginClasspath.split(',')) 4 | } 5 | } 6 | apply plugin: at.schrottner.gradle.GitlabRepositoriesPlugin 7 | 8 | gitLab { 9 | token(PrivateToken) { 10 | it.key = 'tokenIgnoredNoValue' 11 | it.value = '' 12 | } 13 | token(DeployToken) { 14 | it.key = 'token0' 15 | it.value = 'test' 16 | } 17 | token(DeployToken) { 18 | it.key = 'token1' 19 | it.value = 'test' 20 | } 21 | } 22 | 23 | pluginManagement.repositories { 24 | realms.split(',').each { realm -> 25 | maven gitLab."$realm"("$existingId") 26 | } 27 | } 28 | 29 | include 'subproject1', 'subproject2' -------------------------------------------------------------------------------- /src/functionalTest/resources/ApplyTest/subprojectTest/kotlin/settings.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | dependencies { 3 | classpath files(pluginClasspath.split(',')) 4 | } 5 | } 6 | apply plugin: at.schrottner.gradle.GitlabRepositoriesPlugin 7 | 8 | gitLab { 9 | token(PrivateToken) { 10 | it.key = 'tokenIgnoredNoValue' 11 | it.value = '' 12 | } 13 | token(DeployToken) { 14 | it.key = 'token0' 15 | it.value = 'test' 16 | } 17 | token(DeployToken) { 18 | it.key = 'token1' 19 | it.value = 'test' 20 | } 21 | } 22 | 23 | pluginManagement.repositories { 24 | realms.split(',').each { realm -> 25 | maven gitLab."$realm"("$existingId") 26 | } 27 | } 28 | 29 | include 'subproject1', 'subproject2' -------------------------------------------------------------------------------- /src/main/groovy/at/schrottner/gradle/auths/Token.groovy: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2021 the original author or authors. 3 | * 4 | * All rights reserved. This program and the accompanying materials are 5 | * made available under the terms of the Eclipse Public License v2.0 which 6 | * accompanies this distribution and is available at 7 | * 8 | * http://www.eclipse.org/legal/epl-v20.html 9 | */ 10 | package at.schrottner.gradle.auths 11 | 12 | /** 13 | * TODO: 14 | * - rework tokens - this subclassing is ridiculous and should be reflected by a enum 15 | */ 16 | public class Token { 17 | GitLabTokenType type 18 | String value 19 | String key 20 | 21 | Token(GitLabTokenType type) { 22 | this.type = type 23 | } 24 | } -------------------------------------------------------------------------------- /src/functionalTest/resources/ApplyTest/subprojectTest/groovy/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | dependencies { 3 | classpath files(pluginClasspath.split(',')) 4 | } 5 | } 6 | apply plugin: at.schrottner.gradle.GitlabRepositoriesPlugin 7 | 8 | gitLab { 9 | token(PrivateToken) { 10 | it.key = 'tokenIgnoredNoValue' 11 | it.value = '' 12 | } 13 | token(PrivateToken) { 14 | it.key = 'token0' 15 | it.value = 'test' 16 | } 17 | token(PrivateToken) { 18 | it.key = 'token1' 19 | it.value = 'test' 20 | } 21 | token(DeployToken) { 22 | it.key = 'tokenAdded' 23 | it.value = 'test' 24 | } 25 | } 26 | repositories { 27 | realms.split(',').each { realm -> 28 | 29 | maven gitLab."$realm"("$existingId") 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/functionalTest/resources/ApplyTest/subprojectTest/kotlin/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | dependencies { 3 | classpath files(pluginClasspath.split(',')) 4 | } 5 | } 6 | apply plugin: at.schrottner.gradle.GitlabRepositoriesPlugin 7 | 8 | gitLab { 9 | token(PrivateToken) { 10 | it.key = 'tokenIgnoredNoValue' 11 | it.value = '' 12 | } 13 | token(PrivateToken) { 14 | it.key = 'token0' 15 | it.value = 'test' 16 | } 17 | token(PrivateToken) { 18 | it.key = 'token1' 19 | it.value = 'test' 20 | } 21 | token(DeployToken) { 22 | it.key = 'tokenAdded' 23 | it.value = 'test' 24 | } 25 | } 26 | repositories { 27 | realms.split(',').each { realm -> 28 | 29 | maven gitLab."$realm"("$existingId") 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/functionalTest/resources/ApplyTest/subprojectTest/groovy/subproject2/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | dependencies { 3 | classpath files(pluginClasspath.split(',')) 4 | } 5 | } 6 | apply plugin: at.schrottner.gradle.GitlabRepositoriesPlugin 7 | 8 | gitLab { 9 | token(DeployToken) { 10 | it.key = 'tokenAdded' 11 | it.value = 'test' 12 | } 13 | token(DeployToken) { 14 | it.key = 'tokenAdded1' 15 | it.value = '' 16 | } 17 | token(DeployToken) { 18 | it.key = 'token0' 19 | it.value = 'test' 20 | } 21 | } 22 | repositories { 23 | realms.split(',').each { realm -> 24 | maven gitLab."$realm"("tokentest") { 25 | tokenSelector = "tokenAdded" 26 | } 27 | maven gitLab."$realm"("tokentest1") { 28 | tokenSelector = "tokenAdded1" 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/functionalTest/resources/ApplyTest/subprojectTest/kotlin/subproject2/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | dependencies { 3 | classpath files(pluginClasspath.split(',')) 4 | } 5 | } 6 | apply plugin: at.schrottner.gradle.GitlabRepositoriesPlugin 7 | 8 | gitLab { 9 | token(DeployToken) { 10 | it.key = 'tokenAdded' 11 | it.value = 'test' 12 | } 13 | token(DeployToken) { 14 | it.key = 'tokenAdded1' 15 | it.value = '' 16 | } 17 | token(DeployToken) { 18 | it.key = 'token0' 19 | it.value = 'test' 20 | } 21 | } 22 | repositories { 23 | realms.split(',').each { realm -> 24 | maven gitLab."$realm"("tokentest") { 25 | tokenSelector = "tokenAdded" 26 | } 27 | maven gitLab."$realm"("tokentest1") { 28 | tokenSelector = "tokenAdded1" 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/groovy/at/schrottner/gradle/GitLabEntityType.groovy: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2021 the original author or authors. 3 | * 4 | * All rights reserved. This program and the accompanying materials are 5 | * made available under the terms of the Eclipse Public License v2.0 which 6 | * accompanies this distribution and is available at 7 | * 8 | * http://www.eclipse.org/legal/epl-v20.html 9 | */ 10 | package at.schrottner.gradle 11 | 12 | enum GitLabEntityType { 13 | GROUP("Group", "groups"), 14 | PROJECT("Project", "projects") 15 | 16 | String name 17 | String endpoint 18 | 19 | GitLabEntityType(String name, String endpoint) { 20 | this.name = name 21 | this.endpoint = endpoint 22 | } 23 | 24 | @Override 25 | String toString() { 26 | return name 27 | } 28 | } -------------------------------------------------------------------------------- /src/functionalTest/resources/ApplyTest/subprojectTest/groovy/subproject1/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | dependencies { 3 | classpath files(pluginClasspath.split(',')) 4 | } 5 | } 6 | apply plugin: at.schrottner.gradle.GitlabRepositoriesPlugin 7 | 8 | gitLab { 9 | token(DeployToken) { 10 | it.key = 'tokenAdded' 11 | it.value = '' 12 | } 13 | token(DeployToken) { 14 | it.key = 'tokenAdded1' 15 | it.value = 'project1' 16 | } 17 | token(DeployToken) { 18 | it.key = 'token0' 19 | it.value = 'test' 20 | } 21 | } 22 | 23 | repositories { 24 | realms.split(',').each { realm -> 25 | maven gitLab."$realm"("tokentest") { 26 | tokenSelector = "tokenAdded" 27 | } 28 | maven gitLab."$realm"("tokentest1") { 29 | tokenSelector = "tokenAdded1" 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/functionalTest/resources/ApplyTest/subprojectTest/kotlin/subproject1/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | dependencies { 3 | classpath files(pluginClasspath.split(',')) 4 | } 5 | } 6 | apply plugin: at.schrottner.gradle.GitlabRepositoriesPlugin 7 | 8 | gitLab { 9 | token(DeployToken) { 10 | it.key = 'tokenAdded' 11 | it.value = '' 12 | } 13 | token(DeployToken) { 14 | it.key = 'tokenAdded1' 15 | it.value = 'project1' 16 | } 17 | token(DeployToken) { 18 | it.key = 'token0' 19 | it.value = 'test' 20 | } 21 | } 22 | 23 | repositories { 24 | realms.split(',').each { realm -> 25 | maven gitLab."$realm"("tokentest") { 26 | tokenSelector = "tokenAdded" 27 | } 28 | maven gitLab."$realm"("tokentest1") { 29 | tokenSelector = "tokenAdded1" 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/test/groovy/at/schrottner/gradle/GitlabRepositoriesPluginTest.groovy: -------------------------------------------------------------------------------- 1 | /* 2 | * This Groovy source file was generated by the Gradle 'init' task. 3 | */ 4 | package at.schrottner.gradle 5 | 6 | import org.gradle.testfixtures.ProjectBuilder 7 | import spock.lang.Specification 8 | 9 | public class GitlabRepositoriesPluginTest extends Specification { 10 | def "apply to Project"() { 11 | given: 12 | def project = ProjectBuilder.builder().build() 13 | 14 | when: 15 | project.plugins.apply("at.schrottner.gitlab-repositories") 16 | 17 | then: 18 | project.tasks.findByName("gitLabTask") != null 19 | project.extensions.findByName(GitlabRepositoriesExtension.NAME) != null 20 | project.extensions.findByName(GitlabRepositoriesExtension.NAME).tokens.size() > 0 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/groovy/at/schrottner/gradle/auths/GitLabTokenType.groovy: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2021 the original author or authors. 3 | * 4 | * All rights reserved. This program and the accompanying materials are 5 | * made available under the terms of the Eclipse Public License v2.0 which 6 | * accompanies this distribution and is available at 7 | * 8 | * http://www.eclipse.org/legal/epl-v20.html 9 | */ 10 | package at.schrottner.gradle.auths; 11 | 12 | enum GitLabTokenType { 13 | JOB("job", "Job-Token"), 14 | PRIVATE("private", "Private-Token"), 15 | DEPLOY("deploy", "Deploy-Token"), 16 | NO_VALUE("no value", "NO-VALUE") 17 | 18 | String name 19 | String headerName 20 | 21 | GitLabTokenType(String name, String headerName) { 22 | this.name = name 23 | this.headerName = headerName 24 | } 25 | 26 | @Override 27 | String toString() { 28 | return headerName 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/functionalTest/groovy/at/schrottner/gradle/TestFileUtils.groovy: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2021 the original author or authors. 3 | * 4 | * All rights reserved. This program and the accompanying materials are 5 | * made available under the terms of the Eclipse Public License v2.0 which 6 | * accompanies this distribution and is available at 7 | * 8 | * http://www.eclipse.org/legal/epl-v20.html 9 | */ 10 | package at.schrottner.gradle 11 | 12 | class TestFileUtils { 13 | static File getTestResource(String filePath, String resourcePath) { 14 | File file = new File(filePath) 15 | getTestResource(file, resourcePath) 16 | } 17 | 18 | static File getTestResource(File file, String resourcePath) { 19 | ClassLoader.getSystemClassLoader().getResource(resourcePath).withInputStream { inputStream -> 20 | file.withOutputStream { outputStream -> 21 | outputStream << inputStream 22 | } 23 | } 24 | file 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | on: 2 | push: 3 | # Sequence of patterns matched against refs/tags 4 | tags: 5 | - 'v*' # Push events to matching v*, i.e. v1.0, v20.15.10 6 | 7 | name: Create Release 8 | 9 | jobs: 10 | # This workflow contains a single job called "build" 11 | build: 12 | # The type of runner that the job will run on 13 | runs-on: ubuntu-latest 14 | 15 | # Steps represent a sequence of tasks that will be executed as part of the job 16 | steps: 17 | # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it 18 | - uses: actions/checkout@v3 19 | 20 | - name: Build 21 | uses: eskatos/gradle-command-action@v2.10.0 22 | env: 23 | TEST_UPLOAD_TOKEN: ${{secrets.TEST_UPLOAD_TOKEN}} 24 | with: 25 | arguments: build publishPlugins -Pgradle.publish.key=${{secrets.GRADLE_PUBLISH_KEY}} -Pgradle.publish.secret=${{secrets.GRADLE_PUBLISH_SECRET}} -------------------------------------------------------------------------------- /src/functionalTest/groovy/at/schrottner/gradle/PluginTest.java: -------------------------------------------------------------------------------- 1 | package at.schrottner.gradle; 2 | 3 | import org.apiguardian.api.API; 4 | import org.gradle.plugin.devel.tasks.internal.ValidateAction; 5 | import org.junit.jupiter.api.DisplayName; 6 | import org.junit.jupiter.params.ParameterizedTest; 7 | import org.junit.jupiter.params.provider.ArgumentsSource; 8 | import org.junit.platform.commons.annotation.Testable; 9 | 10 | import java.lang.annotation.Documented; 11 | import java.lang.annotation.ElementType; 12 | import java.lang.annotation.Retention; 13 | import java.lang.annotation.RetentionPolicy; 14 | import java.lang.annotation.Target; 15 | 16 | import static org.apiguardian.api.API.Status.STABLE; 17 | 18 | @Target({ ElementType.ANNOTATION_TYPE, ElementType.METHOD }) 19 | @Retention(RetentionPolicy.RUNTIME) 20 | @Documented 21 | @API(status = STABLE, since = "5.0") 22 | @ParameterizedTest(name = "{index} Running test for *.{0}") 23 | @ArgumentsSource(PluginTestParams.class) 24 | public @interface PluginTest { 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/functionalTest/resources/ApplyTest/usedInSettingsAndProjectWithoutApplying/groovy/build.gradle: -------------------------------------------------------------------------------- 1 | gitLab { 2 | token(PrivateToken) { 3 | it.key = 'tokenIgnoredNoValue' 4 | it.value = '' 5 | } 6 | token(PrivateToken) { 7 | it.key = 'token0' 8 | it.value = 'test' 9 | } 10 | token(PrivateToken) { 11 | it.key = 'token1' 12 | it.value = 'test' 13 | } 14 | token(DeployToken) { 15 | it.key = 'tokenAdded' 16 | it.value = 'test' 17 | } 18 | } 19 | repositories { 20 | realms.split(',').each { realm -> 21 | 22 | maven gitLab."$realm"("$existingId") 23 | maven gitLab."$realm"("$renamedId") { name = "$realm-renamed" } 24 | maven gitLab."$realm"("specialToken") { 25 | tokenSelector = "token0" 26 | } 27 | maven gitLab."$realm"("specialToken1") { 28 | tokenSelector = "token1" 29 | } 30 | maven gitLab."$realm"("specialTokenSelection") { 31 | tokenSelectors = ["jobToken", "token1"] 32 | } 33 | maven gitLab."$realm"("ignoredNoValue") { 34 | tokenSelector = "tokenIgnoredNoValue" 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /src/functionalTest/resources/UploadTest/uploadtest/groovy/settings.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | dependencies { 3 | classpath files(pluginClasspath.split(',')) 4 | } 5 | } 6 | apply plugin: at.schrottner.gradle.GitlabRepositoriesPlugin 7 | 8 | gitLab { 9 | token(PrivateToken) { 10 | it.key = 'tokenIgnoredNoValue' 11 | it.value = '' 12 | } 13 | token(DeployToken) { 14 | it.key = 'token0' 15 | it.value = 'test' 16 | } 17 | token(DeployToken) { 18 | it.key = 'token1' 19 | it.value = 'test' 20 | } 21 | } 22 | 23 | pluginManagement.repositories { 24 | realms.split(',').each { realm -> 25 | 26 | maven gitLab."$realm"("$existingId") 27 | maven gitLab."$realm"("$renamedId") { name = "$realm-renamed" } 28 | maven gitLab."$realm"("specialToken") { 29 | tokenSelector = "token0" 30 | } 31 | maven gitLab."$realm"("specialToken1") { 32 | tokenSelector = "token1" 33 | } 34 | maven gitLab."$realm"("specialTokenSelection") { 35 | tokenSelectors = ["jobToken", "token1"] 36 | } 37 | maven gitLab."$realm"("ignoredNoValue") { 38 | tokenSelector = "tokenIgnoredNoValue" 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/functionalTest/resources/ApplyTest/onlyUsedInSettings/groovy/settings.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | dependencies { 3 | classpath files(pluginClasspath.split(',')) 4 | } 5 | } 6 | apply plugin: at.schrottner.gradle.GitlabRepositoriesPlugin 7 | 8 | gitLab { 9 | token(PrivateToken) { 10 | it.key = 'tokenIgnoredNoValue' 11 | it.value = '' 12 | } 13 | token(DeployToken) { 14 | it.key = 'token0' 15 | it.value = 'test' 16 | } 17 | token(DeployToken) { 18 | it.key = 'token1' 19 | it.value = 'test' 20 | } 21 | } 22 | 23 | pluginManagement.repositories { 24 | realms.split(',').each { realm -> 25 | 26 | maven gitLab."$realm"("$existingId") 27 | maven gitLab."$realm"("$renamedId") { name = "$realm-renamed" } 28 | maven gitLab."$realm"("specialToken") { 29 | tokenSelector = "token0" 30 | } 31 | maven gitLab."$realm"("specialToken1") { 32 | tokenSelector = "token1" 33 | } 34 | maven gitLab."$realm"("specialTokenSelection") { 35 | tokenSelectors = ["jobToken", "token1"] 36 | } 37 | maven gitLab."$realm"("ignoredNoValue") { 38 | tokenSelector = "tokenIgnoredNoValue" 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/functionalTest/resources/ApplyTest/usedInSettingsAndProject/groovy/settings.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | dependencies { 3 | classpath files(pluginClasspath.split(',')) 4 | } 5 | } 6 | apply plugin: at.schrottner.gradle.GitlabRepositoriesPlugin 7 | 8 | gitLab { 9 | token(PrivateToken) { 10 | it.key = 'tokenIgnoredNoValue' 11 | it.value = '' 12 | } 13 | token(DeployToken) { 14 | it.key = 'token0' 15 | it.value = 'test' 16 | } 17 | token(DeployToken) { 18 | it.key = 'token1' 19 | it.value = 'test' 20 | } 21 | } 22 | 23 | pluginManagement.repositories { 24 | realms.split(',').each { realm -> 25 | 26 | maven gitLab."$realm"("$existingId") 27 | maven gitLab."$realm"("$renamedId") { name = "$realm-renamed" } 28 | maven gitLab."$realm"("specialToken") { 29 | tokenSelector = "token0" 30 | } 31 | maven gitLab."$realm"("specialToken1") { 32 | tokenSelector = "token1" 33 | } 34 | maven gitLab."$realm"("specialTokenSelection") { 35 | tokenSelectors = ["jobToken", "token1"] 36 | } 37 | maven gitLab."$realm"("ignoredNoValue") { 38 | tokenSelector = "tokenIgnoredNoValue" 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/functionalTest/resources/ApplyTest/usedInSettingsAndProjectWithoutApplying/groovy/settings.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | dependencies { 3 | classpath files(pluginClasspath.split(',')) 4 | } 5 | } 6 | apply plugin: at.schrottner.gradle.GitlabRepositoriesPlugin 7 | 8 | gitLab { 9 | token(PrivateToken) { 10 | it.key = 'tokenIgnoredNoValue' 11 | it.value = '' 12 | } 13 | token(DeployToken) { 14 | it.key = 'token0' 15 | it.value = 'test' 16 | } 17 | token(DeployToken) { 18 | it.key = 'token1' 19 | it.value = 'test' 20 | } 21 | } 22 | 23 | pluginManagement.repositories { 24 | realms.split(',').each { realm -> 25 | 26 | maven gitLab."$realm"("$existingId") 27 | maven gitLab."$realm"("$renamedId") { name = "$realm-renamed" } 28 | maven gitLab."$realm"("specialToken") { 29 | tokenSelector = "token0" 30 | } 31 | maven gitLab."$realm"("specialToken1") { 32 | tokenSelector = "token1" 33 | } 34 | maven gitLab."$realm"("specialTokenSelection") { 35 | tokenSelectors = ["jobToken", "token1"] 36 | } 37 | maven gitLab."$realm"("ignoredNoValue") { 38 | tokenSelector = "tokenIgnoredNoValue" 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | # This is a basic workflow to help you get started with Actions 2 | 3 | name: CI 4 | 5 | # Controls when the action will run. 6 | on: 7 | # Triggers the workflow on push or pull request events but only for the main branch 8 | push: 9 | branches: [ main ] 10 | pull_request: 11 | branches: [ main ] 12 | 13 | # Allows you to run this workflow manually from the Actions tab 14 | workflow_dispatch: 15 | 16 | # A workflow run is made up of one or more jobs that can run sequentially or in parallel 17 | jobs: 18 | # This workflow contains a single job called "build" 19 | build: 20 | # The type of runner that the job will run on 21 | runs-on: ubuntu-latest 22 | 23 | # Steps represent a sequence of tasks that will be executed as part of the job 24 | steps: 25 | # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it 26 | - uses: actions/checkout@v3 27 | 28 | - name: Build 29 | uses: eskatos/gradle-command-action@v2.10.0 30 | env: 31 | TEST_UPLOAD_TOKEN: ${{secrets.TEST_UPLOAD_TOKEN}} 32 | with: 33 | arguments: build -i 34 | -------------------------------------------------------------------------------- /src/main/groovy/at/schrottner/gradle/RepositoryConfiguration.groovy: -------------------------------------------------------------------------------- 1 | package at.schrottner.gradle 2 | 3 | import org.gradle.api.Action 4 | import org.gradle.api.artifacts.repositories.RepositoryContentDescriptor 5 | import org.gradle.api.internal.CollectionCallbackActionDecorator 6 | import org.gradle.api.internal.artifacts.BaseRepositoryFactory 7 | import org.gradle.api.internal.artifacts.dsl.DefaultRepositoryHandler 8 | import org.gradle.api.provider.Property 9 | import org.gradle.api.provider.SetProperty 10 | import org.gradle.internal.reflect.Instantiator 11 | 12 | import javax.inject.Inject 13 | 14 | /** 15 | * Representation of the actual configuration done within the gradle definition 16 | * 17 | * TODO: 18 | * - add ContentFiltering 19 | */ 20 | abstract class RepositoryConfiguration { 21 | String id 22 | GitLabEntityType entityType 23 | 24 | @Inject 25 | RepositoryConfiguration(String id, GitLabEntityType entityType) { 26 | this.id = id 27 | this.entityType = entityType 28 | } 29 | 30 | abstract public Property getTokenSelector() 31 | 32 | abstract public SetProperty getTokenSelectors() 33 | 34 | abstract public Property getName() 35 | 36 | } -------------------------------------------------------------------------------- /src/functionalTest/resources/UploadTest/uploadtest/groovy/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | dependencies { 3 | classpath files(pluginClasspath.split(',')) 4 | } 5 | } 6 | 7 | plugins { 8 | id 'maven-publish' 9 | } 10 | 11 | apply plugin: at.schrottner.gradle.GitlabRepositoriesPlugin 12 | 13 | gitLab { 14 | token(PrivateToken) { 15 | it.key = 'testToken' 16 | it.value = System.getenv('TEST_UPLOAD_TOKEN') 17 | } 18 | } 19 | 20 | publishing { 21 | repositories { 22 | maven gitLab.upload("$existingId") 23 | maven gitLab.upload("specialToken") { 24 | tokenSelector = "token0" 25 | } 26 | maven gitLab.upload("specialToken1") { 27 | tokenSelector = "token1" 28 | } 29 | maven gitLab.upload("specialTokenSelection") { 30 | tokenSelectors = ["jobToken", "token1"] 31 | } 32 | maven gitLab.upload("ignoredNoValue") { 33 | tokenSelector = "tokenIgnoredNoValue" 34 | } 35 | maven gitLab.upload("24974077") { 36 | name = "GitLab" 37 | tokenSelector = "testToken" 38 | } 39 | } 40 | 41 | publications { 42 | test(MavenPublication) { 43 | artifactId 'test-file' 44 | groupId 'at.schrottner.test.gitlab-repositories' 45 | version 'test-SNAPSHOT' 46 | artifact source: 'test.xml', classifier: 'features' 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/functionalTest/resources/ApplyTest/onlyUsedInProject/groovy/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | dependencies { 3 | classpath files(pluginClasspath.split(',')) 4 | } 5 | } 6 | apply plugin: at.schrottner.gradle.GitlabRepositoriesPlugin 7 | 8 | gitLab { 9 | token(PrivateToken) { 10 | it.key = 'tokenIgnoredNoValue' 11 | it.value = '' 12 | } 13 | token(PrivateToken) { 14 | it.key = 'token0' 15 | it.value = 'test' 16 | } 17 | token(PrivateToken) { 18 | it.key = 'token1' 19 | it.value = 'test' 20 | } 21 | token(DeployToken) { 22 | it.key = 'tokenAdded' 23 | it.value = 'test' 24 | } 25 | } 26 | repositories { 27 | realms.split(',').each { realm -> 28 | 29 | maven gitLab."$realm"("$existingId") 30 | maven gitLab."$realm"("$renamedId") { name = "$realm-renamed" } 31 | maven gitLab."$realm"("specialToken") { 32 | tokenSelector = "token0" 33 | } 34 | maven gitLab."$realm"("specialToken1") { 35 | tokenSelector = "token1" 36 | } 37 | maven gitLab."$realm"("specialTokenSelection") { 38 | tokenSelectors = ["jobToken", "token1"] 39 | } 40 | maven gitLab."$realm"("ignoredNoValue") { 41 | tokenSelector = "tokenIgnoredNoValue" 42 | } 43 | } 44 | } 45 | 46 | configurations { 47 | testing 48 | } 49 | 50 | dependencies { 51 | testing "at.schrottner.test.gitlab-repositories:test-file:test-SNAPSHOT@xml" 52 | } -------------------------------------------------------------------------------- /src/functionalTest/resources/ApplyTest/usedInSettingsAndProject/groovy/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | dependencies { 3 | classpath files(pluginClasspath.split(',')) 4 | } 5 | } 6 | apply plugin: at.schrottner.gradle.GitlabRepositoriesPlugin 7 | 8 | gitLab { 9 | token(PrivateToken) { 10 | it.key = 'tokenIgnoredNoValue' 11 | it.value = '' 12 | } 13 | token(PrivateToken) { 14 | it.key = 'token0' 15 | it.value = 'test' 16 | } 17 | token(PrivateToken) { 18 | it.key = 'token1' 19 | it.value = 'test' 20 | } 21 | token(DeployToken) { 22 | it.key = 'tokenAdded' 23 | it.value = 'test' 24 | } 25 | } 26 | repositories { 27 | realms.split(',').each { realm -> 28 | 29 | maven gitLab."$realm"("$existingId") 30 | maven gitLab."$realm"("$renamedId") { name = "$realm-renamed" } 31 | maven gitLab."$realm"("specialToken") { 32 | tokenSelector = "token0" 33 | } 34 | maven gitLab."$realm"("specialToken1") { 35 | tokenSelector = "token1" 36 | } 37 | maven gitLab."$realm"("specialTokenSelection") { 38 | tokenSelectors = ["jobToken", "token1"] 39 | } 40 | maven gitLab."$realm"("ignoredNoValue") { 41 | tokenSelector = "tokenIgnoredNoValue" 42 | } 43 | } 44 | } 45 | 46 | configurations { 47 | testing 48 | } 49 | 50 | dependencies { 51 | testing "at.schrottner.test.gitlab-repositories:test-file:test-SNAPSHOT@xml" 52 | } -------------------------------------------------------------------------------- /src/functionalTest/resources/GoogleRecommendationTest/test/groovy/settings.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | dependencies { 3 | classpath files(pluginClasspath.split(',')) 4 | } 5 | } 6 | apply plugin: at.schrottner.gradle.GitlabRepositoriesPlugin 7 | 8 | gitLab { 9 | token(PrivateToken) { 10 | it.key = 'tokenIgnoredNoValue' 11 | it.value = '' 12 | } 13 | token(DeployToken) { 14 | it.key = 'token0' 15 | it.value = 'test' 16 | } 17 | token(DeployToken) { 18 | it.key = 'token1' 19 | it.value = 'test' 20 | } 21 | token(PrivateToken) { 22 | it.key = 'testToken' 23 | it.value = System.getenv('TEST_UPLOAD_TOKEN') 24 | } 25 | } 26 | 27 | dependencyResolutionManagement { 28 | repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) 29 | repositories { 30 | google() 31 | mavenCentral() 32 | maven gitLab.project("24974077"){ 33 | tokenSelector = "testToken" 34 | } 35 | realms.split(',').each { realm -> 36 | 37 | maven gitLab."$realm"("$existingId") 38 | maven gitLab."$realm"("$renamedId") { name = "$realm-renamed" } 39 | maven gitLab."$realm"("specialToken") { 40 | tokenSelector = "token0" 41 | } 42 | maven gitLab."$realm"("specialToken1") { 43 | tokenSelector = "token1" 44 | } 45 | maven gitLab."$realm"("specialTokenSelection") { 46 | tokenSelectors = ["jobToken", "token1"] 47 | } 48 | maven gitLab."$realm"("ignoredNoValue") { 49 | tokenSelector = "tokenIgnoredNoValue" 50 | } 51 | } 52 | } 53 | } 54 | 55 | include ':app' -------------------------------------------------------------------------------- /src/functionalTest/resources/UploadTest/uploadtest/kotlin/build.gradle.kts: -------------------------------------------------------------------------------- 1 | import at.schrottner.gradle.auths.* 2 | import at.schrottner.gradle.* 3 | 4 | buildscript { 5 | val pluginClasspath: String by project 6 | dependencies { 7 | classpath(files(pluginClasspath.split(','))) 8 | } 9 | } 10 | plugins { 11 | `maven-publish` 12 | } 13 | apply(plugin = "at.schrottner.gitlab-repositories") 14 | 15 | configure { 16 | token("private", { 17 | key = "testToken" 18 | value = System.getenv("TEST_UPLOAD_TOKEN") 19 | }) 20 | } 21 | 22 | publishing { 23 | repositories { 24 | val existingId: String by project 25 | val gitLab = the() 26 | maven(gitLab.upload("$existingId")) 27 | maven(gitLab.upload("specialToken") { tokenSelector.set("token0") }) 28 | maven(gitLab.upload("specialToken1") { tokenSelector.set("token1") }) 29 | maven(gitLab.upload("specialTokenSelection") { tokenSelectors.addAll("jobToken", "token1") }) 30 | maven(gitLab.upload("ignoredNoValue") { tokenSelector.set("tokenIgnoredNoValue") }) 31 | maven(gitLab.upload("24974077") { 32 | name.set("GitLab") 33 | tokenSelector.set("testToken") 34 | }) 35 | } 36 | 37 | publications { 38 | create("test") { 39 | artifactId = "test-file" 40 | groupId = "at.schrottner.test.gitlab-repositories" 41 | version = "test-kotlin-SNAPSHOT" 42 | artifact("test.xml", { 43 | classifier = "features" 44 | }) 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/functionalTest/groovy/at/schrottner/gradle/testhelper/MappedParameterContext.java: -------------------------------------------------------------------------------- 1 | package at.schrottner.gradle.testhelper; 2 | 3 | import org.junit.jupiter.api.extension.ParameterContext; 4 | import org.junit.platform.commons.util.AnnotationUtils; 5 | 6 | import java.lang.annotation.Annotation; 7 | import java.lang.reflect.Parameter; 8 | import java.util.List; 9 | import java.util.Optional; 10 | 11 | public class MappedParameterContext implements ParameterContext { 12 | 13 | private final int index; 14 | private final Parameter parameter; 15 | private final Optional target; 16 | 17 | public MappedParameterContext(int index, Parameter parameter, Optional target) { 18 | this.index = index; 19 | this.parameter = parameter; 20 | this.target = target; 21 | } 22 | 23 | @Override 24 | public Parameter getParameter() { 25 | return parameter; 26 | } 27 | 28 | @Override 29 | public int getIndex() { 30 | return index; 31 | } 32 | 33 | @Override 34 | public Optional getTarget() { 35 | return target; 36 | } 37 | 38 | @Override 39 | public boolean isAnnotated(Class annotationType) { 40 | return AnnotationUtils.isAnnotated(parameter, annotationType); 41 | } 42 | 43 | @Override 44 | public Optional findAnnotation(Class annotationType) { 45 | return AnnotationUtils.findAnnotation(parameter, annotationType); 46 | } 47 | 48 | @Override 49 | public List findRepeatableAnnotations(Class annotationType) { 50 | return AnnotationUtils.findRepeatableAnnotations(parameter, annotationType); 51 | } 52 | } -------------------------------------------------------------------------------- /src/functionalTest/resources/UploadTest/uploadtest/kotlin/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | import at.schrottner.gradle.auths.* 2 | import at.schrottner.gradle.* 3 | 4 | buildscript { 5 | val pluginClasspath: String by settings 6 | dependencies { 7 | classpath(files(pluginClasspath.split(','))) 8 | } 9 | } 10 | 11 | apply(plugin = "at.schrottner.gitlab-repositories") 12 | 13 | configure { 14 | token("private", { 15 | key = "tokenIgnoredNoValue" 16 | value = "" 17 | }) 18 | token("deploy", { 19 | key = "token0" 20 | value = "test" 21 | }) 22 | token("deploy", { 23 | key = "token1" 24 | value = "test" 25 | }) 26 | } 27 | 28 | pluginManagement.repositories { 29 | val realms: String by settings 30 | val existingId: String by settings 31 | val renamedId: String by settings 32 | val gitLab = the() 33 | 34 | maven(gitLab.group("$existingId")) 35 | maven(gitLab.project("$existingId")) 36 | maven(gitLab.group("$renamedId") { name.set("group-renamed") }) 37 | maven(gitLab.project("$renamedId") { name.set("project-renamed") }) 38 | maven(gitLab.group("specialToken") { tokenSelector.set("token0") }) 39 | maven(gitLab.project("specialToken") { tokenSelector.set("token0") }) 40 | maven(gitLab.group("specialToken1") { tokenSelector.set("token1") }) 41 | maven(gitLab.project("specialToken1") { tokenSelector.set("token1") }) 42 | maven(gitLab.group("specialTokenSelection") { tokenSelectors.addAll("jobToken", "token1") }) 43 | maven(gitLab.project("specialTokenSelection") { tokenSelectors.addAll("jobToken", "token1") }) 44 | maven(gitLab.group("ignoredNoValue") { tokenSelector.set("tokenIgnoredNoValue") }) 45 | maven(gitLab.project("ignoredNoValue") { tokenSelector.set("tokenIgnoredNoValue") }) 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/functionalTest/resources/ApplyTest/onlyUsedInSettings/kotlin/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | import at.schrottner.gradle.auths.* 2 | import at.schrottner.gradle.* 3 | 4 | buildscript { 5 | val pluginClasspath: String by settings 6 | dependencies { 7 | classpath(files(pluginClasspath.split(','))) 8 | } 9 | } 10 | 11 | apply(plugin = "at.schrottner.gitlab-repositories") 12 | 13 | configure { 14 | token("private", { 15 | key = "tokenIgnoredNoValue" 16 | value = "" 17 | }) 18 | token("deploy", { 19 | key = "token0" 20 | value = "test" 21 | }) 22 | token("deploy", { 23 | key = "token1" 24 | value = "test" 25 | }) 26 | } 27 | 28 | pluginManagement.repositories { 29 | val realms: String by settings 30 | val existingId: String by settings 31 | val renamedId: String by settings 32 | val gitLab = the() 33 | 34 | maven(gitLab.group("$existingId")) 35 | maven(gitLab.project("$existingId")) 36 | maven(gitLab.group("$renamedId") { name.set("group-renamed") }) 37 | maven(gitLab.project("$renamedId") { name.set("project-renamed") }) 38 | maven(gitLab.group("specialToken") { tokenSelector.set("token0") }) 39 | maven(gitLab.project("specialToken") { tokenSelector.set("token0") }) 40 | maven(gitLab.group("specialToken1") { tokenSelector.set("token1") }) 41 | maven(gitLab.project("specialToken1") { tokenSelector.set("token1") }) 42 | maven(gitLab.group("specialTokenSelection") { tokenSelectors.addAll("jobToken", "token1") }) 43 | maven(gitLab.project("specialTokenSelection") { tokenSelectors.addAll("jobToken", "token1") }) 44 | maven(gitLab.group("ignoredNoValue") { tokenSelector.set("tokenIgnoredNoValue") }) 45 | maven(gitLab.project("ignoredNoValue") { tokenSelector.set("tokenIgnoredNoValue") }) 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/functionalTest/resources/ApplyTest/usedInSettingsAndProject/kotlin/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | import at.schrottner.gradle.auths.* 2 | import at.schrottner.gradle.* 3 | 4 | buildscript { 5 | val pluginClasspath: String by settings 6 | dependencies { 7 | classpath(files(pluginClasspath.split(','))) 8 | } 9 | } 10 | 11 | apply(plugin = "at.schrottner.gitlab-repositories") 12 | 13 | configure { 14 | token("private", { 15 | key = "tokenIgnoredNoValue" 16 | value = "" 17 | }) 18 | token("deploy", { 19 | key = "token0" 20 | value = "test" 21 | }) 22 | token("deploy", { 23 | key = "token1" 24 | value = "test" 25 | }) 26 | } 27 | 28 | pluginManagement.repositories { 29 | val realms: String by settings 30 | val existingId: String by settings 31 | val renamedId: String by settings 32 | val gitLab = the() 33 | 34 | maven(gitLab.group("$existingId")) 35 | maven(gitLab.project("$existingId")) 36 | maven(gitLab.group("$renamedId") { name.set("group-renamed") }) 37 | maven(gitLab.project("$renamedId") { name.set("project-renamed") }) 38 | maven(gitLab.group("specialToken") { tokenSelector.set("token0") }) 39 | maven(gitLab.project("specialToken") { tokenSelector.set("token0") }) 40 | maven(gitLab.group("specialToken1") { tokenSelector.set("token1") }) 41 | maven(gitLab.project("specialToken1") { tokenSelector.set("token1") }) 42 | maven(gitLab.group("specialTokenSelection") { tokenSelectors.addAll("jobToken", "token1") }) 43 | maven(gitLab.project("specialTokenSelection") { tokenSelectors.addAll("jobToken", "token1") }) 44 | maven(gitLab.group("ignoredNoValue") { tokenSelector.set("tokenIgnoredNoValue") }) 45 | maven(gitLab.project("ignoredNoValue") { tokenSelector.set("tokenIgnoredNoValue") }) 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/functionalTest/resources/ApplyTest/usedInSettingsAndProjectWithoutApplying/kotlin/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | import at.schrottner.gradle.auths.* 2 | import at.schrottner.gradle.* 3 | 4 | buildscript { 5 | val pluginClasspath: String by settings 6 | dependencies { 7 | classpath(files(pluginClasspath.split(','))) 8 | } 9 | } 10 | 11 | apply(plugin = "at.schrottner.gitlab-repositories") 12 | 13 | configure { 14 | token("private", { 15 | key = "tokenIgnoredNoValue" 16 | value = "" 17 | }) 18 | token("deploy", { 19 | key = "token0" 20 | value = "test" 21 | }) 22 | token("deploy", { 23 | key = "token1" 24 | value = "test" 25 | }) 26 | } 27 | 28 | pluginManagement.repositories { 29 | val realms: String by settings 30 | val existingId: String by settings 31 | val renamedId: String by settings 32 | val gitLab = the() 33 | 34 | maven(gitLab.group("$existingId")) 35 | maven(gitLab.project("$existingId")) 36 | maven(gitLab.group("$renamedId") { name.set("group-renamed") }) 37 | maven(gitLab.project("$renamedId") { name.set("project-renamed") }) 38 | maven(gitLab.group("specialToken") { tokenSelector.set("token0") }) 39 | maven(gitLab.project("specialToken") { tokenSelector.set("token0") }) 40 | maven(gitLab.group("specialToken1") { tokenSelector.set("token1") }) 41 | maven(gitLab.project("specialToken1") { tokenSelector.set("token1") }) 42 | maven(gitLab.group("specialTokenSelection") { tokenSelectors.addAll("jobToken", "token1") }) 43 | maven(gitLab.project("specialTokenSelection") { tokenSelectors.addAll("jobToken", "token1") }) 44 | maven(gitLab.group("ignoredNoValue") { tokenSelector.set("tokenIgnoredNoValue") }) 45 | maven(gitLab.project("ignoredNoValue") { tokenSelector.set("tokenIgnoredNoValue") }) 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/functionalTest/groovy/at/schrottner/gradle/UploadTest.groovy: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2021 the original author or authors. 3 | * 4 | * All rights reserved. This program and the accompanying materials are 5 | * made available under the terms of the Eclipse Public License v2.0 which 6 | * accompanies this distribution and is available at 7 | * 8 | * http://www.eclipse.org/legal/epl-v20.html 9 | */ 10 | package at.schrottner.gradle 11 | 12 | import static org.assertj.core.api.Assertions.assertThat 13 | 14 | import org.gradle.internal.impldep.org.apache.commons.io.FileUtils 15 | import org.junit.jupiter.api.condition.DisabledIfEnvironmentVariable 16 | 17 | 18 | class UploadTest extends AbstractFunctionalTests { 19 | 20 | @PluginTest 21 | @DisabledIfEnvironmentVariable( 22 | named = 'TEST_UPLOAD_TOKEN', 23 | matches = '^$', 24 | disabledReason = 'Upload deactivated due to missing TEST_UPLOAD_TOKEN' 25 | ) 26 | void "uploadTest"(String primer) { 27 | def testFile = TestFileUtils.getTestResource(new File(projectDir, 'test.xml'), 'test.xml') 28 | 29 | def uploadResult = runTest("publishTestPublicationToGitLabRepository", "-i", "-s") 30 | def repoPrefix = "GitLab-Project" 31 | assertThat(uploadResult.output) 32 | .contains("BUILD SUCCESSFUL") 33 | .containsSubsequence( 34 | "added Job-Token: jobToken", 35 | "added Private-Token: tokenIgnoredNoValue", 36 | "added Deploy-Token: token0", 37 | "added Deploy-Token: token1", 38 | "Settings evaluated", 39 | "added Private-Token: testToken" 40 | ) 41 | .containsSubsequence("Maven Repository $repoPrefix-$existingId is using 'token0'", 42 | "Maven Repository $repoPrefix-specialToken is using 'token0'", 43 | "Maven Repository $repoPrefix-specialToken1 is using 'token1'", 44 | "Maven Repository $repoPrefix-specialTokenSelection is using 'token1'", 45 | "Maven Repository $repoPrefix-ignoredNoValue was not added, as no token could be applied!", 46 | "Maven Repository GitLab is using 'testToken'", 47 | ) 48 | .doesNotContain("Maven Repository $repoPrefix-ignoredNoValue is using '") 49 | .contains("Publishing to repository 'GitLab'") 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/functionalTest/resources/ApplyTest/usedInSettingsAndProjectWithoutApplying/kotlin/build.gradle.kts: -------------------------------------------------------------------------------- 1 | import at.schrottner.gradle.auths.* 2 | import at.schrottner.gradle.* 3 | import org.gradle.api.artifacts.repositories.MavenArtifactRepository 4 | 5 | configure { 6 | token("private", { 7 | key = "tokenIgnoredNoValue" 8 | value = "" 9 | }) 10 | token("private", { 11 | key = "token0" 12 | value = "test" 13 | }) 14 | token("private", { 15 | key = "token1" 16 | value = "test" 17 | }) 18 | token("deploy", { 19 | key = "tokenAdded" 20 | value = "test" 21 | }) 22 | token("private", { 23 | key = "downloadToken" 24 | value = System.getenv("TEST_UPLOAD_TOKEN") 25 | }) 26 | } 27 | 28 | repositories { 29 | val realms: String by project 30 | val existingId: String by project 31 | val renamedId: String by project 32 | val gitLab = the() 33 | 34 | maven(gitLab.project("24974077") { tokenSelector.set("downloadToken") }) 35 | maven(gitLab.group("$existingId")) 36 | maven(gitLab.project("$existingId")) 37 | maven(gitLab.group("$renamedId") { name.set("group-renamed") }) 38 | maven(gitLab.project("$renamedId") { name.set("project-renamed") }) 39 | maven(gitLab.group("specialToken") { tokenSelector.set("token0") }) 40 | maven(gitLab.project("specialToken") { tokenSelector.set("token0") }) 41 | maven(gitLab.group("specialToken1") { tokenSelector.set("token1") }) 42 | maven(gitLab.project("specialToken1") { tokenSelector.set("token1") }) 43 | maven(gitLab.group("specialTokenSelection") { tokenSelectors.addAll("jobToken", "token1") }) 44 | maven(gitLab.project("specialTokenSelection") { tokenSelectors.addAll("jobToken", "token1") }) 45 | maven(gitLab.group("ignoredNoValue") { tokenSelector.set("tokenIgnoredNoValue") }) 46 | maven(gitLab.project("ignoredNoValue") { tokenSelector.set("tokenIgnoredNoValue") }) 47 | } 48 | 49 | val testing by configurations.creating 50 | 51 | dependencies { 52 | testing("at.schrottner.test.gitlab-repositories:test-file:test-SNAPSHOT@xml") 53 | } -------------------------------------------------------------------------------- /src/functionalTest/resources/ApplyTest/onlyUsedInProject/kotlin/build.gradle.kts: -------------------------------------------------------------------------------- 1 | import at.schrottner.gradle.auths.* 2 | import at.schrottner.gradle.* 3 | import org.gradle.api.artifacts.repositories.MavenArtifactRepository 4 | 5 | buildscript { 6 | val pluginClasspath: String by project 7 | dependencies { 8 | classpath(files(pluginClasspath.split(','))) 9 | } 10 | } 11 | 12 | apply(plugin = "at.schrottner.gitlab-repositories") 13 | 14 | configure { 15 | token("private", { 16 | key = "tokenIgnoredNoValue" 17 | value = "" 18 | }) 19 | token("private", { 20 | key = "token0" 21 | value = "test" 22 | }) 23 | token("private", { 24 | key = "token1" 25 | value = "test" 26 | }) 27 | token("deploy", { 28 | key = "tokenAdded" 29 | value = "test" 30 | }) 31 | token("private", { 32 | key = "downloadToken" 33 | value = System.getenv("TEST_UPLOAD_TOKEN") 34 | }) 35 | } 36 | 37 | repositories { 38 | val realms: String by project 39 | val existingId: String by project 40 | val renamedId: String by project 41 | val gitLab = the() 42 | 43 | maven(gitLab.project("24974077") { tokenSelector.set("downloadToken") }) 44 | maven(gitLab.group("$existingId")) 45 | maven(gitLab.project("$existingId")) 46 | maven(gitLab.group("$renamedId") { name.set("group-renamed") }) 47 | maven(gitLab.project("$renamedId") { name.set("project-renamed") }) 48 | maven(gitLab.group("specialToken") { tokenSelector.set("token0") }) 49 | maven(gitLab.project("specialToken") { tokenSelector.set("token0") }) 50 | maven(gitLab.group("specialToken1") { tokenSelector.set("token1") }) 51 | maven(gitLab.project("specialToken1") { tokenSelector.set("token1") }) 52 | maven(gitLab.group("specialTokenSelection") { tokenSelectors.addAll("jobToken", "token1") }) 53 | maven(gitLab.project("specialTokenSelection") { tokenSelectors.addAll("jobToken", "token1") }) 54 | maven(gitLab.group("ignoredNoValue") { tokenSelector.set("tokenIgnoredNoValue") }) 55 | maven(gitLab.project("ignoredNoValue") { tokenSelector.set("tokenIgnoredNoValue") }) 56 | } 57 | 58 | val testing by configurations.creating 59 | 60 | dependencies { 61 | testing("at.schrottner.test.gitlab-repositories:test-file:test-SNAPSHOT@xml") 62 | } -------------------------------------------------------------------------------- /src/functionalTest/resources/ApplyTest/usedInSettingsAndProject/kotlin/build.gradle.kts: -------------------------------------------------------------------------------- 1 | import at.schrottner.gradle.auths.* 2 | import at.schrottner.gradle.* 3 | import org.gradle.api.artifacts.repositories.MavenArtifactRepository 4 | 5 | buildscript { 6 | val pluginClasspath: String by project 7 | dependencies { 8 | classpath(files(pluginClasspath.split(','))) 9 | } 10 | } 11 | 12 | apply(plugin = "at.schrottner.gitlab-repositories") 13 | 14 | configure { 15 | token("private", { 16 | key = "tokenIgnoredNoValue" 17 | value = "" 18 | }) 19 | token("private", { 20 | key = "token0" 21 | value = "test" 22 | }) 23 | token("private", { 24 | key = "token1" 25 | value = "test" 26 | }) 27 | token("deploy", { 28 | key = "tokenAdded" 29 | value = "test" 30 | }) 31 | token("private", { 32 | key = "downloadToken" 33 | value = System.getenv("TEST_UPLOAD_TOKEN") 34 | }) 35 | } 36 | 37 | repositories { 38 | val realms: String by project 39 | val existingId: String by project 40 | val renamedId: String by project 41 | val gitLab = the() 42 | 43 | maven(gitLab.project("24974077") { tokenSelector.set("downloadToken") }) 44 | maven(gitLab.group("$existingId")) 45 | maven(gitLab.project("$existingId")) 46 | maven(gitLab.group("$renamedId") { name.set("group-renamed") }) 47 | maven(gitLab.project("$renamedId") { name.set("project-renamed") }) 48 | maven(gitLab.group("specialToken") { tokenSelector.set("token0") }) 49 | maven(gitLab.project("specialToken") { tokenSelector.set("token0") }) 50 | maven(gitLab.group("specialToken1") { tokenSelector.set("token1") }) 51 | maven(gitLab.project("specialToken1") { tokenSelector.set("token1") }) 52 | maven(gitLab.group("specialTokenSelection") { tokenSelectors.addAll("jobToken", "token1") }) 53 | maven(gitLab.project("specialTokenSelection") { tokenSelectors.addAll("jobToken", "token1") }) 54 | maven(gitLab.group("ignoredNoValue") { tokenSelector.set("tokenIgnoredNoValue") }) 55 | maven(gitLab.project("ignoredNoValue") { tokenSelector.set("tokenIgnoredNoValue") }) 56 | } 57 | 58 | val testing by configurations.creating 59 | 60 | dependencies { 61 | testing("at.schrottner.test.gitlab-repositories:test-file:test-SNAPSHOT@xml") 62 | } -------------------------------------------------------------------------------- /src/functionalTest/groovy/at/schrottner/gradle/AbstractFunctionalTests.groovy: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2021 the original author or authors. 3 | * 4 | * All rights reserved. This program and the accompanying materials are 5 | * made available under the terms of the Eclipse Public License v2.0 which 6 | * accompanies this distribution and is available at 7 | * 8 | * http://www.eclipse.org/legal/epl-v20.html 9 | */ 10 | package at.schrottner.gradle 11 | 12 | import static org.assertj.core.api.Assertions.assertThat 13 | 14 | import at.schrottner.gradle.testhelper.AfterBeforeParameterResolver 15 | import org.apache.commons.text.CaseUtils 16 | import org.gradle.internal.impldep.org.apache.commons.io.FileUtils 17 | import org.gradle.testkit.runner.BuildResult 18 | import org.gradle.testkit.runner.GradleRunner 19 | import org.junit.jupiter.api.BeforeEach 20 | import org.junit.jupiter.api.TestInfo 21 | import org.junit.jupiter.api.extension.ExtendWith 22 | import org.junit.jupiter.api.io.TempDir 23 | import org.slf4j.Logger 24 | import org.slf4j.LoggerFactory 25 | 26 | // TODO: check if we can parameterize this somehow 27 | 28 | @ExtendWith(AfterBeforeParameterResolver.class) 29 | class AbstractFunctionalTests { 30 | 31 | private static final Logger logger = LoggerFactory.getLogger(AbstractFunctionalTests.class) 32 | protected static def existingId = "1234" 33 | protected static def renamedId = "123" 34 | protected static def realms = ["group", "project"] 35 | protected pluginClasspath = getClass().classLoader.findResource("plugin-classpath.txt") 36 | .readLines() 37 | .collect { it.replace('\\\\', '\\\\\\\\') } // escape backslashes in Windows paths 38 | .collect { "$it" } 39 | .join(",") 40 | 41 | File projectDir 42 | File gradleProperties 43 | 44 | @BeforeEach 45 | void setup(String primer, @TempDir File projectDir, TestInfo testInfo) { 46 | this.projectDir = projectDir 47 | gradleProperties = new File(projectDir, "gradle.properties") 48 | gradleProperties << """ 49 | existingId=$existingId 50 | renamedId=$renamedId 51 | pluginClasspath=$pluginClasspath 52 | realms=${realms.join(',')} 53 | """ 54 | 55 | testInfo.testMethod.ifPresent { 56 | FileUtils.copyDirectory( 57 | new File( 58 | ClassLoader 59 | .getSystemClassLoader() 60 | .getResource("${it.declaringClass.simpleName}/${CaseUtils.toCamelCase(it.name, false)}/$primer") 61 | .toURI()), projectDir) 62 | } 63 | } 64 | 65 | protected BuildResult runTest(String[] args = ["tasks", "-i", "-s"]) { 66 | def runner = GradleRunner.create() 67 | runner.forwardOutput() 68 | runner.withPluginClasspath() 69 | runner.withArguments(args) 70 | runner.withProjectDir(projectDir) 71 | runner.build() 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/main/groovy/at/schrottner/gradle/GitlabRepositoriesPlugin.groovy: -------------------------------------------------------------------------------- 1 | package at.schrottner.gradle 2 | 3 | import at.schrottner.gradle.auths.GitLabTokenType 4 | import org.gradle.api.DefaultTask 5 | import org.gradle.api.Plugin 6 | import org.gradle.api.Project 7 | import org.gradle.api.initialization.Settings 8 | import org.gradle.api.model.ObjectFactory 9 | import org.gradle.api.plugins.ExtensionAware 10 | import org.gradle.internal.extensibility.DefaultExtraPropertiesExtension 11 | 12 | import javax.inject.Inject 13 | 14 | class GitlabRepositoriesPlugin implements Plugin { 15 | 16 | ObjectFactory objects 17 | 18 | @Inject 19 | GitlabRepositoriesPlugin(ObjectFactory objectFactory) { 20 | this.objects = objectFactory 21 | } 22 | 23 | void apply(ExtensionAware extensionAware) { 24 | addProps(extensionAware) 25 | 26 | if (extensionAware instanceof Project) { 27 | apply(extensionAware) 28 | } else if (extensionAware instanceof Settings) { 29 | apply(extensionAware) 30 | } 31 | } 32 | 33 | void addProps(ExtensionAware extensionAware) { 34 | extensionAware.extensions.extraProperties.set('DeployToken', GitLabTokenType.DEPLOY) 35 | extensionAware.extensions.extraProperties.set('PrivateToken', GitLabTokenType.PRIVATE) 36 | extensionAware.extensions.extraProperties.set('JobToken', GitLabTokenType.JOB) 37 | } 38 | 39 | void apply(Settings extensionAware) { 40 | GitlabRepositoriesExtension extension = extensionAware.extensions.create( 41 | GitlabRepositoriesExtension.NAME, 42 | GitlabRepositoriesExtension, 43 | extensionAware, 44 | objects 45 | ) 46 | 47 | extensionAware.gradle.beforeProject { Project project -> 48 | def ext = project.extensions.findByName(DefaultExtraPropertiesExtension.EXTENSION_NAME) 49 | ext.gitLabTokens = extension.tokens 50 | if (extension.applyToProject) { 51 | applyProjects(extension, project) 52 | addProps(project) 53 | project.extensions.create( 54 | GitlabRepositoriesExtension.NAME, 55 | GitlabRepositoriesExtension, 56 | project, 57 | objects, 58 | extension 59 | ) 60 | } 61 | } 62 | } 63 | 64 | void apply(Project extensionAware) { 65 | def extension = extensionAware.extensions.findByName(GitlabRepositoriesExtension.NAME) ?: 66 | extensionAware.extensions.create( 67 | GitlabRepositoriesExtension.NAME, 68 | GitlabRepositoriesExtension, 69 | extensionAware, 70 | objects 71 | ) 72 | 73 | def task = extensionAware.tasks.maybeCreate('gitLabTask', DefaultTask) 74 | task.doLast { 75 | println "GitLab Repository tokens:" 76 | extension.tokens.each { key, value -> 77 | println "- $key: ${value.getClass().simpleName}" 78 | } 79 | } 80 | } 81 | 82 | private void applyProjects(extension, project) { 83 | extension.artifactActionStorage.each { value -> 84 | project.repositories.maven value 85 | } 86 | } 87 | 88 | } 89 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if "%ERRORLEVEL%" == "0" goto execute 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto execute 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :execute 68 | @rem Setup the command line 69 | 70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 71 | 72 | 73 | @rem Execute Gradle 74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 75 | 76 | :end 77 | @rem End local scope for the variables with windows NT shell 78 | if "%ERRORLEVEL%"=="0" goto mainEnd 79 | 80 | :fail 81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 82 | rem the _cmd.exe /c_ return code! 83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 84 | exit /b 1 85 | 86 | :mainEnd 87 | if "%OS%"=="Windows_NT" endlocal 88 | 89 | :omega 90 | -------------------------------------------------------------------------------- /src/functionalTest/groovy/at/schrottner/gradle/testhelper/AfterBeforeParameterResolver.java: -------------------------------------------------------------------------------- 1 | package at.schrottner.gradle.testhelper; 2 | 3 | import org.junit.jupiter.api.AfterEach; 4 | import org.junit.jupiter.api.BeforeEach; 5 | import org.junit.jupiter.api.extension.ExtensionContext; 6 | import org.junit.jupiter.api.extension.ParameterContext; 7 | import org.junit.jupiter.api.extension.ParameterResolutionException; 8 | import org.junit.jupiter.api.extension.ParameterResolver; 9 | import org.junit.jupiter.engine.execution.BeforeEachMethodAdapter; 10 | import org.junit.jupiter.engine.extension.ExtensionRegistry; 11 | 12 | import java.lang.annotation.Annotation; 13 | import java.util.Arrays; 14 | import java.util.Optional; 15 | 16 | public class AfterBeforeParameterResolver implements BeforeEachMethodAdapter, ParameterResolver { 17 | private ParameterResolver parameterisedTestParameterResolver = null; 18 | 19 | @Override 20 | public void invokeBeforeEachMethod(ExtensionContext context, ExtensionRegistry registry) { 21 | Optional resolverOptional = registry.getExtensions(ParameterResolver.class) 22 | .stream() 23 | .filter(parameterResolver -> parameterResolver.getClass().getName().contains("ParameterizedTestParameterResolver")) 24 | .findFirst(); 25 | if (!resolverOptional.isPresent()) { 26 | throw new IllegalStateException("ParameterizedTestParameterResolver missed in the registry. Probably it's not a Parameterized Test"); 27 | } else { 28 | parameterisedTestParameterResolver = resolverOptional.get(); 29 | } 30 | } 31 | 32 | @Override 33 | public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException { 34 | try { 35 | if (isExecutedOnAfterOrBeforeMethod(parameterContext)) { 36 | ParameterContext pContext = getMappedContext(parameterContext, extensionContext); 37 | return parameterisedTestParameterResolver.supportsParameter(pContext, extensionContext); 38 | } 39 | } catch (IndexOutOfBoundsException e) { 40 | // no-op 41 | } 42 | return false; 43 | } 44 | 45 | private MappedParameterContext getMappedContext(ParameterContext parameterContext, ExtensionContext extensionContext) { 46 | return new MappedParameterContext( 47 | parameterContext.getIndex(), 48 | extensionContext.getRequiredTestMethod().getParameters()[parameterContext.getIndex()], 49 | Optional.of(parameterContext.getTarget())); 50 | } 51 | 52 | 53 | private boolean isExecutedOnAfterOrBeforeMethod(ParameterContext parameterContext) { 54 | return Arrays.stream(parameterContext.getDeclaringExecutable().getDeclaredAnnotations()) 55 | .anyMatch(this::isAfterEachOrBeforeEachAnnotation); 56 | } 57 | 58 | private boolean isAfterEachOrBeforeEachAnnotation(Annotation annotation) { 59 | return annotation.annotationType() == BeforeEach.class || annotation.annotationType() == AfterEach.class; 60 | } 61 | 62 | @Override 63 | public Object resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException { 64 | return parameterisedTestParameterResolver.resolveParameter(getMappedContext(parameterContext, extensionContext), extensionContext); 65 | } 66 | } -------------------------------------------------------------------------------- /src/main/groovy/at/schrottner/gradle/GitlabRepositoriesExtension.groovy: -------------------------------------------------------------------------------- 1 | package at.schrottner.gradle 2 | 3 | import at.schrottner.gradle.auths.GitLabTokenType 4 | import at.schrottner.gradle.auths.Token 5 | import groovy.transform.CompileStatic 6 | import org.gradle.api.Action 7 | import org.gradle.api.Project 8 | import org.gradle.api.artifacts.dsl.RepositoryHandler 9 | import org.gradle.api.artifacts.repositories.MavenArtifactRepository 10 | import org.gradle.api.initialization.Settings 11 | import org.gradle.api.model.ObjectFactory 12 | import org.slf4j.Logger 13 | import org.slf4j.LoggerFactory 14 | 15 | /** 16 | * GitLabRepositoriesExtension is the main entry point to configure the plugin 17 | * 18 | * It provides additional methods to automatically add repositories based on GitLab Groups 19 | * or Projects. 20 | */ 21 | @CompileStatic 22 | class GitlabRepositoriesExtension { 23 | 24 | private static final Logger logger = LoggerFactory.getLogger(RepositoryHandler) 25 | public static final String NAME = "gitLab" 26 | private final ObjectFactory objects 27 | 28 | String baseUrl = "gitlab.com" 29 | boolean applyToProject = true 30 | Map tokens = [:] 31 | 32 | public final List> artifactActionStorage = [] 33 | 34 | GitlabRepositoriesExtension(Settings settings, ObjectFactory objects) { 35 | this.objects = objects 36 | setup() 37 | } 38 | 39 | GitlabRepositoriesExtension(Project project, ObjectFactory objects, GitlabRepositoriesExtension parent = null) { 40 | this.objects = objects 41 | if (parent) { 42 | this.baseUrl = parent.baseUrl 43 | } 44 | if (!migrateSettingsTokens(project)) { 45 | setup() 46 | } 47 | } 48 | 49 | private boolean migrateSettingsTokens(Project project) { 50 | if (project.extensions.extraProperties.has('gitLabTokens')) { 51 | def passedOnTokens = (project.extensions.extraProperties['gitLabTokens'] ?: [:]) as Map 52 | passedOnTokens.each { key, value -> 53 | def token = value 54 | logger.info("$Config.LOG_PREFIX readding Token from Parent $token.type: $token.key") 55 | tokens.put(token.key, token) 56 | } 57 | return true 58 | } 59 | return false 60 | } 61 | 62 | void setup() { 63 | logger.info("$Config.LOG_PREFIX initializing") 64 | token(GitLabTokenType.JOB, { 65 | it.key = 'jobToken' 66 | it.value = System.getenv("CI_JOB_TOKEN") 67 | }) 68 | } 69 | 70 | void token(String tokenType, Action action) { 71 | token(GitLabTokenType.valueOf(tokenType.toUpperCase()), action) 72 | } 73 | 74 | void token(GitLabTokenType tokenType, Action action) { 75 | if (!tokenType) { 76 | throw new IllegalArgumentException('no token') 77 | } 78 | def token = new Token(tokenType) 79 | action.execute(token) 80 | 81 | logger.info("$Config.LOG_PREFIX ${tokens.containsKey(token.key) ? "replaced" : "added"} $token.type: $token.key") 82 | tokens.put(token.key, token) 83 | } 84 | 85 | /** 86 | * Special endpoint for uploading as GitLab only supports uploads for project, this is using the project endpoint. 87 | * it allows to be directly added to a DefaultRepositoryHandler, as the ID might be some env variable only 88 | * available during CI builds etc. and this might cause on wanted side-effects if it is not resolving to a 89 | * usable endpoint 90 | * 91 | * @param id 92 | * @param configAction 93 | * @return 94 | */ 95 | Action upload(String projectId, Action configAction = null) { 96 | RepositoryConfiguration repositoryConfiguration = generateRepositoryConfiguration(projectId, GitLabEntityType.PROJECT) 97 | mavenInternal(repositoryConfiguration, configAction) 98 | } 99 | 100 | 101 | private RepositoryConfiguration generateRepositoryConfiguration(String id, GitLabEntityType entityType) { 102 | RepositoryConfiguration repositoryConfiguration = objects.newInstance(RepositoryConfiguration.class, id ?: "NOT_PROPERLY_SET", entityType) 103 | repositoryConfiguration 104 | } 105 | 106 | /** 107 | * @deprecated use{@link #group(java.lang.String, org.gradle.api.Action)} or {@link #project(java.lang.String, org.gradle.api.Action)} 108 | */ 109 | @Deprecated 110 | Action maven(String id, Action configAction = null) { 111 | group(id, configAction) 112 | } 113 | 114 | Action group(String id, Action configAction = null) { 115 | RepositoryConfiguration repositoryConfiguration = generateRepositoryConfiguration(id, GitLabEntityType.GROUP) 116 | mavenInternal(repositoryConfiguration, configAction) 117 | } 118 | 119 | Action project(String id, Action configAction = null) { 120 | RepositoryConfiguration repositoryConfiguration = generateRepositoryConfiguration(id, GitLabEntityType.PROJECT) 121 | mavenInternal(repositoryConfiguration, configAction) 122 | } 123 | 124 | Action mavenInternal(RepositoryConfiguration repositoryConfiguration, 125 | Action configAction = null) { 126 | 127 | if (!repositoryConfiguration.id) { 128 | logger.info("$Config.LOG_PREFIX: No ID provided - project will be added anyways, but will not be used") 129 | } 130 | 131 | configAction?.execute(repositoryConfiguration) 132 | 133 | Action artifactRepo = new RepositoryActionHandler(this, repositoryConfiguration) 134 | 135 | artifactActionStorage.add artifactRepo 136 | 137 | return artifactRepo 138 | } 139 | } -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | We as members, contributors, and leaders pledge to make participation in our 6 | community a harassment-free experience for everyone, regardless of age, body 7 | size, visible or invisible disability, ethnicity, sex characteristics, gender 8 | identity and expression, level of experience, education, socio-economic status, 9 | nationality, personal appearance, race, religion, or sexual identity 10 | and orientation. 11 | 12 | We pledge to act and interact in ways that contribute to an open, welcoming, 13 | diverse, inclusive, and healthy community. 14 | 15 | ## Our Standards 16 | 17 | Examples of behavior that contributes to a positive environment for our 18 | community include: 19 | 20 | * Demonstrating empathy and kindness toward other people 21 | * Being respectful of differing opinions, viewpoints, and experiences 22 | * Giving and gracefully accepting constructive feedback 23 | * Accepting responsibility and apologizing to those affected by our mistakes, 24 | and learning from the experience 25 | * Focusing on what is best not just for us as individuals, but for the 26 | overall community 27 | 28 | Examples of unacceptable behavior include: 29 | 30 | * The use of sexualized language or imagery, and sexual attention or 31 | advances of any kind 32 | * Trolling, insulting or derogatory comments, and personal or political attacks 33 | * Public or private harassment 34 | * Publishing others' private information, such as a physical or email 35 | address, without their explicit permission 36 | * Other conduct which could reasonably be considered inappropriate in a 37 | professional setting 38 | 39 | ## Enforcement Responsibilities 40 | 41 | Community leaders are responsible for clarifying and enforcing our standards of 42 | acceptable behavior and will take appropriate and fair corrective action in 43 | response to any behavior that they deem inappropriate, threatening, offensive, 44 | or harmful. 45 | 46 | Community leaders have the right and responsibility to remove, edit, or reject 47 | comments, commits, code, wiki edits, issues, and other contributions that are 48 | not aligned to this Code of Conduct, and will communicate reasons for moderation 49 | decisions when appropriate. 50 | 51 | ## Scope 52 | 53 | This Code of Conduct applies within all community spaces, and also applies when 54 | an individual is officially representing the community in public spaces. 55 | Examples of representing our community include using an official e-mail address, 56 | posting via an official social media account, or acting as an appointed 57 | representative at an online or offline event. 58 | 59 | ## Enforcement 60 | 61 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 62 | reported to the community leaders responsible for enforcement at 63 | simon.schrottner@gmail.com. 64 | All complaints will be reviewed and investigated promptly and fairly. 65 | 66 | All community leaders are obligated to respect the privacy and security of the 67 | reporter of any incident. 68 | 69 | ## Enforcement Guidelines 70 | 71 | Community leaders will follow these Community Impact Guidelines in determining 72 | the consequences for any action they deem in violation of this Code of Conduct: 73 | 74 | ### 1. Correction 75 | 76 | **Community Impact**: Use of inappropriate language or other behavior deemed 77 | unprofessional or unwelcome in the community. 78 | 79 | **Consequence**: A private, written warning from community leaders, providing 80 | clarity around the nature of the violation and an explanation of why the 81 | behavior was inappropriate. A public apology may be requested. 82 | 83 | ### 2. Warning 84 | 85 | **Community Impact**: A violation through a single incident or series 86 | of actions. 87 | 88 | **Consequence**: A warning with consequences for continued behavior. No 89 | interaction with the people involved, including unsolicited interaction with 90 | those enforcing the Code of Conduct, for a specified period of time. This 91 | includes avoiding interactions in community spaces as well as external channels 92 | like social media. Violating these terms may lead to a temporary or 93 | permanent ban. 94 | 95 | ### 3. Temporary Ban 96 | 97 | **Community Impact**: A serious violation of community standards, including 98 | sustained inappropriate behavior. 99 | 100 | **Consequence**: A temporary ban from any sort of interaction or public 101 | communication with the community for a specified period of time. No public or 102 | private interaction with the people involved, including unsolicited interaction 103 | with those enforcing the Code of Conduct, is allowed during this period. 104 | Violating these terms may lead to a permanent ban. 105 | 106 | ### 4. Permanent Ban 107 | 108 | **Community Impact**: Demonstrating a pattern of violation of community 109 | standards, including sustained inappropriate behavior, harassment of an 110 | individual, or aggression toward or disparagement of classes of individuals. 111 | 112 | **Consequence**: A permanent ban from any sort of public interaction within 113 | the community. 114 | 115 | ## Attribution 116 | 117 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], 118 | version 2.0, available at 119 | https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. 120 | 121 | Community Impact Guidelines were inspired by [Mozilla's code of conduct 122 | enforcement ladder](https://github.com/mozilla/diversity). 123 | 124 | [homepage]: https://www.contributor-covenant.org 125 | 126 | For answers to common questions about this code of conduct, see the FAQ at 127 | https://www.contributor-covenant.org/faq. Translations are available at 128 | https://www.contributor-covenant.org/translations. 129 | -------------------------------------------------------------------------------- /src/main/groovy/at/schrottner/gradle/RepositoryActionHandler.groovy: -------------------------------------------------------------------------------- 1 | package at.schrottner.gradle 2 | 3 | import at.schrottner.gradle.auths.GitLabTokenType 4 | import at.schrottner.gradle.auths.Token 5 | import groovy.transform.CompileStatic 6 | import org.gradle.api.Action 7 | import org.gradle.api.artifacts.repositories.AuthenticationContainer 8 | import org.gradle.api.artifacts.repositories.MavenArtifactRepository 9 | import org.gradle.api.credentials.HttpHeaderCredentials 10 | import org.gradle.authentication.http.HttpHeaderAuthentication 11 | import org.slf4j.Logger 12 | import org.slf4j.LoggerFactory 13 | 14 | @CompileStatic 15 | class RepositoryActionHandler implements Action { 16 | 17 | public static final String REPOSITORY_PREFIX = "GitLab" 18 | private static final Logger logger = LoggerFactory.getLogger(RepositoryActionHandler) 19 | private String baseUrl 20 | private Map tokens 21 | private RepositoryConfiguration repositoryConfiguration 22 | 23 | RepositoryActionHandler(GitlabRepositoriesExtension extension, RepositoryConfiguration repositoryConfiguration) { 24 | this.baseUrl = extension.baseUrl 25 | this.tokens = extension.tokens 26 | this.repositoryConfiguration = repositoryConfiguration 27 | } 28 | 29 | @Override 30 | void execute(MavenArtifactRepository mavenArtifactRepository) { 31 | TokenInformation tokenInformation = computeTokenInformation(repositoryConfiguration) 32 | Token token = tokenInformation.token 33 | Set tokenList = tokenInformation.tokenList 34 | if (!token) { 35 | handleInapplicableTokenCase(repositoryConfiguration, tokenList) 36 | token = new Token(GitLabTokenType.NO_VALUE) 37 | } else { 38 | logger.info("${logPrefix(repositoryConfiguration)} is using '${token.key}' '${token.type}'") 39 | } 40 | 41 | mavenArtifactRepository.url = buildUrl(repositoryConfiguration) 42 | mavenArtifactRepository.name = buildName(repositoryConfiguration) 43 | 44 | mavenArtifactRepository.credentials(HttpHeaderCredentials) { 45 | it.name = token?.type.toString() 46 | it.value = token?.value 47 | } 48 | mavenArtifactRepository.authentication(new Action() { 49 | @Override 50 | @Override 51 | void execute(AuthenticationContainer authentications) { 52 | authentications.create('header', HttpHeaderAuthentication) 53 | } 54 | }) 55 | } 56 | 57 | private TokenInformation computeTokenInformation(RepositoryConfiguration repositoryConfiguration) { 58 | Token token 59 | Set tokenList 60 | if (repositoryConfiguration.tokenSelector.getOrNull()) { 61 | logger.info("${logPrefix(repositoryConfiguration)} is using Single Token Selector '${repositoryConfiguration.tokenSelector.get()}' " + 62 | "- other tokens will be ignored") 63 | 64 | def t = tokens.get(repositoryConfiguration.tokenSelector.get()) 65 | token = t?.value ? t : null 66 | def str = repositoryConfiguration.tokenSelector.get() 67 | tokenList = new HashSet<>() 68 | tokenList.add(str) 69 | } else if (repositoryConfiguration.tokenSelectors.getOrNull()) { 70 | token = repositoryConfiguration.tokenSelectors.get().findResult { 71 | def t = tokens.get(it) 72 | return t?.value ? t : null 73 | } 74 | tokenList = repositoryConfiguration.tokenSelectors.get() 75 | } else { 76 | token = tokens.values().find { 77 | it.value 78 | } 79 | tokenList = tokens.keySet() 80 | } 81 | return new TokenInformation(token, tokenList) 82 | } 83 | 84 | private String logPrefix(RepositoryConfiguration repositoryConfiguration) { 85 | "$Config.LOG_PREFIX Maven Repository ${buildName(repositoryConfiguration)}" 86 | } 87 | 88 | private String buildName(RepositoryConfiguration repositoryConfiguration) { 89 | return repositoryConfiguration.name.getOrElse("$REPOSITORY_PREFIX-${repositoryConfiguration.entityType}-${repositoryConfiguration.id}".toString()) 90 | } 91 | 92 | private String buildUrl(RepositoryConfiguration repositoryConfiguration) { 93 | switch (repositoryConfiguration.entityType) { 94 | case GitLabEntityType.PROJECT: 95 | "https://$baseUrl/api/v4/${GitLabEntityType.PROJECT.endpoint}/${repositoryConfiguration.id}/packages/maven" 96 | break 97 | case Config.GROUP: 98 | "https://$baseUrl/api/v4/${GitLabEntityType.GROUP.endpoint}/${repositoryConfiguration.id}/-/packages/maven" 99 | break 100 | } 101 | } 102 | 103 | private void handleInapplicableTokenCase(RepositoryConfiguration repositoryConfiguration, Set applicableTokens) { 104 | logger.error("${logPrefix(repositoryConfiguration)} was not added, as no token could be applied!\n\t" + 105 | "\n\t" + 106 | "#################################################################################### \n\t" + 107 | "#################################################################################### \n\t" + 108 | "#################################################################################### \n\t" + 109 | "Currently you have configured following tokens, but none seem to resolve to a value: \n\t" + 110 | "\t- ${applicableTokens.join("\n\t\t- ")} \n\t" + 111 | "\n\t" + 112 | " Please verify your configuration - Thank you! \n\t" + 113 | "\n\t" + 114 | "#################################################################################### \n\t" + 115 | "#################################################################################### \n\t" + 116 | "#################################################################################### \n\t" + 117 | "") 118 | } 119 | 120 | 121 | private class TokenInformation { 122 | Token token 123 | Set tokenList 124 | 125 | TokenInformation(Token token, Set tokenList) { 126 | this.token = token 127 | this.tokenList = tokenList 128 | } 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /src/functionalTest/groovy/at/schrottner/gradle/ApplyTest.groovy: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2021 the original author or authors. 3 | * 4 | * All rights reserved. This program and the accompanying materials are 5 | * made available under the terms of the Eclipse Public License v2.0 which 6 | * accompanies this distribution and is available at 7 | * 8 | * http://www.eclipse.org/legal/epl-v20.html 9 | */ 10 | package at.schrottner.gradle 11 | 12 | import static org.assertj.core.api.Assertions.assertThat 13 | 14 | import org.gradle.internal.impldep.org.apache.commons.io.FileUtils 15 | import org.gradle.testkit.runner.BuildResult 16 | import org.slf4j.Logger 17 | import org.slf4j.LoggerFactory 18 | 19 | // TODO: check if we can parameterize this somehow 20 | 21 | class ApplyTest extends AbstractFunctionalTests { 22 | 23 | @PluginTest 24 | void "only used in settings"(String primer) { 25 | //given: 26 | 27 | //when: 28 | BuildResult result = runTest() 29 | 30 | //then: 31 | realms.each { 32 | def capitalized = it.capitalize() 33 | def repoPrefix = "GitLab-${capitalized}" 34 | assertThat(result.output) 35 | .contains("BUILD SUCCESSFUL") 36 | .containsSubsequence( 37 | "added Job-Token: jobToken", 38 | "added Private-Token: tokenIgnoredNoValue", 39 | "added Deploy-Token: token0", 40 | "added Deploy-Token: token1" 41 | ) 42 | .containsSubsequence("Maven Repository $repoPrefix-$existingId is using 'token0'", 43 | "Maven Repository $it-renamed is using 'token0'", 44 | "Maven Repository $repoPrefix-specialToken is using 'token0'", 45 | "Maven Repository $repoPrefix-specialToken1 is using 'token1'", 46 | "Maven Repository $repoPrefix-specialTokenSelection is using 'token1'", 47 | "Maven Repository $repoPrefix-ignoredNoValue was not added, as no token could be applied!" 48 | ) 49 | .doesNotContain("Maven Repository $repoPrefix-ignoredNoValue is using '") 50 | } 51 | } 52 | 53 | @PluginTest 54 | void "only used in project"(String primer) { 55 | //given: 56 | 57 | //when: 58 | BuildResult result = runTest() 59 | 60 | //then: 61 | realms.each { 62 | def capitalized = it.capitalize() 63 | def repoPrefix = "GitLab-${capitalized}" 64 | assertThat(result.output) 65 | .contains("BUILD SUCCESSFUL") 66 | .containsSubsequence( 67 | "added Job-Token: jobToken", 68 | "added Private-Token: tokenIgnoredNoValue", 69 | "added Private-Token: token0", 70 | "added Private-Token: token1" 71 | ) 72 | .containsSubsequence("Maven Repository $repoPrefix-$existingId is using 'token0'", 73 | "Maven Repository $it-renamed is using 'token0'", 74 | "Maven Repository $repoPrefix-specialToken is using 'token0'", 75 | "Maven Repository $repoPrefix-specialToken1 is using 'token1'", 76 | "Maven Repository $repoPrefix-specialTokenSelection is using 'token1'", 77 | "Maven Repository $repoPrefix-ignoredNoValue was not added, as no token could be applied!" 78 | ) 79 | .doesNotContain("Maven Repository $repoPrefix-ignoredNoValue is using '") 80 | } 81 | } 82 | 83 | @PluginTest 84 | void "used in settings and project"(String primer) { 85 | //given: 86 | 87 | //when: 88 | BuildResult result = runTest() 89 | 90 | //then: 91 | realms.each { 92 | def capitalized = it.capitalize() 93 | def repoPrefix = "GitLab-${capitalized}" 94 | assertThat(result.output) 95 | .contains("BUILD SUCCESSFUL") 96 | .containsSubsequence( 97 | "added Job-Token: jobToken", 98 | "added Private-Token: tokenIgnoredNoValue", 99 | "added Deploy-Token: token0", 100 | "added Deploy-Token: token1", 101 | "Settings evaluated", 102 | "replaced Private-Token: tokenIgnoredNoValue", 103 | "replaced Private-Token: token0", 104 | "replaced Private-Token: token1", 105 | "added Deploy-Token: tokenAdded" 106 | ) 107 | .containsSubsequence("Maven Repository $repoPrefix-$existingId is using 'token0'", 108 | "Maven Repository $it-renamed is using 'token0'", 109 | "Maven Repository $repoPrefix-specialToken is using 'token0'", 110 | "Maven Repository $repoPrefix-specialToken1 is using 'token1'", 111 | "Maven Repository $repoPrefix-specialTokenSelection is using 'token1'", 112 | "Maven Repository $repoPrefix-ignoredNoValue was not added, as no token could be applied!" 113 | ) 114 | .doesNotContain("Maven Repository $repoPrefix-ignoredNoValue is using '") 115 | } 116 | } 117 | 118 | @PluginTest 119 | void "used in settings and project without applying"(String primer) { 120 | //given: 121 | 122 | //when: 123 | BuildResult result = runTest() 124 | 125 | //then: 126 | realms.each { 127 | def capitalized = it.capitalize() 128 | def repoPrefix = "GitLab-${capitalized}" 129 | assertThat(result.output) 130 | .contains("BUILD SUCCESSFUL") 131 | .containsSubsequence( 132 | "added Job-Token: jobToken", 133 | "added Private-Token: tokenIgnoredNoValue", 134 | "added Deploy-Token: token0", 135 | "added Deploy-Token: token1", 136 | "Settings evaluated", 137 | "replaced Private-Token: tokenIgnoredNoValue", 138 | "replaced Private-Token: token0", 139 | "replaced Private-Token: token1", 140 | "added Deploy-Token: tokenAdded" 141 | ) 142 | .containsSubsequence("Maven Repository $repoPrefix-$existingId is using 'token0'", 143 | "Maven Repository $it-renamed is using 'token0'", 144 | "Maven Repository $repoPrefix-specialToken is using 'token0'", 145 | "Maven Repository $repoPrefix-specialToken1 is using 'token1'", 146 | "Maven Repository $repoPrefix-specialTokenSelection is using 'token1'", 147 | "Maven Repository $repoPrefix-ignoredNoValue was not added, as no token could be applied!" 148 | ) 149 | .doesNotContain("Maven Repository $repoPrefix-ignoredNoValue is using '") 150 | } 151 | } 152 | 153 | @PluginTest 154 | void "subproject test"(String primer) { 155 | //given: 156 | 157 | //when: 158 | BuildResult result = runTest() 159 | assertThat(result.output) 160 | .contains("BUILD SUCCESSFUL") 161 | .containsSubsequence( 162 | "added Job-Token: jobToken", 163 | "added Private-Token: tokenIgnoredNoValue", 164 | "added Deploy-Token: token0", 165 | "added Deploy-Token: token1", 166 | "Settings evaluated", 167 | "Configure project :", 168 | "readding Token from Parent Job-Token: jobToken", 169 | "readding Token from Parent Private-Token: tokenIgnoredNoValue", 170 | "readding Token from Parent Deploy-Token: token0", 171 | "readding Token from Parent Deploy-Token: token1", 172 | "replaced Private-Token: tokenIgnoredNoValue", 173 | "replaced Private-Token: token0", 174 | "replaced Private-Token: token1", 175 | "Configure project :subproject1", 176 | "readding Token from Parent Job-Token: jobToken", 177 | "readding Token from Parent Private-Token: tokenIgnoredNoValue", 178 | "readding Token from Parent Deploy-Token: token0", 179 | "readding Token from Parent Deploy-Token: token1", 180 | "added Deploy-Token: tokenAdded", 181 | "added Deploy-Token: tokenAdded1", 182 | "replaced Deploy-Token: token0", 183 | "Configure project :subproject2", 184 | "readding Token from Parent Job-Token: jobToken", 185 | "readding Token from Parent Private-Token: tokenIgnoredNoValue", 186 | "readding Token from Parent Deploy-Token: token0", 187 | "readding Token from Parent Deploy-Token: token1", 188 | "added Deploy-Token: tokenAdded", 189 | "added Deploy-Token: tokenAdded1", 190 | "replaced Deploy-Token: token0", 191 | ) 192 | } 193 | } 194 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 4 | # Copyright © 2015-2021 the original authors. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | ############################################################################## 20 | # 21 | # Gradle start up script for POSIX generated by Gradle. 22 | # 23 | # Important for running: 24 | # 25 | # (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is 26 | # noncompliant, but you have some other compliant shell such as ksh or 27 | # bash, then to run this script, type that shell name before the whole 28 | # command line, like: 29 | # 30 | # ksh Gradle 31 | # 32 | # Busybox and similar reduced shells will NOT work, because this script 33 | # requires all of these POSIX shell features: 34 | # * functions; 35 | # * expansions «$var», «${var}», «${var:-default}», «${var+SET}», 36 | # «${var#prefix}», «${var%suffix}», and «$( cmd )»; 37 | # * compound commands having a testable exit status, especially «case»; 38 | # * various built-in commands including «command», «set», and «ulimit». 39 | # 40 | # Important for patching: 41 | # 42 | # (2) This script targets any POSIX shell, so it avoids extensions provided 43 | # by Bash, Ksh, etc; in particular arrays are avoided. 44 | # 45 | # The "traditional" practice of packing multiple parameters into a 46 | # space-separated string is a well documented source of bugs and security 47 | # problems, so this is (mostly) avoided, by progressively accumulating 48 | # options in "$@", and eventually passing that to Java. 49 | # 50 | # Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, 51 | # and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; 52 | # see the in-line comments for details. 53 | # 54 | # There are tweaks for specific operating systems such as AIX, CygWin, 55 | # Darwin, MinGW, and NonStop. 56 | # 57 | # (3) This script is generated from the Groovy template 58 | # https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt 59 | # within the Gradle project. 60 | # 61 | # You can find Gradle at https://github.com/gradle/gradle/. 62 | # 63 | ############################################################################## 64 | 65 | # Attempt to set APP_HOME 66 | 67 | # Resolve links: $0 may be a link 68 | app_path=$0 69 | 70 | # Need this for daisy-chained symlinks. 71 | while 72 | APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path 73 | [ -h "$app_path" ] 74 | do 75 | ls=$( ls -ld "$app_path" ) 76 | link=${ls#*' -> '} 77 | case $link in #( 78 | /*) app_path=$link ;; #( 79 | *) app_path=$APP_HOME$link ;; 80 | esac 81 | done 82 | 83 | APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit 84 | 85 | APP_NAME="Gradle" 86 | APP_BASE_NAME=${0##*/} 87 | 88 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 89 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' 90 | 91 | # Use the maximum available, or set MAX_FD != -1 to use that value. 92 | MAX_FD=maximum 93 | 94 | warn () { 95 | echo "$*" 96 | } >&2 97 | 98 | die () { 99 | echo 100 | echo "$*" 101 | echo 102 | exit 1 103 | } >&2 104 | 105 | # OS specific support (must be 'true' or 'false'). 106 | cygwin=false 107 | msys=false 108 | darwin=false 109 | nonstop=false 110 | case "$( uname )" in #( 111 | CYGWIN* ) cygwin=true ;; #( 112 | Darwin* ) darwin=true ;; #( 113 | MSYS* | MINGW* ) msys=true ;; #( 114 | NONSTOP* ) nonstop=true ;; 115 | esac 116 | 117 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 118 | 119 | 120 | # Determine the Java command to use to start the JVM. 121 | if [ -n "$JAVA_HOME" ] ; then 122 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 123 | # IBM's JDK on AIX uses strange locations for the executables 124 | JAVACMD=$JAVA_HOME/jre/sh/java 125 | else 126 | JAVACMD=$JAVA_HOME/bin/java 127 | fi 128 | if [ ! -x "$JAVACMD" ] ; then 129 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 130 | 131 | Please set the JAVA_HOME variable in your environment to match the 132 | location of your Java installation." 133 | fi 134 | else 135 | JAVACMD=java 136 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 137 | 138 | Please set the JAVA_HOME variable in your environment to match the 139 | location of your Java installation." 140 | fi 141 | 142 | # Increase the maximum file descriptors if we can. 143 | if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then 144 | case $MAX_FD in #( 145 | max*) 146 | MAX_FD=$( ulimit -H -n ) || 147 | warn "Could not query maximum file descriptor limit" 148 | esac 149 | case $MAX_FD in #( 150 | '' | soft) :;; #( 151 | *) 152 | ulimit -n "$MAX_FD" || 153 | warn "Could not set maximum file descriptor limit to $MAX_FD" 154 | esac 155 | fi 156 | 157 | # Collect all arguments for the java command, stacking in reverse order: 158 | # * args from the command line 159 | # * the main class name 160 | # * -classpath 161 | # * -D...appname settings 162 | # * --module-path (only if needed) 163 | # * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. 164 | 165 | # For Cygwin or MSYS, switch paths to Windows format before running java 166 | if "$cygwin" || "$msys" ; then 167 | APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) 168 | CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) 169 | 170 | JAVACMD=$( cygpath --unix "$JAVACMD" ) 171 | 172 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 173 | for arg do 174 | if 175 | case $arg in #( 176 | -*) false ;; # don't mess with options #( 177 | /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath 178 | [ -e "$t" ] ;; #( 179 | *) false ;; 180 | esac 181 | then 182 | arg=$( cygpath --path --ignore --mixed "$arg" ) 183 | fi 184 | # Roll the args list around exactly as many times as the number of 185 | # args, so each arg winds up back in the position where it started, but 186 | # possibly modified. 187 | # 188 | # NB: a `for` loop captures its iteration list before it begins, so 189 | # changing the positional parameters here affects neither the number of 190 | # iterations, nor the values presented in `arg`. 191 | shift # remove old arg 192 | set -- "$@" "$arg" # push replacement arg 193 | done 194 | fi 195 | 196 | # Collect all arguments for the java command; 197 | # * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of 198 | # shell script including quotes and variable substitutions, so put them in 199 | # double quotes to make sure that they get re-expanded; and 200 | # * put everything else in single quotes, so that it's not re-expanded. 201 | 202 | set -- \ 203 | "-Dorg.gradle.appname=$APP_BASE_NAME" \ 204 | -classpath "$CLASSPATH" \ 205 | org.gradle.wrapper.GradleWrapperMain \ 206 | "$@" 207 | 208 | # Use "xargs" to parse quoted args. 209 | # 210 | # With -n1 it outputs one arg per line, with the quotes and backslashes removed. 211 | # 212 | # In Bash we could simply go: 213 | # 214 | # readarray ARGS < <( xargs -n1 <<<"$var" ) && 215 | # set -- "${ARGS[@]}" "$@" 216 | # 217 | # but POSIX shell has neither arrays nor command substitution, so instead we 218 | # post-process each arg (as a line of input to sed) to backslash-escape any 219 | # character that might be a shell metacharacter, then use eval to reverse 220 | # that process (while maintaining the separation between arguments), and wrap 221 | # the whole thing up as a single "set" statement. 222 | # 223 | # This will of course break if any of these variables contains a newline or 224 | # an unmatched quote. 225 | # 226 | 227 | eval "set -- $( 228 | printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | 229 | xargs -n1 | 230 | sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | 231 | tr '\n' ' ' 232 | )" '"$@"' 233 | 234 | exec "$JAVACMD" "$@" 235 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Gradle GitLab Repositories Plugin 2 | 3 | Handling Maven GitLab dependencies easy. Define multiple tokens and selectively apply them to repositories. 4 | 5 | Adding a GitLab repository to your project is tiresome, based on the documentation you need to have different Tokens in 6 | place for different systems. 7 | The [GitLab Documentation](https://docs.gitlab.com/ee/user/packages/maven_repository/#authenticate-to-the-package-registry-with-gradle) 8 | shows the different types of Tokens, which can be used. 9 | 10 | There are: 11 | 12 | - Job-Tokens for CI 13 | - Private-Tokens for Users 14 | - Deploy-Tokens for external systems 15 | 16 | Additionally, all tokens use a different name for the HttpHeaderCredentials. 17 | 18 | Sometimes, there is even the need for gradle-plugin specific repositories and for project specific ones, which can also 19 | overlap. 20 | 21 | This plugin tries to cover this by allowing to reapply the same plugins, even to each project. 22 | 23 | ## Background 24 | 25 | We were in the migration phase from self-hosted development infrastructure (SCM, Nexus, Jenkins, SonarQube) to GitLab 26 | and Sonarcloud.io. During the migration phase we needed to support all 3 types of Tokens: 27 | 28 | - Job Token for GitLab CI 29 | - Deploy Token for 3rd Party systems like Jenkins 30 | - Private Token for local development 31 | 32 | Configuring multiple repositories with repeated configuration was bloating our gradle files. Additionally, minor 33 | mistakes like forgetting some parts in the configuration, made it really hard to migrate and follow up. 34 | 35 | In the end we investigated and come up with this solution. It will for sure fit not all needs, but it is a starting 36 | point. It might help others to easily setup this configuration and if there is demand, there is also room for 37 | improvements. 38 | 39 | # Usage 40 | 41 | ## Configuration 42 | 43 | ### Groovy DSL 44 | ```groovy 45 | gitLab { 46 | /** 47 | * Token configuration also the order in which we try to apply them. 48 | * The key is the name of the token, and the value will be used for application. 49 | * Currently we do have 3 different token classes: 50 | * - PrivateToken 51 | * - DeployToken 52 | * - JobToken (will be always added by default, based on CI_JOB_TOKEN) 53 | * */ 54 | token(PrivateToken) { 55 | it.key = 'private' 56 | it.value = gitLabPrivateToken // assumed variable in gradle.properties 57 | } 58 | token(DeployToken) { 59 | it.key = 'deploy' 60 | it.value = System.getenv("GITLAB_DEPLOY_TOKEN") 61 | } 62 | } 63 | ``` 64 | 65 | ### Kotlin DSL 66 | 67 | ```kotlin 68 | configure { 69 | /** 70 | * Token configuration also the order in which we try to apply them. 71 | * The key is the name of the token, and the value will be used for application. 72 | * Currently we do have 3 different token classes: 73 | * - PrivateToken "private" 74 | * - DeployToken "deploy" 75 | * - JobToken (will be always added by default, based on CI_JOB_TOKEN) 76 | * */ 77 | token("private", { 78 | key = "private" 79 | value = "" 80 | }) 81 | token("deploy", { 82 | key = "tokenAdded" 83 | value = System.getenv("GITLAB_DEPLOY_TOKEN") 84 | }) 85 | } 86 | 87 | ``` 88 | 89 | ## Applying the plugin 90 | 91 | The plugin can be used within `build.gradle` and within `settings.gradle`. 92 | 93 | If there is no need to apply special repositories to the `build.gradle` it might be enough, to just apply it to the 94 | settings. 95 | 96 | ### Groovy DSL 97 | 98 | #### build.gradle 99 | 100 | ```groovy 101 | plugins { 102 | id 'at.schrottner.gitlab-repositories' version '' 103 | } 104 | ``` 105 | 106 | #### settings.gradle 107 | 108 | ```groovy 109 | buildscript { 110 | // ... 111 | dependencies { 112 | classpath 'at.schrottner.gradle.gitlab-plugin:gitlab-repositories:' 113 | } 114 | } 115 | 116 | apply plugin: 'at.schrottner.gitlab-repositories' 117 | ``` 118 | 119 | ### Kotlin DSL 120 | 121 | #### build.gradle.kts 122 | 123 | ```kotlin 124 | plugins { 125 | id("at.schrottner.gitlab-repositories") version "" 126 | } 127 | ``` 128 | 129 | #### settings.gradle.kts 130 | 131 | ```kotlin 132 | buildscript { 133 | // .. 134 | dependencies { 135 | classpath("at.schrottner.gradle.gitlab-plugin:gitlab-repositories:") 136 | } 137 | } 138 | 139 | apply(plugin = "at.schrottner.gitlab-repositories") 140 | ``` 141 | 142 | ## Repository handling 143 | 144 | ### Adding repositories for dependencies 145 | 146 | The plugin offers you a nice helper method inspired by `gradle-jruby-plugin` to easily add repositories. 147 | 148 | #### Groovy DSL 149 | 150 | ```groovy 151 | repositories { 152 | maven gitLab.project(projectId) 153 | maven gitLab.project(projectId) { 154 | name = "custom name" 155 | tokenSelektor = "" // a name of a configured token 156 | tokenSelectors = [] // a list of configured tokens, which will be checked based on their order in this set 157 | } 158 | maven gitLab.group(groupId) 159 | maven gitLab.group(groupId) { 160 | name = "custom name" 161 | tokenSelektor = "" // a name of a configured token 162 | tokenSelectors = [] // a list of configured tokens, which will be checked based on their order in this set 163 | } 164 | } 165 | ``` 166 | 167 | #### Kotlin DSL 168 | 169 | ```kotlin 170 | repositories { 171 | val gitLab = the() 172 | maven(gitLab.project(projectId)) 173 | maven(gitLab.project(projectId) { 174 | name.set("custom name") 175 | tokenSelektor.set("") // a name of a configured token 176 | tokenSelectors.addAll(/*...*/) // a list of configured tokens, which will be checked based on their order in this set 177 | }) 178 | maven(gitLab.group(groupId)) 179 | maven(gitLab.group(groupId) { 180 | name.set("custom name") 181 | tokenSelektor.set("") // a name of a configured token 182 | tokenSelectors.addAll(/*...*/) // a list of configured tokens, which will be checked based on their order in this set 183 | }) 184 | } 185 | ``` 186 | 187 | ### Adding repositories for publishing 188 | 189 | Be aware that this has to be a projectId - you are not able to upload to groups! 190 | 191 | #### Groovy DSL 192 | 193 | For adding a repository to the maven-publish repositories please use following method. 194 | 195 | ```groovy 196 | publishing { 197 | repositories { 198 | maven gitLab.upload(projectId) 199 | maven gitLab.upload(projectId) { 200 | name = "custom name" 201 | tokenSelektor = "" // a name of a configured token 202 | tokenSelectors = [] // a list of configured tokens, which will be checked based on their order in this set 203 | } 204 | } 205 | } 206 | ``` 207 | 208 | #### Kotlin DSL 209 | 210 | ```kotlin 211 | publishing { 212 | repositories { 213 | val gitLab = the() 214 | maven(gitLab.upload(projectId) { 215 | name.set("GitLab") 216 | tokenSelector.set("testToken") 217 | }) 218 | } 219 | } 220 | ``` 221 | 222 | ### Adding a repository with defaults 223 | 224 | This will add a repository and will apply conditions for the first token matching, and not being empty. 225 | 226 | ```groovy 227 | // pluginManagment.repositories { // when in settings.gradle 228 | repositories { 229 | maven gitLab.project(1) 230 | maven gitLab.group(1) 231 | } 232 | 233 | ``` 234 | 235 | ### Adding a repository with specific tokens 236 | 237 | We can define which tokens should be taken into account (currently order of parameter is ignored) 238 | 239 | ```groovy 240 | gitLab.project(1) { 241 | tokenSelectors = ['private', 'deploy'] 242 | } 243 | gitLab.group(1) { 244 | tokenSelectors = ['private', 'deploy'] 245 | } 246 | ``` 247 | 248 | Additionally, we can provide one specific token to be used, if the token is not set, or empty, nothing will be done. 249 | 250 | ```groovy 251 | gitLab.project(1) { tokenSelector = 'deploy' } 252 | gitLab.group(1) { tokenSelector = 'deploy' } 253 | ``` 254 | 255 | ## Comparison 256 | 257 | with the plugin 258 | 259 | ```groovy 260 | plugins { 261 | id 'maven' 262 | id 'maven-publish' 263 | id 'at.schrotter.gitlab-repositories' version '' 264 | } 265 | 266 | gitLab { 267 | // jobToken will be applied automatically 268 | token(DeployToken) { 269 | name = "deployToken" 270 | value = System.getenv("GITLAB_DEPLOY_TOKEN") 271 | } 272 | token(PrivateToken) { 273 | name = "privateToken" 274 | value = gitLabPrivateToken 275 | } 276 | } 277 | 278 | repositories { 279 | maven gitLab.group("ID") 280 | } 281 | 282 | publishing { 283 | repositories { 284 | maven gitLab.upload("ID") 285 | } 286 | } 287 | ``` 288 | 289 | without this plugin 290 | 291 | ```groovy 292 | plugins { 293 | id 'maven' 294 | id 'maven-publish' 295 | } 296 | 297 | repositories { 298 | maven { 299 | url 'GitLab Url with ID' 300 | name "GitLab" 301 | if (System.getenv("CI_JOB_TOKEN")) { 302 | credentials(HttpHeaderCredentials) { 303 | name = 'Job-Token' 304 | value = System.getenv("CI_JOB_TOKEN") 305 | } 306 | } else if (System.getenv("GITLAB_DEPLOY_TOKEN")) { 307 | credentials(HttpHeaderCredentials) { 308 | name = 'Deploy-Token' 309 | value = System.getenv("GITLAB_DEPLOY_TOKEN") 310 | } 311 | } else { 312 | credentials(HttpHeaderCredentials) { 313 | name = 'Private-Token' 314 | value = gitLabPrivateToken 315 | } 316 | } 317 | authentication { 318 | header(HttpHeaderAuthentication) 319 | } 320 | } 321 | } 322 | 323 | publishing { 324 | repositories { 325 | maven { 326 | url 'GitLab Url with ID' 327 | name "GitLab" 328 | if (System.getenv("CI_JOB_TOKEN")) { 329 | credentials(HttpHeaderCredentials) { 330 | name = 'Job-Token' 331 | value = System.getenv("CI_JOB_TOKEN") 332 | } 333 | } else if (System.getenv("GITLAB_DEPLOY_TOKEN")) { 334 | credentials(HttpHeaderCredentials) { 335 | name = 'Deploy-Token' 336 | value = System.getenv("GITLAB_DEPLOY_TOKEN") 337 | } 338 | } else { 339 | credentials(HttpHeaderCredentials) { 340 | name = 'Private-Token' 341 | value = gitLabPrivateToken 342 | } 343 | } 344 | authentication { 345 | header(HttpHeaderAuthentication) 346 | } 347 | } 348 | } 349 | } 350 | ``` 351 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Eclipse Public License - v 2.0 2 | 3 | THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE 4 | PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION 5 | OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 6 | 7 | 1. DEFINITIONS 8 | 9 | "Contribution" means: 10 | 11 | a) in the case of the initial Contributor, the initial content 12 | Distributed under this Agreement, and 13 | 14 | b) in the case of each subsequent Contributor: 15 | i) changes to the Program, and 16 | ii) additions to the Program; 17 | where such changes and/or additions to the Program originate from 18 | and are Distributed by that particular Contributor. A Contribution 19 | "originates" from a Contributor if it was added to the Program by 20 | such Contributor itself or anyone acting on such Contributor's behalf. 21 | Contributions do not include changes or additions to the Program that 22 | are not Modified Works. 23 | 24 | "Contributor" means any person or entity that Distributes the Program. 25 | 26 | "Licensed Patents" mean patent claims licensable by a Contributor which 27 | are necessarily infringed by the use or sale of its Contribution alone 28 | or when combined with the Program. 29 | 30 | "Program" means the Contributions Distributed in accordance with this 31 | Agreement. 32 | 33 | "Recipient" means anyone who receives the Program under this Agreement 34 | or any Secondary License (as applicable), including Contributors. 35 | 36 | "Derivative Works" shall mean any work, whether in Source Code or other 37 | form, that is based on (or derived from) the Program and for which the 38 | editorial revisions, annotations, elaborations, or other modifications 39 | represent, as a whole, an original work of authorship. 40 | 41 | "Modified Works" shall mean any work in Source Code or other form that 42 | results from an addition to, deletion from, or modification of the 43 | contents of the Program, including, for purposes of clarity any new file 44 | in Source Code form that contains any contents of the Program. Modified 45 | Works shall not include works that contain only declarations, 46 | interfaces, types, classes, structures, or files of the Program solely 47 | in each case in order to link to, bind by name, or subclass the Program 48 | or Modified Works thereof. 49 | 50 | "Distribute" means the acts of a) distributing or b) making available 51 | in any manner that enables the transfer of a copy. 52 | 53 | "Source Code" means the form of a Program preferred for making 54 | modifications, including but not limited to software source code, 55 | documentation source, and configuration files. 56 | 57 | "Secondary License" means either the GNU General Public License, 58 | Version 2.0, or any later versions of that license, including any 59 | exceptions or additional permissions as identified by the initial 60 | Contributor. 61 | 62 | 2. GRANT OF RIGHTS 63 | 64 | a) Subject to the terms of this Agreement, each Contributor hereby 65 | grants Recipient a non-exclusive, worldwide, royalty-free copyright 66 | license to reproduce, prepare Derivative Works of, publicly display, 67 | publicly perform, Distribute and sublicense the Contribution of such 68 | Contributor, if any, and such Derivative Works. 69 | 70 | b) Subject to the terms of this Agreement, each Contributor hereby 71 | grants Recipient a non-exclusive, worldwide, royalty-free patent 72 | license under Licensed Patents to make, use, sell, offer to sell, 73 | import and otherwise transfer the Contribution of such Contributor, 74 | if any, in Source Code or other form. This patent license shall 75 | apply to the combination of the Contribution and the Program if, at 76 | the time the Contribution is added by the Contributor, such addition 77 | of the Contribution causes such combination to be covered by the 78 | Licensed Patents. The patent license shall not apply to any other 79 | combinations which include the Contribution. No hardware per se is 80 | licensed hereunder. 81 | 82 | c) Recipient understands that although each Contributor grants the 83 | licenses to its Contributions set forth herein, no assurances are 84 | provided by any Contributor that the Program does not infringe the 85 | patent or other intellectual property rights of any other entity. 86 | Each Contributor disclaims any liability to Recipient for claims 87 | brought by any other entity based on infringement of intellectual 88 | property rights or otherwise. As a condition to exercising the 89 | rights and licenses granted hereunder, each Recipient hereby 90 | assumes sole responsibility to secure any other intellectual 91 | property rights needed, if any. For example, if a third party 92 | patent license is required to allow Recipient to Distribute the 93 | Program, it is Recipient's responsibility to acquire that license 94 | before distributing the Program. 95 | 96 | d) Each Contributor represents that to its knowledge it has 97 | sufficient copyright rights in its Contribution, if any, to grant 98 | the copyright license set forth in this Agreement. 99 | 100 | e) Notwithstanding the terms of any Secondary License, no 101 | Contributor makes additional grants to any Recipient (other than 102 | those set forth in this Agreement) as a result of such Recipient's 103 | receipt of the Program under the terms of a Secondary License 104 | (if permitted under the terms of Section 3). 105 | 106 | 3. REQUIREMENTS 107 | 108 | 3.1 If a Contributor Distributes the Program in any form, then: 109 | 110 | a) the Program must also be made available as Source Code, in 111 | accordance with section 3.2, and the Contributor must accompany 112 | the Program with a statement that the Source Code for the Program 113 | is available under this Agreement, and informs Recipients how to 114 | obtain it in a reasonable manner on or through a medium customarily 115 | used for software exchange; and 116 | 117 | b) the Contributor may Distribute the Program under a license 118 | different than this Agreement, provided that such license: 119 | i) effectively disclaims on behalf of all other Contributors all 120 | warranties and conditions, express and implied, including 121 | warranties or conditions of title and non-infringement, and 122 | implied warranties or conditions of merchantability and fitness 123 | for a particular purpose; 124 | 125 | ii) effectively excludes on behalf of all other Contributors all 126 | liability for damages, including direct, indirect, special, 127 | incidental and consequential damages, such as lost profits; 128 | 129 | iii) does not attempt to limit or alter the recipients' rights 130 | in the Source Code under section 3.2; and 131 | 132 | iv) requires any subsequent distribution of the Program by any 133 | party to be under a license that satisfies the requirements 134 | of this section 3. 135 | 136 | 3.2 When the Program is Distributed as Source Code: 137 | 138 | a) it must be made available under this Agreement, or if the 139 | Program (i) is combined with other material in a separate file or 140 | files made available under a Secondary License, and (ii) the initial 141 | Contributor attached to the Source Code the notice described in 142 | Exhibit A of this Agreement, then the Program may be made available 143 | under the terms of such Secondary Licenses, and 144 | 145 | b) a copy of this Agreement must be included with each copy of 146 | the Program. 147 | 148 | 3.3 Contributors may not remove or alter any copyright, patent, 149 | trademark, attribution notices, disclaimers of warranty, or limitations 150 | of liability ("notices") contained within the Program from any copy of 151 | the Program which they Distribute, provided that Contributors may add 152 | their own appropriate notices. 153 | 154 | 4. COMMERCIAL DISTRIBUTION 155 | 156 | Commercial distributors of software may accept certain responsibilities 157 | with respect to end users, business partners and the like. While this 158 | license is intended to facilitate the commercial use of the Program, 159 | the Contributor who includes the Program in a commercial product 160 | offering should do so in a manner which does not create potential 161 | liability for other Contributors. Therefore, if a Contributor includes 162 | the Program in a commercial product offering, such Contributor 163 | ("Commercial Contributor") hereby agrees to defend and indemnify every 164 | other Contributor ("Indemnified Contributor") against any losses, 165 | damages and costs (collectively "Losses") arising from claims, lawsuits 166 | and other legal actions brought by a third party against the Indemnified 167 | Contributor to the extent caused by the acts or omissions of such 168 | Commercial Contributor in connection with its distribution of the Program 169 | in a commercial product offering. The obligations in this section do not 170 | apply to any claims or Losses relating to any actual or alleged 171 | intellectual property infringement. In order to qualify, an Indemnified 172 | Contributor must: a) promptly notify the Commercial Contributor in 173 | writing of such claim, and b) allow the Commercial Contributor to control, 174 | and cooperate with the Commercial Contributor in, the defense and any 175 | related settlement negotiations. The Indemnified Contributor may 176 | participate in any such claim at its own expense. 177 | 178 | For example, a Contributor might include the Program in a commercial 179 | product offering, Product X. That Contributor is then a Commercial 180 | Contributor. If that Commercial Contributor then makes performance 181 | claims, or offers warranties related to Product X, those performance 182 | claims and warranties are such Commercial Contributor's responsibility 183 | alone. Under this section, the Commercial Contributor would have to 184 | defend claims against the other Contributors related to those performance 185 | claims and warranties, and if a court requires any other Contributor to 186 | pay any damages as a result, the Commercial Contributor must pay 187 | those damages. 188 | 189 | 5. NO WARRANTY 190 | 191 | EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, AND TO THE EXTENT 192 | PERMITTED BY APPLICABLE LAW, THE PROGRAM IS PROVIDED ON AN "AS IS" 193 | BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR 194 | IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF 195 | TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR 196 | PURPOSE. Each Recipient is solely responsible for determining the 197 | appropriateness of using and distributing the Program and assumes all 198 | risks associated with its exercise of rights under this Agreement, 199 | including but not limited to the risks and costs of program errors, 200 | compliance with applicable laws, damage to or loss of data, programs 201 | or equipment, and unavailability or interruption of operations. 202 | 203 | 6. DISCLAIMER OF LIABILITY 204 | 205 | EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, AND TO THE EXTENT 206 | PERMITTED BY APPLICABLE LAW, NEITHER RECIPIENT NOR ANY CONTRIBUTORS 207 | SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 208 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST 209 | PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 210 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 211 | ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE 212 | EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE 213 | POSSIBILITY OF SUCH DAMAGES. 214 | 215 | 7. GENERAL 216 | 217 | If any provision of this Agreement is invalid or unenforceable under 218 | applicable law, it shall not affect the validity or enforceability of 219 | the remainder of the terms of this Agreement, and without further 220 | action by the parties hereto, such provision shall be reformed to the 221 | minimum extent necessary to make such provision valid and enforceable. 222 | 223 | If Recipient institutes patent litigation against any entity 224 | (including a cross-claim or counterclaim in a lawsuit) alleging that the 225 | Program itself (excluding combinations of the Program with other software 226 | or hardware) infringes such Recipient's patent(s), then such Recipient's 227 | rights granted under Section 2(b) shall terminate as of the date such 228 | litigation is filed. 229 | 230 | All Recipient's rights under this Agreement shall terminate if it 231 | fails to comply with any of the material terms or conditions of this 232 | Agreement and does not cure such failure in a reasonable period of 233 | time after becoming aware of such noncompliance. If all Recipient's 234 | rights under this Agreement terminate, Recipient agrees to cease use 235 | and distribution of the Program as soon as reasonably practicable. 236 | However, Recipient's obligations under this Agreement and any licenses 237 | granted by Recipient relating to the Program shall continue and survive. 238 | 239 | Everyone is permitted to copy and distribute copies of this Agreement, 240 | but in order to avoid inconsistency the Agreement is copyrighted and 241 | may only be modified in the following manner. The Agreement Steward 242 | reserves the right to publish new versions (including revisions) of 243 | this Agreement from time to time. No one other than the Agreement 244 | Steward has the right to modify this Agreement. The Eclipse Foundation 245 | is the initial Agreement Steward. The Eclipse Foundation may assign the 246 | responsibility to serve as the Agreement Steward to a suitable separate 247 | entity. Each new version of the Agreement will be given a distinguishing 248 | version number. The Program (including Contributions) may always be 249 | Distributed subject to the version of the Agreement under which it was 250 | received. In addition, after a new version of the Agreement is published, 251 | Contributor may elect to Distribute the Program (including its 252 | Contributions) under the new version. 253 | 254 | Except as expressly stated in Sections 2(a) and 2(b) above, Recipient 255 | receives no rights or licenses to the intellectual property of any 256 | Contributor under this Agreement, whether expressly, by implication, 257 | estoppel or otherwise. All rights in the Program not expressly granted 258 | under this Agreement are reserved. Nothing in this Agreement is intended 259 | to be enforceable by any entity that is not a Contributor or Recipient. 260 | No third-party beneficiary rights are created under this Agreement. 261 | 262 | Exhibit A - Form of Secondary Licenses Notice 263 | 264 | "This Source Code may also be made available under the following 265 | Secondary Licenses when the conditions for such availability set forth 266 | in the Eclipse Public License, v. 2.0 are satisfied: {name license(s), 267 | version(s), and exceptions or additional permissions here}." 268 | 269 | Simply including a copy of this Agreement, including this Exhibit A 270 | is not sufficient to license the Source Code under Secondary Licenses. 271 | 272 | If it is not possible or desirable to put the notice in a particular 273 | file, then You may include the notice in a location (such as a LICENSE 274 | file in a relevant directory) where a recipient would be likely to 275 | look for such a notice. 276 | 277 | You may add additional accurate notices of copyright ownership. 278 | --------------------------------------------------------------------------------