Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 8 additions & 6 deletions .github/workflows/javadoc.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,18 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v3.11.0
with:
java-version: '8'
fetch-depth: 0 # Required for git-version plugin
- uses: actions/setup-java@v4
with:
java-version: '11'
distribution: 'corretto'
- name: Validate Gradle wrapper
uses: gradle/wrapper-validation-action@v1
uses: gradle/wrapper-validation-action@v2
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v3
- name: Generate Javadoc
uses: gradle/gradle-build-action@v2
with:
arguments: javadoc
run: ./gradlew javadoc
- name: Check Javadoc generation
run: |
if [ -d "build/docs/javadoc" ]; then
Expand Down
40 changes: 22 additions & 18 deletions .github/workflows/publish.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Publish package to GitHub Packages
name: Publish package to GitHub Packages and Maven Central
on:
release:
types: [ created ]
Expand All @@ -11,17 +11,19 @@ jobs:
contents: read
packages: write
steps:
- uses: actions/checkout@v2
- uses: actions/setup-java@v3.11.0
- uses: actions/checkout@v4
with:
java-version: '8'
fetch-depth: 0 # Required for git-version plugin
- uses: actions/setup-java@v4
with:
java-version: '11'
distribution: 'corretto'
- name: Validate Gradle wrapper
uses: gradle/wrapper-validation-action@v1
uses: gradle/wrapper-validation-action@v2
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v3
- name: Verify Javadoc generation
uses: gradle/gradle-build-action@v2
with:
arguments: javadoc
run: ./gradlew javadoc
- name: Check Javadoc generation
run: |
if [ -d "build/docs/javadoc" ]; then
Expand All @@ -30,15 +32,17 @@ jobs:
echo "ERROR: Javadoc directory not found"
exit 1
fi
- name: Publish package
uses: gradle/gradle-build-action@v2
with:
arguments: publish publishToSonatype closeAndReleaseSonatypeStagingRepository
- name: Publish to GitHub Packages
run: ./gradlew publish
env:
GITHUB_ACTOR: ${{ github.actor }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
OSSRH_USERNAME: ${{ secrets.OSSRH_USERNAME }}
OSSRH_PASSWORD: ${{ secrets.OSSRH_PASSWORD }}
GPG_SIGNING_KEY: ${{ secrets.GPG_SIGNING_KEY }}
GPG_SIGNING_PASSPHRASE: ${{ secrets.GPG_SIGNING_PASSPHRASE }}
NEXUS_TOKEN_USERNAME: ${{ secrets.NEXUS_TOKEN_USERNAME }}
NEXUS_TOKEN_PASSWORD: ${{ secrets.NEXUS_TOKEN_PASSWORD }}
- name: Publish to Maven Central
run: ./gradlew publishAndReleaseToMavenCentral
env:
# Nexus tokens were generated before we migrated to the new Maven Central,
# it's backward compatible.
ORG_GRADLE_PROJECT_mavenCentralUsername: ${{ secrets.NEXUS_TOKEN_USERNAME }}
ORG_GRADLE_PROJECT_mavenCentralPassword: ${{ secrets.NEXUS_TOKEN_PASSWORD }}
ORG_GRADLE_PROJECT_signingInMemoryKey: ${{ secrets.GPG_SIGNING_KEY }}
ORG_GRADLE_PROJECT_signingInMemoryKeyPassword: ${{ secrets.GPG_SIGNING_PASSPHRASE }}
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ build
# Ignore stg schemas
stg-schemas/
bin
/key.asc
183 changes: 183 additions & 0 deletions PUBLISHING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
# Publishing Guide

This document describes how to publish the Permit.io Java SDK to Maven Central and GitHub Packages.

## Overview

The SDK is published to two repositories:

- **Maven Central** - Primary distribution for public consumption
- **GitHub Packages** - Secondary distribution for GitHub-based workflows

## Prerequisites

### Maven Central Portal Account

1. Create an account at [central.sonatype.com](https://central.sonatype.com)
2. Verify ownership of the `io.permit` namespace
3. Generate a User Token: Account → Generate User Token

### GPG Signing Key

Maven Central requires all artifacts to be signed with GPG.
[For more info see here.](https://central.sonatype.org/publish/requirements/gpg/)

#### Generate a new key (if you don't have one)

```bash
gpg --full-generate-key
```

When prompted:

1. **Key type**: Select `1` (RSA and RSA)
2. **Key size**: Enter `4096`
3. **Expiration**: Enter `0` (doesn't expire) or set a reasonable expiration
4. **Name and email**: Use the same email as your Maven Central account
5. **Passphrase**: Set a strong passphrase (this is your `signingInMemoryKeyPassword`)

#### List your keys

```bash
gpg --list-secret-keys --keyid-format LONG
```

#### Export the private key

For local use:

```bash
gpg --armor --export-secret-keys YOUR_KEY_ID > key.asc
```

For CI/CD (base64 encoded):

```bash
gpg --armor --export-secret-keys YOUR_KEY_ID | base64
```

#### Publish your public key (required for Maven Central verification)

```bash
gpg --keyserver keyserver.ubuntu.com --send-keys YOUR_KEY_ID
# Note: if you get a "no route to host" error, try an alternative keyserver such as keys.openpgp.org or pgp.mit.edu.
```

## GitHub Secrets

Configure these secrets in your GitHub repository:

| Secret | Description |
|--------------------------|--------------------------------------------------------|
| `MAVEN_CENTRAL_USERNAME` | Username from Central Portal TOKEN (not the user) |
| `MAVEN_CENTRAL_PASSWORD` | Password from Central Portal TOKEN (not user password) |
| `GPG_SIGNING_KEY` | Base64-encoded GPG private key |
| `GPG_SIGNING_PASSPHRASE` | Passphrase for the GPG key |

## Publishing Methods

### Automatic (CI/CD)

Publishing is triggered automatically when:

- A GitHub Release is created
- The workflow is manually dispatched

The workflow (`.github/workflows/publish.yaml`) handles:

1. Javadoc verification
2. Publishing to GitHub Packages
3. Publishing to Maven Central

### Manual (Local)

#### Publish to Local Maven Repository

Test artifact generation without uploading:

```bash
./gradlew publishToMavenLocal -PskipSigning
```

Artifacts are published to `~/.m2/repository/io/permit/permit-sdk-java/`

Note: Use `-PskipSigning` for local testing without GPG keys. This flag is not available for Maven Central publishing (signing is required).

#### Publish to Maven Central (Staging Only)

Upload to Central Portal without releasing:

```bash
./gradlew publishToMavenCentral \
-PmavenCentralUsername=TOKEN_USERNAME \
-PmavenCentralPassword=TOKEN_PASSWORD \
-PsigningInMemoryKey="$(cat key.asc)" \
-PsigningInMemoryKeyPassword=KEY_PASSPHRASE
```

Review at [Central Portal Deployments](https://central.sonatype.com/publishing/deployments)

#### Publish and Release to Maven Central

Full publish with automatic release:

```bash
./gradlew publishAndReleaseToMavenCentral \
-PmavenCentralUsername=TOKEN_USERNAME \
-PmavenCentralPassword=TOKEN_PASSWORD \
-PsigningInMemoryKey="$(cat key.asc)" \
-PsigningInMemoryKeyPassword=KEY_PASSPHRASE
```

#### Publish to GitHub Packages

```bash
GITHUB_ACTOR=username GITHUB_TOKEN=token ./gradlew publish
```

## Gradle Tasks

| Task | Description |
|-----------------------------------|----------------------------------------------------------|
| `publishToMavenLocal` | Publish to local Maven cache (~/.m2) |
| `publishToMavenCentral` | Upload to Central Portal (staging) |
| `publishAndReleaseToMavenCentral` | Upload and release to Maven Central |
| `publish` | Publish to all configured repositories (GitHub Packages) |

## Versioning

Version is automatically determined by the `com.palantir.git-version` plugin based on git tags:

- Tagged commit: `2.2.0`
- Commits after tag: `2.2.0-1-gabcdef`
- Dirty working directory: `2.2.0-1-gabcdef.dirty`

To release a new version:

```bash
git tag 2.3.0
git push origin 2.3.0
```

## Troubleshooting

### 403 Forbidden

- Credentials may be invalid or expired
- Regenerate token at Central Portal

### Signature Verification Failed

- GPG key may be malformed
- Ensure key is base64 encoded without line breaks

### Version Already Exists

- Maven Central doesn't allow overwriting versions
- Bump the version and try again

## References

- [Maven Central Portal](https://central.sonatype.com)
- [vanniktech/gradle-maven-publish-plugin](https://vanniktech.github.io/gradle-maven-publish-plugin/central/)
- [Sonatype Publishing Guide](https://central.sonatype.org/publish/publish-portal-gradle/)
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ For [Maven](https://maven.apache.org/) projects, use:
<dependency>
<groupId>io.permit</groupId>
<artifactId>permit-sdk-java</artifactId>
<version>2.0.0</version>
<version>2.2.2</version>
</dependency>
```

Expand All @@ -25,7 +25,7 @@ For [Gradle](https://gradle.org/) projects, configure `permit-sdk-java` as a dep
dependencies {
// ...

implementation 'io.permit:permit-sdk-java:2.0.0'
implementation 'io.permit:permit-sdk-java:2.2.2'
}
```

Expand Down Expand Up @@ -149,6 +149,6 @@ CreateOrUpdateResult<UserRead> result = permit.api.users.sync(new UserCreate("[U

## Javadoc reference

To view the javadoc reference, [click here](https://javadoc.io/doc/io.permit/permit-sdk-java/2.0.0/index.html).
To view the javadoc reference, [click here](https://javadoc.io/doc/io.permit/permit-sdk-java/latest/index.html).

It's easiest to start with the root [Permit](https://javadoc.io/static/io.permit/permit-sdk-java/2.0.0/io/permit/sdk/Permit.html) class.
It's easiest to start with the root [Permit](https://javadoc.io/doc/io.permit/permit-sdk-java/latest/io/permit/sdk/Permit.html) class.
Loading
Loading