Blog Infos
Author
Published
Topics
, , , ,
Published

In my previous article, we explored the manual process of publishing artifacts to Maven Central. We established a solid foundation for understanding the requirements and steps involved.

Now, let’s take things to the next level! This guide will demonstrate how to leverage GitHub Actions to automate your Maven Central publication flow.

To ensure a smooth transition, I’ll assume you’ve already completed the setup process outlined in the previous article. This allows us to focus specifically on the automation aspect without repeating information. However, if you haven’t yet configured your project for deployment to Maven Central, I highly recommend taking a moment to review the earlier guide before proceeding.

GitHub Actions is a CI/CD platform integrated into GitHub that enables developers to automate software development workflows directly within their repositories. GitHub Actions can automate various tasks within your development workflow, such as testing your code, building your software, and deploying it to a server. By streamlining these processes, you can save time and improve efficiency.

Let’s dive into the requirements. As mentioned previously, we’ll assume you’ve already completed the necessary setup steps outlined in the previous article.

Requirements

You likely have the .gitignore file excluding gradle.properties. This file contains sensitive information that should never be committed to a public repository. We will start by remove these information because we will need to include in git the gradle.properties file. You’ll need this information later, so it’s recommended to make a copy of it for safekeeping. You will need to remove these parameters:

mavenCentralUsername=YOUR_MAVEN_CENTRAL_USERNAME
mavenCentralPassword=YOUR_MAVEN_CENTRAL_PASSWORD
signing.keyId=YOUR_SIGNING_KEY_ID
signing.password=YOUR_SIGNING_PASSWORD
signing.secretKeyRingFile=PATH/TO/YOUR/SECRET_KEY_RING_FILE

With sensitive information removed, you can now safely include your gradle.properties file in your Git repository bu removing it from the .gitignore.

Secure Secret Management with GitHub Actions

Now that your gradle.properties is cleaned and safely committed, we’ll leverage GitHub Actions’ secure secret management features. This ensures your secrets are never exposed in plain text within your code or workflow files.

While not strictly necessary, installing the GitHub CLI can simplify managing secrets. You can find installation instructions on the official websiteThis tool allows you to interact with GitHub’s secrets directly from your machine.

Let’s open your terminal and run the following commands:

gh secret set OSSRH_GPG_SECRET_KEY_ID -a actions --body "YOUR_SIGNING_KEY_ID"
gh secret set OSSRH_GPG_SECRET_KEY_PASSWORD -a actions --body "YOUR_SIGNING_PASSWORD"
gh secret set OSSRH_PASSWORD -a actions --body "YOUR_MAVEN_CENTRAL_PASSWORD"
gh secret set OSSRH_USERNAME -a actions --body "YOUR_MAVEN_CENTRAL_USERNAME"

These secrets correspond to the values you previously removed from your gradle.properties file.

In addition to the previously mentioned secrets, we need to generate and store two more for the publication process, but, for these we need the GPG secret key. To generate it, run the following command in your terminal, replacing YOUR_SIGNING_KEY_ID with your actual key ID:

gpg --export-secret-key --armor "YOUR_SIGNING_KEY_ID"

The output of this command will be block of text that look like this:

-----BEGIN PGP PRIVATE KEY BLOCK-----

xxxx
xxxx
xxxx
=qJG3
-----END PGP PRIVATE KEY BLOCK-----

We’ll create two GitHub secrets: OSSRH_GPG_SECRET_KEY and PLUGIN_SECRET_KEY. For the first one, copy the entire output from the gpg command and run the following command, replacing PASTE HERE with the copied content:

gh secret set OSSRH_GPG_SECRET_KEY -a actions --body "PASTE HERE"

To create the PLUGIN_SECRET_KEY remove the first two lines and the last two lines from the GPG secret key output (all the xxxx from my example) and run the following command with the modified content:

gh secret set PLUGIN_SECRET_KEY -a actions --body "PASTE HERE"

We’ve successfully created the necessary secrets. If you encounter any issues, you can easily manage your secrets in your repository’s settings. Go to Settings -> Secrets and variables -> Actions. Here, you can view, edit, or add new secrets as needed.

Job Offers

Job Offers

There are currently no vacancies.

OUR VIDEO RECOMMENDATION

No results found.

Jobs

Creating the GitHub Actions Workflow

With our secrets securely in place, we can now define the GitHub Actions workflow. Start by creating a .github directory at the root of your project. Inside this directory, create a workflows folder. This is where we’ll store our workflow configuration files.

To enhance organization and maintainability, I’ll split the publication process into two distinct workflows:

  • gradle.yml: Handles running tests.
  • deploy.yml: Takes care of the actual publication to Maven Central.

Let’s begin by creating the first workflow file named gradle.yml within the workflows directory. This file will define a workflow specifically for running tests. Here’s the content of the file:

name: Java CI with Gradle

on:
  push:
    branches: [ "main" ]
  pull_request:
    branches: [ "main" ]
  workflow_call:

permissions:
  contents: read

jobs:
  build:
    strategy:
      matrix:
        include:
          - target: testDebugUnitTest
            os: ubuntu-latest
          - target: testReleaseUnitTest
            os: ubuntu-latest
    runs-on: ${{ matrix.os }}

    steps:
    - uses: actions/checkout@v3
    - name: Validate Gradle Wrapper
      uses: gradle/wrapper-validation-action@v1
    - uses: actions/cache@v3
      with:
        path: |
          ~/.konan
        key: ${{ runner.os }}-${{ hashFiles('**/.lock') }}
    - name: Set up JDK 17
      uses: actions/setup-java@v3
      with:
        java-version: '17'
        distribution: 'temurin'
    - name: Build with Gradle
      uses: gradle/gradle-build-action@ce999babab2de1c4b649dc15f0ee67e6246c994f
      with:
        arguments: ${{ matrix.target }}

Let’s create the second workflow file named deploy.yml within the workflows directory. This file will define the workflow for publishing your library to Maven Central.

name: Deploy to central

on: workflow_dispatch

permissions:
  contents: read

jobs:
  build:
    uses: ./.github/workflows/gradle.yml
  deploy:
    needs: build
    runs-on: macos-latest
    steps:
    - uses: actions/checkout@v3
    - name: Validate Gradle Wrapper
      uses: gradle/wrapper-validation-action@v1
    - uses: actions/cache@v3
      with:
        path: |
          ~/.konan
        key: ${{ runner.os }}-${{ hashFiles('**/.lock') }}
    - name: Import GPG key
      uses: crazy-max/ghaction-import-gpg@v6
      with:
        gpg_private_key: ${{ secrets.OSSRH_GPG_SECRET_KEY }}
        passphrase: ${{ secrets.OSSRH_GPG_SECRET_KEY_PASSWORD }}
    - name: Set up JDK 17
      uses: actions/setup-java@v3
      with:
        java-version: '17'
        distribution: 'temurin'
    - name: Publish
      run: ./gradlew publishAllPublicationsToMavenCentralRepository
      env:
        ORG_GRADLE_PROJECT_mavenCentralUsername: ${{ secrets.OSSRH_USERNAME }}
        ORG_GRADLE_PROJECT_mavenCentralPassword: ${{ secrets.OSSRH_PASSWORD }}
        ORG_GRADLE_PROJECT_signingInMemoryKey: ${{ secrets.PLUGIN_SECRET_KEY }}
        ORG_GRADLE_PROJECT_signingInMemoryKeyId: ${{ secrets.OSSRH_GPG_SECRET_KEY_ID }}
        ORG_GRADLE_PROJECT_signingInMemoryKeyPassword: ${{ secrets.OSSRH_GPG_SECRET_KEY_PASSWORD }}

With these two workflow files in place, you can now trigger the deploy workflow to publish your library to Maven Central.

Launching the Workflow

With your workflow configuration complete, head over to your GitHub repository. Navigate to the Actions tab. You should see the two workflows.

To initiate the deployment process, click on the Deploy to central workflow and then press the Run workflow button.

GitHub will execute the defined steps. If everything goes smoothly, you’ll see a green checkmark indicating a successful deployment.

In case of errors, the workflow will fail, and you can inspect the logs to identify the issue. Each step provides detailed logs to help you troubleshoot.

Monitoring Publication Status

After initiating the deployment workflow, head over to on the Maven Central website to monitor your library’s validation status. Navigate to the Publish section to track the progress.

Once the library is successfully validated by Sonatype, you can proceed to the final step by clicking the Publish button located in the top right corner. This action will officially release your library to Maven Central.

Conclusions

With this article, we’ve covered the entire journey of publishing a library to Maven Central, from manual processes to automated workflows using GitHub Actions. By effectively managing secrets, configuring build and test jobs, and streamlining the deployment process, you can significantly enhance your development efficiency.

This guide aims to empower you to share your open-source libraries with the broader Android community. By publishing your work on Maven Central, you contribute to the ecosystem and make it easier for other developers to build upon your efforts.

If you’re looking for a concrete example, feel free to explore an open-source project I’ve configured with this setup, here.

By following the steps outlined in this article and leveraging the provided resources, you’ll be well-equipped to automate your library’s publication and share your valuable contributions with the Android community.

I hope you found this article informative and helpful. I regularly publish articles on various Android topics, so be sure to follow me to stay updated on my latest work. If you enjoyed this article, please consider rating it to help others discover valuable content.

This article is previously published on proandroiddev.com

YOU MAY BE INTERESTED IN

YOU MAY BE INTERESTED IN

blog
Using annotations in Kotlin has some nuances that are useful to know
READ MORE
blog
One of the latest trends in UI design is blurring the background content behind the foreground elements. This creates a sense of depth, transparency, and focus,…
READ MORE
blog
Now that Android Studio Iguana is out and stable, I wanted to write about…
READ MORE
blog
The suspension capability is the most essential feature upon which all other Kotlin Coroutines…
READ MORE
Menu