> For clean Markdown content of this page, append .md to this URL. For the complete documentation index, see https://buildwithfern.com/learn/llms.txt. # Publishing to Maven Central > Learn how to publish your Fern-generated Java SDK to Maven Central. Complete guide covering authentication, GPG signatures, and automated releases. > **Enterprise feature** > > This feature is available only for the [Enterprise plan](https://buildwithfern.com/pricing). To get started, reach out to [support@buildwithfern.com](mailto:support@buildwithfern.com). Publish your public-facing Fern Java SDK to the [Maven Central registry](https://central.sonatype.com/). After following the steps on this page, you'll have a versioned package published on Maven Central. To distribute the SDK internally instead, generate to the local file system (optionally [self-hosted](/learn/sdks/deep-dives/self-hosted)) and build a JAR with [`fern generate --package`](/learn/cli-api-reference/cli-reference/sdk-commands#package). > **Info** > > This page assumes that you have: > > * An initialized `fern` folder, a GitHub repository for your Java SDK, and a Java generator group in `generators.yml`. See [Generating an SDK (Java)](/learn/sdks/generators/java/quickstart). ## Configure Maven Central publication You'll need to update your `generators.yml` file to configure the output location, target repository, and publishing mode. Your `generators.yml` [should live in your source repository](/learn/sdks/overview/project-structure) (or on your local machine), not the repository that contains your Java SDK code. #### Configure \`output\` location In the `group` for your Java SDK, change the output location in `generators.yml` from `local-file-system` (the default) to `maven` to indicate that Fern should publish your package directly to the Maven Central registry. Then, add `publish-to: central` to indicate that the publish target is the new Maven Central Portal (Sonatype). To publish to the legacy Nexus Repository, use `publish-to: ossrh`. **`generators.yml`** ```yaml {6-9} title="generators.yml" groups: java-sdk: generators: - name: fern-java-sdk version: 4.22.0 output: location: maven config: publish-to: central ``` #### Add repository location Add the path to the GitHub repository containing your Java SDK: **`generators.yml`** ```yaml {10-11} title="generators.yml" groups: java-sdk: generators: - name: fern-java-sdk version: 4.22.0 output: location: maven config: publish-to: central github: repository: your-org/company-java ``` #### Choose your publishing mode Optionally set the mode to control how Fern handles SDK publishing: * `mode: release` (default): Fern generates code, commits to the default branch (or the `branch` you specify), and tags a release automatically * `mode: pull-request` (recommended): Fern generates code and creates a PR for you to review before release * `mode: push`: Fern generates code and pushes to a branch you specify for you to review before release You can also configure other settings, like the reviewers or license. Refer to the [full `github` (`generators.yml`) reference](/learn/sdks/reference/generators-yml#github) for more information. **`generators.yml`** ```yaml title="generators.yml" {12-13} groups: java-sdk: generators: - name: fern-java-sdk version: 4.22.0 output: location: maven config: publish-to: central github: repository: your-org/company-java mode: push branch: your-branch-name # Required for mode: push ``` ## Set up Maven Central publishing authentication #### Log into Maven Central Log into [Maven Central](https://central.sonatype.com/) or create a new account. #### Verify your namespace 1. Click on your username, then select **View Namespaces**. Click **Register New Namespace**. 2. Enter your company website or GitHub account in reverse domain name format and go through the verification process. #### Configure Maven Coordinate Add the namespace you just verified in Maven Central to the `coordinate` field. This specifies how your Java SDK will be published and referenced in the Maven Central respository. **`generators.yml`** ```yaml {8} title="generators.yml" groups: java-sdk: generators: - name: fern-java-sdk version: 4.22.0 output: location: maven coordinate: com.company:sdk-name # groupId:artifactId config: publish-to: central github: repository: your-org/company-java ``` #### Generate user tokens 1. Back in Maven Central, click on your username, then select **View Account** 2. Click on **Generate User Token**, then click **Ok** to confirm generation. This will invalidate any existing token. > **Warning** > > Save your username and password tokens – they won’t be displayed after you leave the page. #### Configure Maven Central authentication token Add `username: ${MAVEN_USERNAME}` and `password: ${MAVEN_PASSWORD}` to `generators.yml` to tell Fern to use the `MAVEN_USERNAME` and `MAVEN_PASSWORD` environment variable for authentication when publishing to the Maven Central registry. **`generators.yml`** ```yaml {9-10} title="generators.yml" groups: java-sdk: generators: - name: fern-java-sdk version: 4.22.0 output: location: maven coordinate: com.company:sdk-name username: ${MAVEN_USERNAME} password: ${MAVEN_PASSWORD} config: publish-to: central github: repository: your-org/company-java ``` ## Generate GPG Signature Next, set up code signing credentials by generating or identifying a GPG key ID, password, and secret key. Maven Central requires all artifacts to be digitally signed with PGP/GPG keys. > **Info** > > If you don't have gpg installed, you can download the binary from [https://gnupg.org/download/index.html](https://gnupg.org/download/index.html), or install it via package manager. #### Find your key If you already have a GPG key, you can list your keys: ```sh gpg --list-secret-keys --keyid-format LONG ``` If you don't have a GPG key, you can generate a new one: ```sh gpg --gen-key ``` You'll be prompted to create a new username and passphrase. #### Export your key Export your key so you can store it in an environment variable later on: ```sh gpg --export-secret-keys --armor YOUR_KEY_ID ``` Be sure to replace `YOUR_KEY_ID` with the key ID of the key you want to export. > **Info** > > More information is available on [Maven Central's GPG validation page](https://central.sonatype.org/publish/requirements/gpg/). #### Configure GPG Signature Add the `keyId`, `password`, and `secretKey` from the previous step to `generators.yml`: **`generators.yml`** ```yaml {11-14} title="generators.yml" groups: java-sdk: generators: - name: fern-java-sdk version: 4.22.0 output: location: maven coordinate: com.company:sdk-name username: ${MAVEN_USERNAME} password: ${MAVEN_PASSWORD} signature: keyId: ${MAVEN_SIGNATURE_SECRET_KEY_ID} password: ${MAVEN_SIGNATURE_PASSWORD} secretKey: ${MAVEN_SIGNATURE_SECRET_KEY} config: publish-to: central github: repository: your-org/company-java ``` #### Upload your key to public key servers Finally, upload your key to public key servers so Maven Central can access the signature: ```bash # Upload to multiple key servers gpg --keyserver keyserver.ubuntu.com --send-keys YOUR_KEY_ID gpg --keyserver keys.openpgp.org --send-keys YOUR_KEY_ID gpg --keyserver pgp.mit.edu --send-keys YOUR_KEY_ID ``` ## Publish your SDK Decide how you want to publish your SDK to Maven Central. You can use GitHub workflows for automated releases or publish directly via the CLI. #### Release via a GitHub workflow Set up a release workflow via [GitHub Actions](https://docs.github.com/en/actions/get-started/quickstart) so you can trigger new SDK releases directly from your source repository. #### Set up authentication Open your source repository in GitHub. Click on the **Settings** tab. Then, under the **Security** section, open **Secrets and variables** > **Actions**. You can also use the url `https://github.com//settings/secrets/actions`. #### Add secret for your Fern API key 1. Select **New repository secret**. 2. Name your secret `FERN_TOKEN`. 3. Add your Fern API key. If you don't already have one, generate one by running `fern token`. By default, the API key is generated for the organization listed in `fern.config.json`. 4. Click **Add secret**. #### Add secrets for Maven Central Add the following repository secrets by selecting **New repository secret** for each: 1. `MAVEN_USERNAME` - Your Maven Central username 2. `MAVEN_PASSWORD` - Your Maven Central password 3. `MAVEN_SIGNATURE_SECRET_KEY_ID` - Your GPG key ID 4. `MAVEN_SIGNATURE_PASSWORD` - Your GPG passphrase 5. `MAVEN_SIGNATURE_SECRET_KEY` - Your GPG secret key #### Set up a new workflow Set up a CI workflow that you can manually trigger from the GitHub UI. In your repository, navigate to **Actions**. Select **New workflow**, then **Set up workflow yourself**. Add a workflow that's similar to this: **`.github/workflows/publish.yml`** ```yaml title=".github/workflows/publish.yml" maxLines=0 name: Publish Java SDK on: workflow_dispatch: inputs: version: description: "The version of the Java SDK that you would like to release" required: true type: string jobs: release: runs-on: ubuntu-latest steps: - name: Checkout repo uses: actions/checkout@v4 - name: Install Fern CLI run: npm install -g fern-api - name: Release Java SDK env: FERN_TOKEN: ${{ secrets.FERN_TOKEN }} MAVEN_USERNAME: ${{ secrets.MAVEN_USERNAME }} MAVEN_PASSWORD: ${{ secrets.MAVEN_PASSWORD }} MAVEN_SIGNATURE_SECRET_KEY_ID: ${{ secrets.MAVEN_SIGNATURE_SECRET_KEY_ID }} MAVEN_SIGNATURE_PASSWORD: ${{ secrets.MAVEN_SIGNATURE_PASSWORD }} MAVEN_SIGNATURE_SECRET_KEY: ${{ secrets.MAVEN_SIGNATURE_SECRET_KEY }} run: | fern generate --group java-sdk --version ${{ inputs.version }} --log-level debug ``` > **Note** > > You can alternatively configure your workflow to execute `on: [push]`. #### Regenerate and release your SDK Navigate to the **Actions** tab, select the workflow you just created, specify a version number, and click **Run workflow**. This regenerates your SDK. The rest of the release process depends on your chosen mode: * **Release mode (default):** If you didn't specify a `mode` or set `mode: release`, no further action is required. Fern automatically tags the new release with your specified version number and initiates the publishing workflow in your SDK repository. * **Pull request or push mode:** If you set `mode: pull-request` or `mode: push`, Fern creates a pull request or pushes to a branch respectively. Review and merge the PR (`pull-request`) or branch (`push`), then [tag a new release](https://docs.github.com/en/repositories/releasing-projects-on-github/managing-releases-in-a-repository) to initiate the publishing workflow in your SDK repository. Once the workflow completes, you can view your new release by logging into Maven Central and navigating to **View Deployments**. #### Release via CLI and environment variables #### Set Maven environment variables Set the Maven Central environment variables on your local machine: ```bash export MAVEN_USERNAME=your-maven-username export MAVEN_PASSWORD=your-maven-password export MAVEN_SIGNATURE_SECRET_KEY_ID=your-gpg-key-id export MAVEN_SIGNATURE_PASSWORD=your-gpg-passphrase export MAVEN_SIGNATURE_SECRET_KEY=your-gpg-secret-key ``` #### Regenerate and release your SDK Regenerate your SDK, specifying the version: ```bash fern generate --group java-sdk --version ``` The rest of the release process depends on your chosen mode: * **Release mode (default):** If you didn't specify a `mode` or set `mode: release`, no further action is required. Fern automatically tags the new release with your specified version number and initiates the publishing workflow in your SDK repository. * **Pull request or push mode:** If you set `mode: pull-request` or `mode: push`, Fern creates a pull request or pushes to a branch respectively. Review and merge the PR (`pull-request`) or branch (`push`), then [tag a new release](https://docs.github.com/en/repositories/releasing-projects-on-github/managing-releases-in-a-repository) to initiate the publishing workflow in your SDK repository. Once the command completes, you can view your new release by logging into Maven Central and navigating to **View Deployments**. > Learn how to publish your Fern-generated Java SDK to Maven Central. Complete guide covering authentication, GPG signatures, and automated releases.