diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 0000000..ceccfb4 --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,63 @@ +name: Publish + +on: + workflow_dispatch: {} + push: + tags: + - v[0-9]+.[0-9]+.[0-9]+* + +permissions: {} + +jobs: + build: + name: Build & Test + runs-on: ubuntu-latest + permissions: + contents: read + strategy: + matrix: + java: ['11', '17', '21'] + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-java@v4 + with: + java-version: ${{ matrix.java }} + distribution: 'temurin' + cache: gradle + - run: ./gradlew test + + publish: + name: Publish to Maven Central + if: startsWith(github.ref, 'refs/tags/v') + needs: [build] + runs-on: ubuntu-latest + permissions: + contents: read + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-java@v4 + with: + java-version: '11' + distribution: 'temurin' + cache: gradle + + - name: Configure GPG Key + run: | + set -ex + echo $GPG_SIGNING_PRIVKEY | base64 --decode | gpg --import --batch --yes --pinentry-mode loopback --passphrase "$GPG_SIGNING_PASSPHRASE" + env: + GPG_SIGNING_PRIVKEY: ${{ secrets.GPG_SIGNING_PRIVKEY }} + GPG_SIGNING_PASSPHRASE: ${{ secrets.GPG_SIGNING_PASSPHRASE }} + + - name: Publish package + run: | + ./gradlew publishToSonatype closeAndReleaseSonatypeStagingRepository \ + -Dorg.gradle.project.NEXUS_USERNAME=$NEXUS_USERNAME \ + -Dorg.gradle.project.NEXUS_PASSWORD=$NEXUS_PASSWORD \ + -Dorg.gradle.project.signing.gnupg.keyName=$GPG_SIGNING_KEYID \ + -Dorg.gradle.project.signing.gnupg.passphrase=$GPG_SIGNING_PASSPHRASE + env: + NEXUS_USERNAME: ${{ secrets.NEXUS_USERNAME }} + NEXUS_PASSWORD: ${{ secrets.NEXUS_PASSWORD }} + GPG_SIGNING_KEYID: ${{ secrets.GPG_SIGNING_KEYID }} + GPG_SIGNING_PASSPHRASE: ${{ secrets.GPG_SIGNING_PASSPHRASE }} diff --git a/README.md b/README.md index 3eb63a0..4c61a15 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,24 @@ Java SDK for the [**Machine Payments Protocol**](https://mpp.dev) [![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE) +## Installation + +### Gradle + +```groovy +implementation 'com.stripe:mpp-java:0.1.0' +``` + +### Maven + +```xml + + com.stripe + mpp-java + 0.1.0 + +``` + ## Usage ### Testnet diff --git a/build.gradle b/build.gradle index 4cddc3c..d621aa9 100644 --- a/build.gradle +++ b/build.gradle @@ -1,10 +1,12 @@ plugins { id 'java-library' id 'maven-publish' + id 'signing' + id 'io.github.gradle-nexus.publish-plugin' version '1.1.0' } -group = 'com.stripe' -version = '0.1.0' +group = GROUP +version = VERSION_NAME java { sourceCompatibility = JavaVersion.VERSION_11 @@ -60,35 +62,14 @@ tasks.register('integrationTest', Test) { shouldRunAfter test } -publishing { - publications { - mavenJava(MavenPublication) { - from components.java - artifactId = 'mpp-java' - - pom { - name = 'MPP Java SDK' - description = 'Java SDK for the Machine Payments Protocol (MPP)' - url = 'https://github.com/stripe/mpp-java' - - licenses { - license { - name = 'MIT License' - url = 'https://opensource.org/licenses/MIT' - } - } - } - } - } - - repositories { - maven { - name = 'GitHubPackages' - url = uri('https://maven.pkg.github.com/stripe/mpp-java') - credentials { - username = project.findProperty('gpr.user') ?: System.getenv('GITHUB_ACTOR') - password = project.findProperty('gpr.key') ?: System.getenv('GITHUB_TOKEN') - } - } +jar { + manifest { + attributes( + "Implementation-Title": POM_NAME, + "Implementation-Version": VERSION_NAME, + "Implementation-Vendor": "Stripe, Inc." + ) } } + +apply from: "deploy.gradle" diff --git a/deploy.gradle b/deploy.gradle new file mode 100644 index 0000000..2f23ea5 --- /dev/null +++ b/deploy.gradle @@ -0,0 +1,106 @@ +apply plugin: "maven-publish" +apply plugin: "signing" + +def isReleaseBuild() { + return VERSION_NAME.contains("SNAPSHOT") == false +} + +def getReleaseRepositoryUrl() { + return hasProperty("RELEASE_REPOSITORY_URL") ? RELEASE_REPOSITORY_URL + : "https://ossrh-staging-api.central.sonatype.com/service/local/staging/deploy/maven2/" +} + +def getSnapshotRepositoryUrl() { + return hasProperty("SNAPSHOT_REPOSITORY_URL") ? SNAPSHOT_REPOSITORY_URL + : "https://central.sonatype.com/repository/maven-snapshots/" +} + +def getRepositoryUsername() { + return hasProperty("NEXUS_USERNAME") ? NEXUS_USERNAME : "" +} + +def getRepositoryPassword() { + return hasProperty("NEXUS_PASSWORD") ? NEXUS_PASSWORD : "" +} + +nexusPublishing { + packageGroup = GROUP + + repositories { + sonatype { + nexusUrl = uri("https://ossrh-staging-api.central.sonatype.com/service/local/") + username = getRepositoryUsername() + password = getRepositoryPassword() + } + } + + transitionCheckOptions { + maxRetries.set(40) + delayBetween.set(java.time.Duration.ofMillis(4000)) + } +} + +afterEvaluate { project -> + tasks.withType(Sign) { + onlyIf { isReleaseBuild() && project.hasProperty("signing.gnupg.keyName") } + } + + signing { + required { isReleaseBuild() && gradle.taskGraph.hasTask("publish") } + useGpgCmd() + sign publishing.publications + } + + publishing { + publications { + mavenJava(MavenPublication) { + groupId = GROUP + artifactId = POM_ARTIFACT_ID + version = VERSION_NAME + from components.java + + pom { + name = POM_NAME + description = POM_DESCRIPTION + url = POM_URL + packaging = POM_PACKAGING + licenses { + license { + name = POM_LICENCE_NAME + url = POM_LICENCE_URL + distribution = POM_LICENCE_DIST + } + } + developers { + developer { + id = POM_DEVELOPER_ID + name = POM_DEVELOPER_NAME + email = POM_DEVELOPER_EMAIL + } + } + organization { + name = POM_DEVELOPER_NAME + url = POM_ORGANIZATION_URL + } + scm { + connection = POM_SCM_CONNECTION + developerConnection = POM_SCM_DEV_CONNECTION + url = POM_SCM_URL + } + } + } + } + repositories { + maven { + name = "nexus" + def releasesRepoUrl = getReleaseRepositoryUrl() + def snapshotsRepoUrl = getSnapshotRepositoryUrl() + url = isReleaseBuild() ? releasesRepoUrl : snapshotsRepoUrl + credentials { + username = getRepositoryUsername() + password = getRepositoryPassword() + } + } + } + } +} diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 0000000..e84e726 --- /dev/null +++ b/gradle.properties @@ -0,0 +1,19 @@ +GROUP=com.stripe +VERSION_NAME=0.1.0 + +POM_URL=https://github.com/stripe/mpp-java +POM_SCM_URL=git@github.com:stripe/mpp-java.git +POM_SCM_CONNECTION=scm:git:git@github.com:stripe/mpp-java.git +POM_SCM_DEV_CONNECTION=scm:git:git@github.com:stripe/mpp-java.git +POM_LICENCE_NAME=The MIT License +POM_LICENCE_URL=https://opensource.org/licenses/MIT +POM_LICENCE_DIST=repo +POM_DEVELOPER_ID=stripe +POM_DEVELOPER_NAME=Stripe +POM_DEVELOPER_EMAIL=support+mpp@stripe.com + +POM_DESCRIPTION=Java SDK for the Machine Payments Protocol (MPP) +POM_NAME=mpp-java +POM_ARTIFACT_ID=mpp-java +POM_PACKAGING=jar +POM_ORGANIZATION_URL=https://stripe.com diff --git a/jitpack.yml b/jitpack.yml deleted file mode 100644 index adb3fe1..0000000 --- a/jitpack.yml +++ /dev/null @@ -1,2 +0,0 @@ -jdk: - - openjdk11