Release a Gradle Project Using GitLab CI/CD Pipeline

I’ll show you how to configure Gradle build for a Java/Scala project and integrate it with GitLab CI/CD so that it can be automatically released and published to a Maven repository.

The example uses Axion release Gradle plugin to manage version number using git tags and Maven Publish Gradle plugin to upload artifacts to a Maven (Nexus) repository.

As an extra step I’m demonstrating how to publish a distribution zip file to the Maven repository and then how to add a link to GitLab release. You can see distZip in the code below which is provided by the Distribution Gradle plugin.

Create new variables CI_REPOSITORY_USERNAME and CI_REPOSITORY_PASSWORD in your GitLab project (Settings > CI/CD > Variables). Set them to Maven repository authentication credentials. The user must have permissions to publish to the repository.

Interesting parts of ./build.gradle:

plugins {
    id 'application'
    id 'maven-publish'
    id 'pl.allegro.tech.build.axion-release' version '1.13.6'
}

ext {
    repository_username = System.env.CI_REPOSITORY_USERNAME
    repository_password = System.env.CI_REPOSITORY_PASSWORD
}

group = 'com.example'
version = scmVersion.version

publishing {
    repositories {
        maven {
            name 'nexus'
            // Enter your Maven repository URL here:
            def releasesRepoUrl = 'https://.../repositories/releases'
            def snapshotsRepoUrl = 'https://.../repositories/snapshots'
            url = version.endsWith('SNAPSHOT') ? snapshotsRepoUrl : releasesRepoUrl
            credentials {
                username repository_username
                password repository_password
            }
        }
    }
    publications {
        // This is an extra (optional) publication:
        mavenJava(MavenPublication) {
            from components.java
            artifact distZip
        }
    }
}

scmVersion {
    // Not really needed, but I like it:
    useHighestVersion = true
}

// Other parts which are not related to release & publish
...

Here’s the ./.gitlab-ci.yml file. Check GitLab documentation for more details:

default:
  image: openjdk:8

variables:
  GIT_STRATEGY: clone
  # Make sure that you get tags from git repository otherwise the release
  # Gradle plugin will not be able to create the next version number:
  GIT_FETCH_EXTRA_FLAGS: --tags 
  GRADLE_OPTS: "-Dorg.gradle.daemon=false"

before_script:
  - export GRADLE_USER_HOME=`pwd`/.gradle

stages:
  - build
  - deploy

build_job:
  stage: build
  script:
    - ./gradlew build

publish_job:
  stage: deploy
  rules:
    - if: $CI_COMMIT_TAG
      when: never
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
  script:
    - ./gradlew createRelease -Prelease.disableChecks
    - ./gradlew publish
    - echo "TAG=$(./gradlew currentVersion -q -Prelease.quiet)" >> variables.env
  artifacts:
    reports:
      dotenv: variables.env

release_job:
  stage: deploy
  image: registry.gitlab.com/gitlab-org/release-cli:latest
  needs:
    - job: publish_job
      artifacts: true
  rules:
    - if: $CI_COMMIT_TAG
      when: never
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
  script:
    - echo "Releasing $TAG"
  release:
    name: 'Release v$TAG'
    description: $CI_COMMIT_MESSAGE
    tag_name: v$TAG
    ref: $CI_COMMIT_SHA
    assets:
      links:
        - name: 'Installation zip'
          url: "https://...your Nexus.../service/local/artifact/maven/redirect?g=com.example&a=example-app&v=$TAG&r=releases&e=zip"