|
| 1 | +# Publishing Guide |
| 2 | + |
| 3 | +This document describes how to publish the Permit.io Java SDK to Maven Central and GitHub Packages. |
| 4 | + |
| 5 | +## Overview |
| 6 | + |
| 7 | +The SDK is published to two repositories: |
| 8 | +- **Maven Central** - Primary distribution for public consumption |
| 9 | +- **GitHub Packages** - Secondary distribution for GitHub-based workflows |
| 10 | + |
| 11 | +## Prerequisites |
| 12 | + |
| 13 | +### Maven Central Portal Account |
| 14 | +1. Create an account at [central.sonatype.com](https://central.sonatype.com) |
| 15 | +2. Verify ownership of the `io.permit` namespace |
| 16 | +3. Generate a User Token: Account → Generate User Token |
| 17 | + |
| 18 | +### GPG Signing Key |
| 19 | +Maven Central requires all artifacts to be signed with GPG: |
| 20 | +```bash |
| 21 | +# Generate a key (if you don't have one) |
| 22 | +gpg --full-generate-key |
| 23 | + |
| 24 | +# Export the private key (base64 encoded for CI) |
| 25 | +gpg --armor --export-secret-keys YOUR_KEY_ID | base64 |
| 26 | +``` |
| 27 | + |
| 28 | +## GitHub Secrets |
| 29 | + |
| 30 | +Configure these secrets in your GitHub repository: |
| 31 | + |
| 32 | +| Secret | Description | |
| 33 | +|--------|-------------| |
| 34 | +| `MAVEN_CENTRAL_USERNAME` | Username from Central Portal token | |
| 35 | +| `MAVEN_CENTRAL_PASSWORD` | Password from Central Portal token | |
| 36 | +| `GPG_SIGNING_KEY` | Base64-encoded GPG private key | |
| 37 | +| `GPG_SIGNING_PASSPHRASE` | Passphrase for the GPG key | |
| 38 | + |
| 39 | +## Publishing Methods |
| 40 | + |
| 41 | +### Automatic (CI/CD) |
| 42 | + |
| 43 | +Publishing is triggered automatically when: |
| 44 | +- A GitHub Release is created |
| 45 | +- The workflow is manually dispatched |
| 46 | + |
| 47 | +The workflow (`.github/workflows/publish.yaml`) handles: |
| 48 | +1. Javadoc verification |
| 49 | +2. Publishing to GitHub Packages |
| 50 | +3. Publishing to Maven Central |
| 51 | + |
| 52 | +### Manual (Local) |
| 53 | + |
| 54 | +#### Publish to Local Maven Repository |
| 55 | +Test artifact generation without uploading: |
| 56 | +```bash |
| 57 | +./gradlew publishToMavenLocal |
| 58 | +``` |
| 59 | +Artifacts are published to `~/.m2/repository/io/permit/permit-sdk-java/` |
| 60 | + |
| 61 | +#### Publish to Maven Central (Staging Only) |
| 62 | +Upload to Central Portal without releasing: |
| 63 | +```bash |
| 64 | +./gradlew publishToMavenCentral \ |
| 65 | + -PmavenCentralUsername=USERNAME \ |
| 66 | + -PmavenCentralPassword=PASSWORD \ |
| 67 | + -PsigningInMemoryKey="$(cat key.asc)" \ |
| 68 | + -PsigningInMemoryKeyPassword=PASSPHRASE |
| 69 | +``` |
| 70 | +Review at [Central Portal Deployments](https://central.sonatype.com/publishing/deployments) |
| 71 | + |
| 72 | +#### Publish and Release to Maven Central |
| 73 | +Full publish with automatic release: |
| 74 | +```bash |
| 75 | +./gradlew publishAndReleaseToMavenCentral \ |
| 76 | + -PmavenCentralUsername=USERNAME \ |
| 77 | + -PmavenCentralPassword=PASSWORD \ |
| 78 | + -PsigningInMemoryKey="$(cat key.asc)" \ |
| 79 | + -PsigningInMemoryKeyPassword=PASSPHRASE |
| 80 | +``` |
| 81 | + |
| 82 | +#### Publish to GitHub Packages |
| 83 | +```bash |
| 84 | +GITHUB_ACTOR=username GITHUB_TOKEN=token ./gradlew publish |
| 85 | +``` |
| 86 | + |
| 87 | +## Publishing Types |
| 88 | + |
| 89 | +The `mavenPublishing` block in `build.gradle` supports different publishing modes: |
| 90 | + |
| 91 | +### CENTRAL_PORTAL (Current) |
| 92 | +```groovy |
| 93 | +publishToMavenCentral(SonatypeHost.CENTRAL_PORTAL) |
| 94 | +``` |
| 95 | +Uses the new Maven Central Portal API at `central.sonatype.com`. This is the current recommended method as Sonatype has deprecated the legacy OSSRH system. |
| 96 | + |
| 97 | +### S01 (Legacy OSSRH) |
| 98 | +```groovy |
| 99 | +publishToMavenCentral(SonatypeHost.S01) |
| 100 | +``` |
| 101 | +Uses the legacy Sonatype OSSRH at `s01.oss.sonatype.org`. This method is deprecated and may stop working. |
| 102 | + |
| 103 | +### DEFAULT (Legacy OSSRH) |
| 104 | +```groovy |
| 105 | +publishToMavenCentral(SonatypeHost.DEFAULT) |
| 106 | +``` |
| 107 | +Uses the original Sonatype OSSRH at `oss.sonatype.org`. This is for older projects and is deprecated. |
| 108 | + |
| 109 | +## Gradle Tasks |
| 110 | + |
| 111 | +| Task | Description | |
| 112 | +|------|-------------| |
| 113 | +| `publishToMavenLocal` | Publish to local Maven cache (~/.m2) | |
| 114 | +| `publishToMavenCentral` | Upload to Central Portal (staging) | |
| 115 | +| `publishAndReleaseToMavenCentral` | Upload and release to Maven Central | |
| 116 | +| `publish` | Publish to all configured repositories (GitHub Packages) | |
| 117 | + |
| 118 | +## Versioning |
| 119 | + |
| 120 | +Version is automatically determined by the `com.palantir.git-version` plugin based on git tags: |
| 121 | +- Tagged commit: `2.2.0` |
| 122 | +- Commits after tag: `2.2.0-1-gabcdef` |
| 123 | +- Dirty working directory: `2.2.0-1-gabcdef.dirty` |
| 124 | + |
| 125 | +To release a new version: |
| 126 | +```bash |
| 127 | +git tag 2.3.0 |
| 128 | +git push origin 2.3.0 |
| 129 | +``` |
| 130 | + |
| 131 | +## Troubleshooting |
| 132 | + |
| 133 | +### 403 Forbidden |
| 134 | +- Credentials may be invalid or expired |
| 135 | +- Regenerate token at Central Portal |
| 136 | + |
| 137 | +### Signature Verification Failed |
| 138 | +- GPG key may be malformed |
| 139 | +- Ensure key is base64 encoded without line breaks |
| 140 | + |
| 141 | +### Version Already Exists |
| 142 | +- Maven Central doesn't allow overwriting versions |
| 143 | +- Bump the version and try again |
| 144 | + |
| 145 | +## References |
| 146 | + |
| 147 | +- [Maven Central Portal](https://central.sonatype.com) |
| 148 | +- [vanniktech/gradle-maven-publish-plugin](https://vanniktech.github.io/gradle-maven-publish-plugin/central/) |
| 149 | +- [Sonatype Publishing Guide](https://central.sonatype.org/publish/publish-portal-gradle/) |
0 commit comments