Hi guys, I am new with java development. I have finished my library and I have used gradle in order to build and publish it.
I want to publish to sonatype which as I understand will make it public.
In order to achieve that I have generated a gpg key, exported it with --armor and pasted the contents to github secrets.
My issue is when I try to read it back from github repo secrest it fails.
Is there a workaround for this?
Thanks
hey @jkvargas , take a look at plantuml workflow file which reads it back and uses it:
signing {
useGpgCmd()
sign(publishing.publications["maven"])
}
and in the workflow file:
- name: Setup gpg
if: env.ARTIFACT_SIGNING_KEY
id: gpg
env:
ARTIFACT_SIGNING_KEY: ${{ secrets.ARTIFACT_SIGNING_KEY }}
run: |
echo "Importing key ..."
echo "${ARTIFACT_SIGNING_KEY}" | gpg --batch --import --import-options import-show
echo "Getting key id ..."
key_id="$(echo "${ARTIFACT_SIGNING_KEY}" | gpg --batch --show-keys --with-colons | awk -F: '$1 == "sec" { print $5 }')"
echo "::set-output name=key_id::${key_id}"
- name: Sign artifacts
if: env.GPG_KEYNAME
env:
GPG_KEYNAME: ${{ steps.gpg.outputs.key_id }}
GPG_PASSPHRASE: ${{ secrets.ARTIFACT_SIGNING_PASSPHRASE }}
run: |
gradle sign \
"-Psigning.gnupg.keyName=${GPG_KEYNAME}" \
"-Psigning.gnupg.passphrase=${GPG_PASSPHRASE}"
I will try it out, @soloturn.
By the way, did you just ctrl+c, ctrl+v the contents of your key into the github secrets site?
i guess i did the same as you, export it:
Why that complex with importing and exporting and extracting and so on?
Gradle has much better support for the GitHub Actions use-case.
That’s exactly what signing { useInMemoryPgpKeys(...) }
is for.
You can directly provide the ascii-armored secret key to Gradle with that.
i guess one has to decide for local complication or github complication in this case. i saw now that putting the key into the local.properties file would be the way to make it work on both. so you mean doing something like ths?
gpg --export-secret-keys --armor AABBCCDD > AABBCCDD.asc
signingKey=-----BEGIN PGP PRIVATE KEY BLOCK-----\n\nescaped key\n-----END PGP PRIVATE KEY BLOCK-----\n
signingPassphrase=pass
ossrhUsername=user
ossrhPassword=pass
signing {
if (hasProperty("signingPassphrase")) {
val signingKey: String? by project
val signingPassphrase: String? by project
useInMemoryPgpKeys(signingKey, signingPassphrase)
sign(publishing.publications)
}
}
publish:
name: Publish Artifacts
needs: [build]
if: github.event_name != 'pull_request' && github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up JDK 8
uses: actions/setup-java@v2
with:
java-version: '8'
distribution: 'temurin'
- name: Publish with Gradle
env:
ORG_GRADLE_PROJECT_sonatypePassword: ${{ secrets.SONATYPE_PASSWORD }}
ORG_GRADLE_PROJECT_sonatypeUsername: ${{ secrets.SONATYPE_USERNAME }}
ORG_GRADLE_PROJECT_signingKey: ${{ secrets.PGP_SECRET }}
ORG_GRADLE_PROJECT_signingPassphrase: ${{ secrets.PGP_PASSPHRASE }}
run: ./gradlew publishToSonatype
What do you mean with that?
If you want to publish signed both, from local and CI, you can also do logic like “if property is set, use in memory, if not use gpg command”. Or “if GitHub, use in memory, if not use gpg command”. Or similar logic.
Great progess,
plugins {
id 'java-library'
id 'jvm-test-suite'
id 'maven-publish'
id 'signing'
}
group 'com.evervault'
version '1.0-SNAPSHOT'
repositories {
mavenCentral()
}
def getRepositoryUsername() {
return hasProperty("ossrhUsername") ? ossrhUsername : ""
}
def getRepositoryPassword() {
return hasProperty("ossrhPassword") ? ossrhPassword : ""
}
def getKeyFile() {
return hasProperty("signingKey") ? signingKey : ""
}
def getKeyPassword() {
return hasProperty("signingPassword") ? signingPassword : ""
}
dependencies {
testImplementation 'org.junit.jupiter:junit-jupiter:5.7.2'
testImplementation "com.github.tomakehurst:wiremock-jre8:2.32.0"
testImplementation "org.mockito:mockito-core:3.+"
implementation 'com.google.code.gson:gson:2.8.9'
implementation group: 'org.bouncycastle', name: 'bcprov-jdk15on', version: '1.70'
}
java {
withJavadocJar()
withSourcesJar()
}
testing {
suites {
test {
useJUnitJupiter()
}
integrationTests(JvmTestSuite) {
dependencies {
implementation project
implementation group: 'org.bouncycastle', name: 'bcprov-jdk15on', version: '1.70'
}
}
}
}
publishing {
publications {
mavenJava(MavenPublication) {
from components.java
artifact sourcesJar
artifact javadocJar
pom {
name = 'mycompany'
description = 'mycompany SDK enabling developers to integrate their applications with mycompany services'
url = 'https://github.com/mycompany/mycompany
scm {
url = 'https://github.com/mycompany/mycompany'
connection = 'scm:git:ssh://git@github.mycompany/mycompany.git'
}
licenses {
license {
name = 'The MIT License (MIT)'
url = 'https://mit-license.org/'
}
}
developers {
developer {
name = 'mycompany'
organization = 'mycompany'
email = 'mycompany@mycompany.com'
}
}
organization {
name = 'mycompany'
url = 'https://www.mycompany.com/'
}
}
}
}
repositories {
maven {
name = 'sonatype'
def releasesRepoUrl = 'https://oss.sonatype.org/service/local/staging/deploy/maven2'
def snapshotsRepoUrl = 'https://oss.sonatype.org/content/repositories/snapshots'
url = version.endsWith('SNAPSHOT') ? snapshotsRepoUrl : releasesRepoUrl
credentials {
username getRepositoryUsername()
password getRepositoryPassword()
}
}
}
}
signing {
useInMemoryPgpKeys(getKeyFile(), getKeyPassword())
sign publishing.publications.mavenJava
}
javadoc {
if(JavaVersion.current().isJava9Compatible()) {
options.addBooleanOption('html5', true)
}
}
Error: -13T15:20:29.068+0000 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter] > Invalid publication ‘mavenJava’: multiple artifacts with the identical extension and classifier (‘jar’, ‘sources’).
I suppose my artifacts are not correct.
Exactly.
withJavadocJar()
and withSourcesJar()
already add those jars to the java
component.
And then you add them a second time to the publication manually.
Just remove the manual addition.