Working with Gradle and GitHub Packages

Published On: 28. September 2020|Categories: Tech|
Europace and other parts of our IT use a toolchain with GitHub, Jetbrains TeamCity, and Sonatype Nexus

Europace and other parts of our IT use a toolchain with GitHub, Jetbrains TeamCity, and Sonatype Nexus to implement CI/CD Pipelines. Developers have to be in the private network or connected to the VPN, if they want to access Maven and Gradle artifacts from our Nexus repository. Especially in times of COVID-19 more developers work from home, where connecting to the VPN becomes a necessity… does it?

With our efforts to leverage the GitHub platform with many of its features, GitHub Actions and GitHub Packages are an obvious choice to become more independent of services behind our firewalls.

Simply migrating to another artifact repository isn’t something we do on a Friday afternoon: There are shared depen­dencies across several teams, and we wouldn’t like any of them to miss a new release, because we didn’t publish it to the Nexus anymore.

In this article we want to show you how easy it is to use both the “old” Nexus, and the “new” GitHub Packages in your Gradle projects.

Note: We didn’t find a way to apply similar patterns to Maven projects, because Maven allows deploy­ments only to a single repository. Migrating a Maven project to Gradle might be the first step.

Gradle Confi­gu­ration: Publi­shing

The GitHub documen­tation gives you some examples for your Gradle config, along with details about authen­ti­cating to GitHub Packages. So, we’ll keep it short and simple. This is an example Gradle config to publish artifacts to multiple reposi­tories:

Copy to Clipboard

gradle.properties


Copy to Clipboard

build.gradle.kts



The shown config ensures that a ./gradlew publish creates the JarMavenPublication only once, but uploads it to both Nexus and GitHub Packages.

We won’t be able to perform the publish outside of our private network, though. That’s not an issue, because our existing CI config in TeamCity will be enhanced with the GitHub Packages creden­tials, and it can work just like before.

We’re now ready to consume the published artifacts. For existing projects nothing has to be changed, because our Nexus still provides even the most recent releases, but our goal to work independently of the VPN isn’t reached, yet.

Our consuming Gradle projects need to know about the new GitHub Packages repository. Simply adding a new repository “GitHub Packages” sadly won’t work, yet, because we have to add a new repository entry for each depen­dency on a GitHub Packages hosted artifact. This is different from a full fledged repository manager like Nexus (also acting as cache and proxy) and different from artifact collec­tions like Maven Central.

In contrast to the official GitHub documen­tation we’d like to show you a more advanced example consuming multiple reposi­tories:

Copy to Clipboard

The example is a bit simplified, because we use a single token to access all GitHub Packages. YMMV.

With our Nexus not acting as cache anymore, we applied the Repository Content Filtering Gradle feature to reduce failing lookups, thus incre­asing perfor­mance.

Final Thoughts

We’re aware of GitHub working on improving the overall user experience, so the examples above will certainly change over time.

Using modern tooling like Gradle and GitHub helps to slowly improve the CI/CD setup and developer experience when working from home or when traveling. We’re missing some features when comparing GitHub Packages with Nexus, but that’s something where we can give GitHub our feedback and tell them about our use cases.

The combi­nation of GitHub Actions and GitHub Packages works great for us, and we’re working on trans­ferring many “pull request builds” to run on GitHub. That shift removes load from our internal TeamCity agents, which improves our deployment pipeline perfor­mance.