Skip to content

Commit

Permalink
feat: 1588 publish to maven central (#1596)
Browse files Browse the repository at this point in the history
Added steps to publish_assets.yml to push to Sonatype. Modified gradle config to sign artefacts and push.
  • Loading branch information
jcpitre authored Oct 20, 2023
1 parent 85beb70 commit fdd6c9b
Show file tree
Hide file tree
Showing 7 changed files with 201 additions and 41 deletions.
37 changes: 37 additions & 0 deletions .github/workflows/publish_assets.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ name: Upload Release Assets
on:
release:
types: [ prereleased, released ]
workflow_dispatch:

jobs:
upload-release-assets:
Expand All @@ -21,9 +22,11 @@ jobs:
distribution: 'zulu'

- name: Generate CLI jar
if: github.event_name == 'release'
run: ./gradlew shadowJar

- name: Upload JAR Asset
if: github.event_name == 'release'
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Expand All @@ -34,9 +37,11 @@ jobs:
asset_content_type: application/java-archive

- name: Generate rules.json
if: github.event_name == 'release'
run: ./gradlew webClientRulesJSON

- name: Upload rules.json asset
if: github.event_name == 'release'
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Expand All @@ -47,12 +52,15 @@ jobs:
asset_content_type: application/json

- name: Generate JavaDocs
if: github.event_name == 'release'
run: ./gradlew aggregateJavadoc

- name: Zip JavaDocs
if: github.event_name == 'release'
run: zip -r javadocs.zip build/docs/aggregateJavadoc

- name: Upload zipped Javadocs
if: github.event_name == 'release'
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Expand All @@ -62,3 +70,32 @@ jobs:
asset_name: javadocs.zip
asset_content_type: application/zip

# The following steps will publish artifacts to a sonatype staging repo with the aim of promoting them to maven central
# Pretty much everything is done through gradle.
# The version used will be according to the axion-release-plugin, meaning it will take a tag if present.
# The tag should follow semantic versioning, e.g. v1.2.3. There could be a suffix, e.g. v1.2.3-TEST
# gradle will build, sign then upload artifacts to a Sonatype staging repo.
# See https://s01.oss.sonatype.org for accessing these repos.
# At this point it should manually be closed, which will trigger acceptance tests for maven central (but not transfer yet)
# Once closed, the repo is available for testing.
# After testing, it can be manually promoted on the sonatype site, which will then publish to maven central.
# Note than once in maven central a release cannot be removed or altered.

- name: Load secrets from 1Password
id: onepw_secrets
uses: 1password/load-secrets-action@v1.3.1
with:
export-env: true # Export loaded secrets as environment variables
env:
OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN }} # This is required to connect to the vault in our 1Password account.
MAVEN_GPG_PRIVATE_KEY: "op://rbiv7rvkkrsdlpcrz3bmv7nmcu/yztcx47yzp4vizjyaq7ulvkgoi/Private Key"
MAVEN_GPG_PASSPHRASE: "op://rbiv7rvkkrsdlpcrz3bmv7nmcu/yztcx47yzp4vizjyaq7ulvkgoi/password"

- name: Build and Publish to Sonatype
run: |
# The gradle java verifying plugin does not work with java 17.
# Don't verify since it has already been done when the PR was created.
./gradlew publish -x verifyGoogleJavaFormat
env:
SONATYPE_USERNAME: ${{secrets.SONATYPE_USERNAME}}
SONATYPE_PASSWORD: ${{secrets.SONATYPE_PASSWORD}}
115 changes: 113 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,21 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/*
* A note about publishing and signing.
* Maven central requires that artifacts be signed. And upload is done to Sonatype.
* To publish you will need these environment variables defined:
* SONATYPE_USERNAME
* SONATYPE_PASSWORD
* MAVEN_GPG_PRIVATE_KEY
* MAVEN_GPG_PASSPHRASE
* Suggestion is to put these in a shell script with restricted read permissions, then source it before calling
* ./gradlew publish.
*/
plugins {
id 'java'
id 'maven-publish'
id 'signing'
id 'test-report-aggregation'
id 'com.github.sherter.google-java-format' version '0.9'
id "io.freefair.aggregate-javadoc" version "6.4.3"
Expand All @@ -24,7 +36,7 @@ plugins {

// Setup and configure properties that are consistent across all projects, including sub-modules.
allprojects {
group 'org.mobilitydata'
group 'org.mobilitydata.gtfs-validator'

// Per the axion-release plugin, this computes the project version based
// on the most recent tag in the repo.
Expand Down Expand Up @@ -66,6 +78,105 @@ allprojects {
}
}

subprojects {
apply plugin: 'java'

// Cannot publish a SNAPSHOT. The provided sonatype url will not accept it.
tasks.withType(PublishToMavenRepository).all { task ->
task.onlyIf {
if (project.version.toString().contains('SNAPSHOT')) {
throw new GradleException("Publishing is not allowed for SNAPSHOT versions. Currently " + project.version)
}
true
}
}

task javadocJar(type: Jar) {
archiveClassifier.set('javadoc')
from javadoc
}

task sourcesJar(type: Jar) {
archiveClassifier.set('sources')
from sourceSets.main.allSource
}

// These modules require the same publishing configuration, apart from the name of the module
// Also we want to limit artefact publishing to these modules.
if (project.name == 'main' ||
project.name == 'core' ||
project.name == 'model') {
def fullProjectName = 'gtfs-validator-' + project.name

afterEvaluate {
publishing {
repositories {
// This is the sonatype staging repo for maven.
// Once uploaded, the repo needs to be manually closed, which will trigger acceptance tests for
// maven central (but not transfer yet).
// Once successfully closed, the repo is available for testing.
// After testing, it can be manually promoted on the sonatype site, which will then publish to maven central.
maven {
url = 'https://s01.oss.sonatype.org/service/local/staging/deploy/maven2'
credentials {
username System.getenv("SONATYPE_USERNAME")
password System.getenv("SONATYPE_PASSWORD")
}
}
}

publications {
mavenJava(MavenPublication) {
from components.java
artifactId = fullProjectName

artifact sourcesJar
artifact javadocJar

// Definition of the pom that will be included with the uploaded artifacts.
pom {
name = fullProjectName
description = 'The ' + project.name + " artifacts from the gtfs validator"
url = 'https://github.com/MobilityData/gtfs-validator'
licenses {
license {
name = 'The Apache License, Version 2.0'
url = 'https://github.com/MobilityData/gtfs-validator/blob/master/LICENSE'
}
}
developers {
developer {
id = 'dev'
name = 'Dev group'
email = 'it@mobilitydata.org'
}
}
scm {
connection = 'scm:git:git://github.com/MobilityData/gtfs-validator.git'
developerConnection = 'scm:git:ssh://github.com/MobilityData/gtfs-validator.git'
url = 'https://github.com/MobilityData/gtfs-validator'
}
}
}
}
}
signing {
useInMemoryPgpKeys(System.getenv('MAVEN_GPG_PRIVATE_KEY'), System.getenv('MAVEN_GPG_PASSPHRASE'))
sign publishing.publications.mavenJava
}
}

}
compileJava {
options.compilerArgs << '-parameters'
}

compileTestJava {
options.compilerArgs << '-parameters'
}

}

reporting {
reports {
// Necessary for unit test result aggregation.
Expand Down
23 changes: 5 additions & 18 deletions core/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,13 @@
plugins {
id 'java'
id 'maven-publish'
id 'signing'
}

//publishing {
// publishing and signing are done in gtfs-validator build.gradle to minimize repetition
//}

dependencies {
implementation project(':model')
annotationProcessor project(':processor:notices')
Expand Down Expand Up @@ -50,21 +55,3 @@ jar {
'Implementation-Version': project.version)
}
}

publishing {
publications {
mavenJava(MavenPublication) {
artifactId = 'gtfs-validator-core'

from components.java
}
}
}

compileJava {
options.compilerArgs << '-parameters'
}

compileTestJava {
options.compilerArgs << '-parameters'
}
35 changes: 33 additions & 2 deletions docs/RELEASE.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,43 @@ is:pr is:closed merged:>2020-07-28 base:master sort:updated-desc

💡 For more details on versioning, see [Understanding Maven Version Numbers](https://docs.oracle.com/middleware/1212/core/MAVEN/maven_version.htm#MAVEN8855).

### 3. Remove all `sha` Docker images added since last release
### 4. Remove all `sha` Docker images added since last release
1. Find the [list of Docker images for this project.](https://github.com/orgs/MobilityData/packages/container/gtfs-validator/versions)
1. Delete all `sha`tagged Docker images added since last release.
![grhc preview](https://user-images.githubusercontent.com/35747326/100006687-e1b5d080-2d98-11eb-846d-af12fbd7ca9f.png)
**⚠️ Note: this manipulation can only be done by someone whose GitHub account has `Admin` access rights over the `gtfs-validator` package.**

### 3. Update the release number in the wiki
### 5. Update the release number in the wiki
By updating the version number in the project's wiki, users of the app will be advised to upgrade if their local version does not match.
Update [this page](https://github.com/MobilityData/gtfs-validator/wiki/Current-Version) with the new version.

### 6. Publishing to Maven Central
* Maven central is a repository used by developers to download libraries that can be used in their own development.
* We upload some jars (currently gtfs-validator-main, gtfs-validator-core and gtfs-validator-model) there to make them available.
Uploaded artefacts have versions.
* Publication to Maven Central requires some manual operations.

* Typically when doing a release the publish_assets.yml Github action is automatically run.
This will upload some assets
to be available on the release page itself (see for example [Release 4.1.0 assets](https://github.com/MobilityData/gtfs-validator/releases/tag/v4.1.0#:~:text=7%20other%20contributors-,Assets,-6))


* This Github action also publishes to Sonatype. This is used as a staging area before making the arftefacts available via Maven Central.
* See [Sonatype Staging Repositories](https://s01.oss.sonatype.org/#stagingRepositories) (login required)
* There should be a repository in the list with name orgmobilitydata-####. This is automatically created by Sonatype when files are uploaded.

![image](https://github.com/MobilityData/gtfs-validator/assets/106176106/f08a24ec-addb-4d63-840d-24297c505822)


* You can browse the repo content to make sure everything is there. In particular there should be the jars for the code, jars for javadoc, for sources, and files for the maven pom.
* Everything should be signed, as evidenced by the presence of files with extension .sha1, .sha256, .sha512 etc.
* Also make sure the version is correct.
* You then need to manually close the repo. Doing this will trigger acceptance tests for Maven Central.

![image](https://github.com/MobilityData/gtfs-validator/assets/106176106/1d8916c6-a640-43cf-9658-82193d127b1d)

* Once the repository is closed it becomes available for inclusion in projects for testing. The URL to use as repository in your gradle or maven configuration files can be found in the summary for the repo.
![image](https://github.com/MobilityData/gtfs-validator/assets/106176106/c809c1ca-67d7-4c45-bfa5-47441e163d2f)

* Once satisfied with the testing, the repo can be released to Maven Central.
* Note that once a release is deployed on Maven Central, it cannot be removed or modified. If problems are detected after this stage, a new release with a different version has to be created.
13 changes: 4 additions & 9 deletions main/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,12 @@
plugins {
id 'java'
id 'maven-publish'
id 'signing'
}

publishing {
publications {
mavenJava(MavenPublication) {
artifactId = 'gtfs-validator-main'

from components.java
}
}
}
//publishing {
// publishing and signing are done in gtfs-validator build.gradle to minimize repetition
//}

dependencies {
annotationProcessor project(':processor:notices')
Expand Down
15 changes: 7 additions & 8 deletions model/build.gradle
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
plugins {
id 'java'
id 'maven-publish'
id 'signing'
}

//publishing {
// publishing and signing are done in gtfs-validator build.gradle to minimize repetition
//}


dependencies {
annotationProcessor 'com.google.auto.value:auto-value:1.7.4'
compileOnly 'com.google.auto.value:auto-value-annotations:1.7.4'
implementation 'org.jetbrains:annotations:20.1.0'
implementation 'com.google.code.findbugs:jsr305:3.0.2'
}

compileJava {
options.compilerArgs << '-parameters'
}

compileTestJava {
options.compilerArgs << '-parameters'
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
package org.mobilitydata.gtfsvalidator.annotation;

/**
* Generates a {@link org.mobilitydata.gtfsvalidator.notice.InvalidCurrencyAmountNotice} for a
* currency amount value that does not match the specification of its currency code.
* Generates a InvalidCurrencyAmountNotice for a currency amount value that does not match the
* specification of its currency code.
*
* <p>Example.
*
Expand Down

0 comments on commit fdd6c9b

Please sign in to comment.