Skip to content

simonhauck/gradle-release-plugin

Repository files navigation

Gradle Release Plugin

Main Plugin Portal

The Gradle Release Plugin is a small tool designed to streamline and automate the release process for your Gradle projects. The plugin will increment the version number, commit, tag and push the changes to the git repository and increase the version again to a new snapshot version. It is inspired by the researchgate/release-plugin, but addresses some of its shortcomings and provides additional functionalities.

  • Multiple Release Types: You can either directly specify the release version or use a simplified API and just select the release type. Let the plugin do the rest.
  • Adaptable Release Workflow: The plugin offers flexibility by allowing you to incorporate custom tasks into the release process to make it fit your specific project requirements
  • Composite Build Support: This plugin can be applied to projects with a composite build, addressing an issue found in the above-mentioned project.
  • Configuration Cache Support: This plugin can be used in projects where the configuration cache is enabled issue

Feature overview

Here is an overview of the planned features. To vote for a feature, either create an issue or give a thumbs up on an existing issue.

Feature Description Implementation Status Related issues
Release with explicit version numbers Release while providing explicit version numbers #3
Support Trunk based released The plugin can perform a release on a given branch #3
Simplified API Release with a single parameter like major, minor, patch #15
Support Gitflow The plugin should perform merge commits from a development branch to a main branch No issue created yet
Check for snapshot versions Add an optional check to verify the project does not use any snapshot versions. No issue created yet

How to use the plugin

Here is quick guide on how to get started using this plugin.

Prerequisites

  1. Git: In order to perform the different git operations the plugin requires git to be available in the path
  2. Version properties file: A version file must be available. The file should contain a key version which contains the current project version as shown in this example here. The plugin will write the updated version there. By default, the file should be located in the root project and be named version.properties. You can change the name and location with the configuration.
  3. Gradle: Version 6.1 or higher

Configuration

In your build.gradle.kts file, apply the plugin and configure it as shown below:

// build.gradle.kts
import io.github.simonhauck.release.version.api.Version

plugins {
    id("io.github.simonhauck.release") version "<the-current-version>"
}

val versionFile = layout.projectDirectory.file("version.properties")

release {
    versionPropertyFile.set(versionFile)
}

// If you want to set the version in you gradle project you can use this helper method
version = Version.fromPropertiesFile(versionFile.asFile)

The plugin provides sensible defaults for the release process. If you want to customize the release process, have a look at the configuration options.

Trigger a release

If you have a project layout as described in the prerequisites section, you can already start releasing. The plugin provides several ways to set the new version.

In all cases, the plugin will create two commits. The first commit will contain the release version. This commit will be tagged and pushed. Afterward, a second commit with the post release version will be performed and pushed. Typically, you want to set the next snapshot version here. If you are running this in an CI environment, these commits can trigger a new build where you can perform additional release logic. An example for GitHub actions is shown here.

If your want to test your configuration locally without bothering your team with constant commits, you can disable pushes with the shown configuration. It will still generate commits and tags, but you can delete them locally afterward.

// build.gradle.kts
release {
    disablePush = true
}

Option 1: Specify the versions explicitly

The first option is to specify the release and post release versions explicitly. For this you can trigger the release with the following gradle command:

./gradlew release -PreleaseVersion=1.0.0 -PpostReleaseVersion=1.0.1-SNAPSHOT

Replace the values for the releaseVersion and postReleaseVersion with your desired target values.

Option 2: Use the release type

If you have a semver compatible version you can choose to use the simplified api:

./gradlew release -PreleaseType=<release-type>

Replace the release-type with major, minor or patch. This will determine the version automatically.

Customizing the release process

You can easily customize the release process by adding additional tasks and making the relevant tasks depend on your custom tasks. Here are the most interesting tasks performed by the plugin:

  1. writeReleaseVersion: This task writes the release version to your version file.
  2. commitReleaseVersion: This task will create a commit tagged with the release version.
  3. pushRelease: This task will perform the push operation.
  4. writePostReleaseVersion: This task with write the post release version to your version file.
  5. commitPostReleaseVersion: This task will commit the post release version. This commit will not be tagged.
  6. pushPostRelease: This task will push the post release version.

Please note: The plugin will just write the version to the specified version file. Gradle will not automatically reload the version property. The version variable from gradle will still show the old version. If you need the version for your custom task, you either have to read the version directly from the file or run multiple gradle commands.

Example

Let's assume, you want to write an additional file during the release. You could register your custom task and make the commitReleaseVersion task depend on that. If you want to commit this file with the release commit, you can edit the git add command in the release configuration to include both the version file and your custom file. An example for that is shown below:

// build.gradle.kts

// Modify the git add command to include your file. You have to specify all files (including the version file). 
// By default, this is just the version file.
release {
    releaseCommitAddFiles.set(listOf(file("version.properties"), file("release-file.txt")))
}

// This is your custom task
val customTask = tasks.register("myCustomTask") {
    // If you want to do something with the version, depend on the writeReleaseVersion task
    dependsOn(tasks.writeReleaseVersion)
    val outputFile = layout.projectDirectory.file("release-file.txt")

    doLast { outputFile.asFile.writeText("value") }
}


// The commit task should depend on your task
tasks.commitReleaseVersion { dependsOn(customTask) }

Parameter specification

Here are all parameters listed for the release extension. The plugin provides sensible defaults for all parameters, so you can start without any configuration.

Parameter Name Type Description Default value
rootGitDirectory RegularFile The root of your git project. <gradle-project-dir>
versionPropertyFile RegularFile The file containing the version. The content should contain version=<your-version> <gradle-project-dir>/version.properties
releaseCommitAddFiles List <File> The files that should be added for the release commit [<gradle-project-dir>/version.properties]
releaseCommitMessage String The commit message used for the release commit. The key {version} is replaced with the release version "Release commit: v{version}"
postReleaseCommitAddFiles List <File> The files that should be added for the post release commit <gradle-project-dir>/version.properties
postReleaseCommitMessage String The commit message used for the post release commit. The key {version} is replaced with the post release version "Post release commit: v{version}"
commitMessagePrefix String A prefix that is added for all commits ""
tagName String The name for the release tag. The key {version} is replaced with the release version v{version}
gitName String Git name used for the commit. Requires additionally the GitEmail. Falls back to the Git default values null
gitEmail String Email used for the commit. Falls back to the Git default values null
sshKeyFile RegularFile A location of an ssh key file. If the value is null, the standard git authentication methods are used null
disablePush Boolean Disable the actual push operation. This is useful for local testing / development false
delayBeforePush Duration Some systems aggregate commits that are done to quickly. You can specify a delay before the second push operation Duration.ZERO
checkForUncommittedFiles Boolean Checks for any uncommitted files in the working directory before the release process commit is pushed true

Example with GitHub Actions

You can use this plugin with any CI/CD system. Here is an example how you can use this plugin with GitHub actions.

The general workflow will be:

  1. Trigger a release with a manual job
  2. For tagged commits, run your release procedure like publishing the artifacts.
    • Depending on your setup you can also do your release logic if the version does not have a snapshot suffix

To trigger the release you can take inspiration from the following configuration. This task has two inputs for the release version and post release version.

Trigger Release Action
# .github/workflows/trigger-release.yml
name: Trigger Release

on:
  workflow_dispatch:
    inputs:
      release-version:
        description: 'The version with which the code should be released'
        type: string
        required: true
      post-release-version:
        description: 'The next snapshot version'
        type: string
        required: true


jobs:
  trigger-release:
    runs-on: ubuntu-latest
    name: Trigger the release
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4
        with:
          # It is important to perform the checkout with an access token. Only with that can the commit trigger a new build!          
          token: ${{secrets.PERSONAL_ACCESS_TOKEN}}

      # Your setup actions

      # Set the git username and email for the commit
      - name: Set Git User and Email
        run: |
          git config --global user.email "[email protected]"
          git config --global user.name "GitHub Action"

      - name: Run gradle release task
        run: ./gradlew release -PreleaseVersion=${{ github.event.inputs.release-version }} -PpostReleaseVersion=${{ github.event.inputs.post-release-version }}

To do something with the release add another workflow file that is triggered when a tag is pushed.

Release Tag action
# .github/workflows/on-release-tag.yml

name: Release

on:
  push:
    tags:
      - v*

jobs:
  release:
  # Your jon configuration

How to contribute

Issues and pull requests are welcome. Please fill out the issue template and provide as much information as possible. Please have a look at the CONTRIBUTING Guide for more information.