Introduction

I’m used to importing libraries that I need in gradle by simply adding them as a dependency for implementation or testing in build.gradle or build.gradle.kts.

However, I’ve always been curious about how to publish my own dependency that can easily be used by other projects.

This tutorial shows how to take a Kotlin library and publish it to the GitHub Package Registry and JitPack, as a dependency that can be used in gradle projects. I used to use JFrog Bintray but both Bintray and JCenter are going to be shut down in May 2021.

In this tutorial I will create the color-console library that allows console messages to be colorized using ANSI color codes. Here is the end result snippet that we are looking to enable for our color-console library.

Using JitPack (much simpler, and the way to go for public dependencies)

This could not be any easier. It’s really a 2 step process, once you have your library built with gradle and its git repo pushed into GitHub, eg color-console.

Publish and build it

  1. Make sure to create a new release for your dependency, eg: v1.0.0.
  2. Visit jitpack.com and type nazmulidris/color-console into the text box at the top of the page, and click on “Look up”. This will start the import of your gradle repo into JitPack and it will build it (using build.gradle or build.gradle.kts just like you would on your local machine). There are no special steps or things you have to add to your build file! Once the build process is complete you will see that the logs are published and your dependency is ready to be used. It is that simple.

Import and use it

Then, in the project where you want to add this library as a dependency, eg: idea-plugin-example you have to do the following. You can import this dependency into your gradle projects by making the following changes to your build.gradle or build.gradle.kts file.

  1. Add this at the end of your repositories section.

    For build.gradle:

      repositories {maven { url 'https://jitpack.io' }}
    }
    

    For build.gradle.kts:

    repositories {
      maven{
        url = uri("https://jitpack.io")
      }
    }
    
  2. Add the dependency.

    For build.gradle:

    dependencies { implementation 'com.github.nazmulidris:color-console:1.0.0' }
    

    For build.gradle.kts:

    dependencies { implementation ("com.github.nazmulidris:color-console:1.0.0") }
    

Information about this dependency on JitPack:

  • You can find this dependency on JitPack here
  • You can find the JitPack build logs here

Using GitHub Package Registry (complex and has authentication issues for public dependencies)

Desired snippet for build.gradle.kts (using Kotlin DSL):

repositories {
  maven {
    name = "GitHubPackages"
    url = uri("https://maven.pkg.github.com/nazmulidris/color-console")
    credentials {
      username = System.getenv("GITHUB_PACKAGES_USERID") ?: "nazmulidris"
      // Safe to share the password since it is a `read:package` scoped token.
      password = System.getenv("GITHUB_PACKAGES_IMPORT_TOKEN") ?: "22e9ba0d47c3e9116a2f1023867a1985beebfb60"
    }
  }
}

dependencies {
  implementation("com.developerlife:color-console:1.0")
}

Desired snippet for build.gradle (using Groovy):

repositories {
  maven {
    name = "GitHubPackages"
    url = uri("https://maven.pkg.github.com/OWNER/REPOSITORY")
    credentials {
      username = System.getenv("GITHUB_PACKAGES_USERID") ?: "nazmulidris"
      // Safe to share the password since it is a `read:package` scoped token.
      password = System.getenv("GITHUB_PACKAGES_IMPORT_TOKEN") ?: "22e9ba0d47c3e9116a2f1023867a1985beebfb60"
    }
  }
}

dependencies {
  implementation 'com.developerlife:color-console:1.0'
}

Create a new GitHub repo for the actual code of the library

The code that comprises the library, that will be built is in this GitHub repo for color-console.

Using IDEA create a Gradle + Java + Kotlin (JVM) project. Make sure it uses Kotlin and not Groovy for the Gradle build script (I only got this working w/ the Kotlin DSL and not Groovy). It’s a very simple Kotlin and Gradle that has a single source file. Add the source code there and the following steps are where things get interesting.

Generate the personal access tokens that will be needed to publish and import

The first step is to create some GitHub personal access tokens that will do 2 things. You might consider saving them to global environment variables using whatever shell you use.

  1. GITHUB_PACKAGES_PUBLISH_TOKEN - this token has repo, write:packages scope. Do NOT share this!
  2. GITHUB_PACKAGES_IMPORT_TOKEN - this token has read:packages scope. This is ok to share.

You might also consider saving the following environment variable too.

  1. GITHUB_PACKAGES_USERID - this is the GitHub username for the token. This is ok to share.

Add GitHub Package Registry support to the build script so that the package can be published

Edit the build.gradle.kts file to allow this library to be published to GitHub Packages. Here are the high level steps.

  1. Add some plugins so that we can publish this project to GitHub Packages.
  2. Configure the maven publishing plugin. More info.
  3. To publish, you have to run the gradle task named publish. This will generate a release package for color-console.
  4. Before publishing you might want to test that this works locally by using the publishToMavenLocal task which will generate the artifacts locally and save them to the $HOME/.m2/repository/com/developerlife/color-console/ folder.

Here is what you need to add to your build.gradle.kts:

publishing {
  repositories {
    maven {
      name = "GitHubPackages"
      url = uri("https://maven.pkg.github.com/${myGithubUsername}/${myArtifactId}")
      credentials {
        username = System.getenv("GITHUB_PACKAGES_USERID")
        password = System.getenv("GITHUB_PACKAGES_PUBLISH_TOKEN")
      }
    }
  }
}

publishing {
  publications {
    register("gprRelease", MavenPublication::class) {
      groupId = myArtifactGroup
      artifactId = myArtifactId
      version = myArtifactVersion

      from(components["java"])

      artifact(sourcesJar)
      artifact(dokkaJavadocJar)

      pom {
        packaging = "jar"
        name.set(myArtifactId)
        description.set(myGithubDescription)
        url.set(myGithubHttpUrl)
        scm {
          url.set(myGithubHttpUrl)
        }
        issueManagement {
          url.set(myGithubIssueTrackerUrl)
        }
        licenses {
          license {
            name.set(myLicense)
            url.set(myLicenseUrl)
          }
        }
        developers {
          developer {
            id.set(myGithubUsername)
            name.set(myDeveloperName)
          }
        }
      }

    }
  }
}

Here is a link to the entire source file so that you can see where these variables are defined and what the other functions are that generate the docs and the JAR files using the pom function.

Import this dependency into another gradle project

In order to load the package for the library from GitHub Packages Registry, the official docs provide some detailed examples of the provider side of things. And you can extrapolate what the consumer side of things might look like. The biggest thing to keep in mind is that a read:packages scoped GitHub personal access token will be required by the consumer of the package (and has to be accessible their build.gradle or build.gradle.kts file).

Make sure to provide the following environment variables before you import this package.

  1. GITHUB_PACKAGES_IMPORT_TOKEN - this token has read:packages scope. This is ok to share.
  2. GITHUB_PACKAGES_USERID - this is the GitHub username for the token. This is ok to share.

Here is more information on how to declare your own maven repositories using gradle.

To import this library into your Gradle project, please add the following lines in your build.gradle file in order to use this library (in Groovy).

repositories {
  maven {
    name = "GitHubPackages"
    url = uri("https://maven.pkg.github.com/nazmulidris/color-console")
    credentials {
      username = System.getenv("GITHUB_PACKAGES_USERID") ?: "nazmulidris"
      // Safe to share the password since it is a `read:package` scoped token.
      password = System.getenv("GITHUB_PACKAGES_IMPORT_TOKEN") ?: "22e9ba0d47c3e9116a2f1023867a1985beebfb60"
    }
  }
}

dependencies {
    implementation 'com.developerlife:color-console:1.0'
}

Here’s the Kotlin DSL version for build.gradle.kts:

repositories {
  maven {
    name = "GitHubPackages"
    url = uri("https://maven.pkg.github.com/nazmulidris/color-console")
    credentials {
      username = System.getenv("GITHUB_PACKAGES_USERID") ?: "nazmulidris"
      // Safe to share the password since it is a `read:package` scoped token.
      password = System.getenv("GITHUB_PACKAGES_IMPORT_TOKEN") ?: "22e9ba0d47c3e9116a2f1023867a1985beebfb60"
    }
  }
}

dependencies {
  implementation("com.developerlife:color-console:1.0")
}

References

Related Posts