Gradle Artifactory deploy fails when using generated gradle.properties - gradle

I have the following build.gradle file:
plugins {
id 'java-gradle-plugin'
id 'com.gradle.plugin-publish' version '0.10.1'
id 'groovy'
id 'maven-publish'
id "com.jfrog.artifactory" version "4.9.1"
}
group = 'de.gafertp'
version = '2.0.0'
repositories {
mavenCentral()
}
dependencies {
compile 'net.sourceforge.plantuml:plantuml:1.2019.1'
testCompile 'org.junit.jupiter:junit-jupiter-api:5.4.0'
testCompile 'org.junit-pioneer:junit-pioneer:0.3.0'
testRuntime 'org.junit.jupiter:junit-jupiter-engine:5.4.0'
}
gradlePlugin {
plugins {
plantUmlPlugin {
id = 'de.gafertp.plantuml'
displayName = 'Gradle PlantUML Plugin'
description = 'A very simple plugin to render PlantUML files. ' +
'Takes a set of diagram files together with desired output files / formats ' +
'and renders them with PlantUML (http://plantuml.com/).'
implementationClass = 'de.gafertp.PlantUmlPlugin'
}
}
}
pluginBundle {
website = 'https://github.com/codecholeric/gradle-plantuml-plugin'
vcsUrl = 'https://github.com/codecholeric/gradle-plantuml-plugin'
tags = ['plantuml']
}
publishing {
publications {
plantUmlPluginJar(MavenPublication) {
from components.java
}
}
}
artifactory {
contextUrl = "${artifactory_contextUrl}"
publish {
repository {
repoKey = 'gradle-dev-local'
username = "${artifactory_user}"
password = "${artifactory_password}"
println "username=${artifactory_user}"
println "password=${artifactory_password}"
maven = true
}
defaults {
publications('plantUmlPluginJar')
}
}
resolve {
repository {
repoKey = 'gradle-dev'
username = "${artifactory_user}"
password = "${artifactory_password}"
maven = true
}
}
}
test {
useJUnitPlatform()
}
And this gradle.properties file:
artifactory_user=${security.getCurrentUsername()}
artifactory_password=${security.getEncryptedPassword()!"blahblah"}
artifactory_contextUrl=http://localhost:8081/artifactory
The build fails with the following error:
Execution failed for task ':artifactoryDeploy'.
> java.io.IOException: Failed to deploy file. Status code: 401 Response message: Artifactory returned the following errors:
Unauthorized Status code: 401
If we take a look at the printed username and password, we see this:
username=${security.getCurrentUsername()}
password=${security.getEncryptedPassword()!"blahblah"}
Gradle takes the properties values as literal strings instead of evaluating them. So the issue seems to be that the security object cannot be found, because if I replace the properties in build.gradle file with their values directly, the following error occurs:
A problem occurred evaluating root project 'gradle-plantuml-plugin'.
> Could not get unknown property 'security' for object of type org.jfrog.gradle.plugin.artifactory.dsl.DoubleDelegateWrapper.
What am I doing wrong? The deploy works fine when using plaintext username and password, but I would like to use the auto-generated way of logging in (using an encrypted password).

It seems that gradle.properties should look like this:
username=your_username
password=blahblah
We suppose that blahblah is your encrypted password.

Related

Could not get unknown property 'mavenUser' for Credentials [username: null]

I've got this error : Could not get unknown property 'mavenUser' for Credentials [username: null] of type org.gradle.internal.credentials.DefaultPasswordCredentials_Decorated during the gradle build, although I've already created a gradle properties file with the right credentials in the gradle home directory
buildscript {
ext {
nexusBaseUrl = 'http://....'
// Dependencies version
springBootVersion = '2.7.2'
sonarqubeVersion = '3.3'
mybatisSpringBootStarterTestVersion = '2.2.2'
mybatisSpringBootStarterVersion = '2.2.2'
}
repositories {
maven {
url "${nexusBaseUrl}/mha-maven-public/"
allowInsecureProtocol = true
credentials {
username "${mavenUser}"
password "${mavenPassword}"
}
}
}
dependencies {
classpath "org.springframework.boot:spring-boot-gradle-plugin:$springBootVersion"
classpath "org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:$sonarqubeVersion"
}
}

Maven publish plugin complains no username provided but its there

I am trying to push a jar to artifactory, i get the following error from the gradle script:
But the username is there, is hardcoded to "aws":
publishing {
publications {
publicMyArtifact(MavenPublication) {
groupId "com.company.project"
artifactId "artifact"
version = "1.0"
afterEvaluate {
artifact "repo/path/*.jar"
}
}
}
repositories {
maven {
name "reponame"
url "https://accountnumber.d.codeartifact.eu-central-1.amazonaws.com/maven"
credentials {
username = "aws"
password = System.getenv("CODEARTIFACT_AUTH_TOKEN")
}
}
}
}
I invoke this task with the following line in jenkins: sh "./gradlew publish"
Any idea what could be possibly the reason?

Gradle signArchives unable to read Secret Key

I am trying to publish my Java Library to Maven Central. A part of this involves using the signing gradle plugin to sign the artifacts. I need to sign it without using the keyring file as document here as I cant provide my CI secure access to the key ring file.
However when I do this my build fails with:
FAILURE: Build failed with an exception.
* What went wrong:
Could not evaluate onlyIf predicate for task ':signArchives'.
> Could not read PGP secret key
What am I doing wrong? I presume it is related to my GPG_SIGNING_KEY.
I used the full private key from the response of gpg --list-secret-keys --keyid-format LONG. Is this not correct?
My build.gradle
apply plugin: 'java'
apply plugin: 'signing'
apply plugin: 'maven'
apply from: 'publish.gradle'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
compile group: 'org.apache.httpcomponents', name: 'httpclient', version: '4.5.3'
testCompile 'junit:junit:4.11'
}
task Wrapper(type: Wrapper) {
gradleVersion = '5.6.2'
}
My publish.gradle
apply plugin: 'maven'
apply plugin: 'signing'
def isReleaseBuild() {
return !VERSION.contains("SNAPSHOT")
}
def getReleaseRepositoryUrl() {
return 'https://oss.sonatype.org/service/local/staging/deploy/maven2/'
}
def getSnapshotRepositoryUrl() {
return 'https://oss.sonatype.org/content/repositories/snapshots/'
}
afterEvaluate { project ->
uploadArchives {
repositories {
mavenDeployer {
beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) }
repository(url: getReleaseRepositoryUrl()) {
def ossrhUsername = OSSRH_USERNAME
def ossrhPassword = OSSRH_PASSWORD
authentication(userName: ossrhUsername, password: ossrhPassword)
}
snapshotRepository(url: getSnapshotRepositoryUrl()) {
def ossrhUsername = OSSRH_USERNAME
def ossrhPassword = OSSRH_PASSWORD
authentication(userName: ossrhUsername, password: ossrhPassword)
}
pom.groupId = GROUP_ID
pom.artifactId = ARTIFACT_ID
pom.version = VERSION
pom.project {
name ARTIFACT_ID
packaging PROJECT_PACKAGING
description PROJECT_DESCRIPTION
url PROJECT_URL
scm {
url SCM_URL
connection SCM_CONNECTION
}
licenses {
license {
name LICENSE_NAME
url LICENSE_URL
}
}
organization {
name = ORGANIZATION_NAME
url = ORGANIZATION_URL
}
developers {
developer {
id DEVELOPER_ID
name DEVELOPER_NAME
email DEVELOPER_EMAIL
}
}
}
}
}
signing {
required { isReleaseBuild() && gradle.taskGraph.hasTask("uploadArchives") }
def signingKey = GPG_SIGNING_KEY
def signingPassword = GPG_SIGNING_PASSWORD
useInMemoryPgpKeys(signingKey, signingPassword)
sign configurations.archives
}
task javadocJar(type: Jar) {
classifier = 'javadoc'
from javadoc
}
task sourcesJar(type: Jar) {
classifier = 'sources'
from sourceSets.main.allSource
}
artifacts {
archives javadocJar, sourcesJar
}
}
}
And with gradle.properties
RELEASE_REPOSITORY_URL='https://oss.sonatype.org/service/local/staging/deploy/maven2/'
SNAPSHOT_REPOSITORY_URL='https://oss.sonatype.org/content/repositories/snapshots/'
GPG_SIGNING_KEY=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
GPG_SIGNING_PASSWORD=the password used to encrypt the key
OSSRH_USERNAME=my ossrh username
OSSRH_PASSWORD=my ossrh password
VERSION=1.0.0
GROUP_ID=com.example
ARTIFACT_ID=project-name
PROJECT_PACKAGING=...
PROJECT_DESCRIPTION=...
PROJECT_URL=...
SCM_URL=...
SCM_CONNECTION=...
LICENSE_NAME=Apache License, Version 2.0
LICENSE_URL=...
ORGANIZATION_NAME=...
ORGANIZATION_URL=...
DEVELOPER_ID=...
DEVELOPER_NAME=...
DEVELOPER_EMAIL=...
As you suspected, it’s the format of the secret PGP key that is wrong here. The useInMemoryPgpKeys method expects an “ascii-armored in-memory PGP secret key”. gpg --list-secret-keys is only meant for human consumption and doesn’t even show the ‘content’ of the secret key.
You can get the key in the correct format using gpg --armor --export-secret-keys foobar#example.com instead. Use your own key ID (as returned by gpg --list-secret-keys) or email address instead of foobar#example.com.
To make use of the exported key in the gradle.properties file, you need to escape the newline characters. For example, you could append a new, working line for your GPG_SIGNING_KEY property like so:
gpg --armor --export-secret-keys foobar#example.com \
| awk 'NR == 1 { print "GPG_SIGNING_KEY=" } 1' ORS='\\n' \
>> gradle.properties
(See this answer for an explanation of the main awk magic that is used here.)
With your gradle.properties file updated as described (and using your build scripts), I could successfully sign my dummy JAR files with ./gradlew signArchives.

Close and release artifact on maven central using gradle

I have this gradle script:
def configureUploadArtifacts(groupId, repoUrl, _packaging) {
def gpgKeyId = System.getenv('GPG_KEY_ID')
def gpgPassword = System.getenv('GPG_KEY_PASSWORD')
def gpgFile = System.getenv('PATH_TO_GPG_FILE')
project.group = groupId;
project.archivesBaseName = name
project.version = getVersionNameFromFile()
ext."signing.keyId" = gpgKeyId
ext."signing.password" = gpgPassword
ext."signing.secretKeyRingFile" = gpgFile
uploadArchives {
apply plugin: 'maven'
apply plugin: 'signing'
signing {
sign configurations.archives
}
def userName = System.getenv('OSSRH_USER_NAME');
def password = System.getenv('OSSRH_PASSWORD');
repositories {
mavenDeployer {
beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) }
repository(url: "https://oss.sonatype.org/service/local/staging/deploy/maven2/") {
authentication(userName: userName, password: password)
}
snapshotRepository(url: "https://oss.sonatype.org/content/repositories/snapshots/") {
authentication(userName: userName, password: password)
}
pom.project {
name "${project.name}"
packaging "${_packaging}"
// optionally artifactId can be defined here
description 'A collection of core tools I use'
url "http://github.com/${repoUrl}"
scm {
connection "scm:git:git://github.com/${repoUrl}.git"
developerConnection "scm:git:ssh://github.com/${repoUrl}.git"
url "http://github.com/${repoUrl}/tree/master"
}
licenses {
license {
name 'The Apache License, Version 2.0'
url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
}
}
developers {
developer {
id 'TacB0sS'
name 'My Name'
email 'My Email'
}
}
}
}
}
}
}
I use it on my Jenkins server and it works wonderfully.
I would like it also to close and release the artifacts...
How do I do that?
Solution was to add the following to the root build.gradle file:
ext."oss-releases.username" = System.getenv('OSSRH_USER_NAME')
ext."oss-releases.password" = System.getenv('OSSRH_PASSWORD')
ext."oss-releases.url" = "https://oss.sonatype.org/index.html#stagingRepositories"
apply plugin: 'nexus-workflow'
And run the following from the command line:
bash gradlew nexusStagingRelease
DONE!
You can use gradle-release on your script. It works similar as maven-release-plugin (removes SNAPSHOT from version, builds, create tags, deploys artifacts and updates to the next development version):
apply plugin: 'net.researchgate.release'
In Jenkins, using release plugin, you will need to configure the unattended release:
gradle release -Prelease.useAutomaticVersion=true \
-Prelease.releaseVersion=$VERSION \
-Prelease.newVersion=$NEXT_VERSION

Unable to reference gradle.properties in script plugin

I am creating a script plugin to reference the ivy repository holding my orgs gradle plugins. My code right now is:
repository.gradle
repositories {
ivy {
credentials {
username = artifactory_user
password = artifactory_password
}
url 'https://ourUrl/artifactory/repoName'
layout "pattern", {
ivy '[organization]/[module]/[revision]/ivy-[revision].xml'
artifact '[organisation]/[module]/[revision]/[artifact]-[revision].[ext]'
}
}
}
Then, in the build.gradle file,
build.gradle
buildscript {
apply from: https://ourUrl/assets/repository.gradle, to: buildscript
dependencies { classpath group: 'ourGrp', name: 'artifactName', version: '1.0.0' }
}
In my gradle.properties file:
gradle.properties
artifactory_user=username
artifactory_password=password
The error message I recieve is this:
What went wrong:
A problem occurred evaluating script.
Could not find property 'artifactory_user' on Credentials [username: null].
Any suggestions for how I can resolve this? I would like to avoid any further impact to the build.gradle file if possible.
This exact question was asked in the gradle forums. I'll paste the working workaround so it won't get lost during relinking or something:
repository.gradle:
repositories {
ivy {
credentials {
username = artifactory_user
password = artifactory_password
}
url 'https://ourUrl/artifactory/repoName'
layout "pattern", {
ivy '[organization]/[module]/[revision]/ivy-[revision].xml'
artifact '[organisation]/[module]/[revision]/[artifact]-[revision].[ext]'
}
}
}
ext.extRepo = repositories
build.gradle:
buildscript {scriptHandler->
apply from: 'https://ourUrl/assets/repository.gradle'
repositories.addAll(extRepo)

Resources