This plugin is provides the ability to compute useful checksums for Gradle tasks. The primary driver is to have a mechanism by which it can be detected if an assembled artifact was the same as the one that was previously published and if so, skip the publishing step.
buildscript {
repositories {
maven {
url 'https://plugins.gradle.org/m2/'
}
}
dependencies {
classpath 'com.scrain.gradle:checksum-plugin:0.6'
}
}
apply plugin: 'com.scrain.checksum-plugin'plugins {
id 'com.scrain.checksum-plugin' version '0.6'
}Simple example configuration that creates a checksum for a JAR file created by the java plugin.
checksum {
tasks {
jar {} // will create a checksum for the jar task
}
}Now if you execute the saveChecksums tasks this will compute and save a checksum for the jar tasks in the
file called (by default) checksums.properties.
checksum.jar=39b2b893265b6641971057d6d41f1befc838cc6d
Maintaining this file to source control now allows you to use the previously computed checksums to conditionally
disable other tasks. For example, if you would like to prevent the publish tasks from executing if the jar
task’s checksum is the same you would add the following to your gradle build.
publish.dependsOn computeChecksums
publish.onlyIf {
// compares the latest computed checksum to those saved in the checksums property file.
! computeChecksums.sameAsPropertyFile()
}
publish.finalizedBy saveChecksumsWith the above build configuration, executing the publish task will automatically execute computeChecksums
and subsequently stop the publish task from executing if the checksum found within the checksums properties
file matches the computed value. If the value is not the same, then the publish task will execute and
be followed by the saveChecksums task which will update the checksum in the file. The updated checksums
properties file should then be committed back to source control.
Using a configuration extension, tasks can be identified for which checksums should be calculated. Checksums can be
computed from a task using files identified in its inputs, outputs or both. For each task identified within the
configuration, a corresponding task of type com.scrain.gradle.ChecksumTask is created that performs
the checksum calculation.
An overall plugin configuration can be set that changes the behaviour of all checksum tasks that might be executed, but this can be further tweaked for each individual task as well.
checksum {
propertyFile 'checksums.properties' (1)
algorithm 'sha1' (2)
defaultSource 'auto' (3)
taskNameTemplate '${task}Checksum' (4)
propertyNameTemplate 'checksum.${task}' (5)
tasks { (6)
taskOne { }
taskTwo { }
}
}-
checksum.propertyFileis the file in which checksum values should be stored. Can be a stand alone file or a file containing values unrelated to checksums such asgradle.properties. -
checksum.algorithmis the algorithm to use for checksum calculations. Checksum calculations are performed using the Gradle’s AntBuilder Checksum task, so any algorithm supported by this task should be available. -
checksum.defaultSourcecontrols from where the checksum task should obtain files to use for its checksum calculations. Options are:'auto', 'inputs', 'outputs', 'both'. See Checksum Source Configuration Options for more detail on the individual options. -
checksum.taskNameTemplatecontrols the naming convention used for generated checksum tasks. In the above example, the generated checksum tasks would betaskOneChecksumandtaskTwoChecksum. -
checksum.propertyNameTemplatecontrols the naming convention used for the property names under which individual checksum values are stored within the checksums property file. In the above example, the generated property names would bechecksum.taskOneandchecksum.taskTwo. -
checksum.tasks { }is where the names of tasks should be specified for which checksums should be calculated. Information on what can be configured for each task in in the next section.
jar task showing all default task valueschecksum {
tasks {
jar {
source null (1)
taskName null (2)
propertyName null (3)
include '**/*' (4)
exclude '' (5)
}
}
}-
<task>.sourceis the individual task source configuration. If not set, thechecksum.defaultSourcevalue is used. See Checksum Source Configuration Options for more detail on the individual options. -
<task>.taskNameexplicitly sets the name of the generated checksum task. If not set, the task name is generated is based on the convention found inchecksum.taskNameTemplate. -
<task>.propertyNameexplicitly sets the name of the property under which the checksum value will be saved in the checksum property file. If not set, name is generated based on convention found inchecksum.propertyNameTemplate. -
<task>.includeis the directive to control what files are included in the checksum calculation. The default is to include all files. -
<task>.excludeis the directive to control what files are excluded from the checksum calculation. The default is to exclude no files.
|
Note
|
See official Gradle documentation
on org.gradle.api.PatternFilterable for more detail on how include and exclude might be configured.
|
When the plugin creates a checksum task based from the checksum configuration block, it can configure it to calculate
the checksum from the files found within the identified task’s inputs, outputs or both. By default
checksum.defaultSource is set to auto, but values of inputs, outputs or both are also supported. In addition,
this can be overridden for each individual task explicitly by setting its <task>.source option. Descriptions of each
option are as follows:
| Option | Description |
|---|---|
|
Using this option will result in the checksum task being configured to use the files found in a task’s inputs if
|
|
Uses the files found in a task’s inputs for checksum calculations |
|
Uses the files found in a task’s outputs for checksum calculations |
|
Uses the files found in both a task’s inputs and outputs for checksum calculations |
It is not uncommon for build tasks to produce output that contains timestamps or other build-time related information.
While including these do not prevent checksums from being calculated, it will cause their values to be different for
every new build even though nothing may have materially changed. If this is limited to a few files, the checksum
could be made to be more stable by using the include or exclude configurations to omit these ever-changing files.
Zip archives contain a lot of time sensitive information, including the timestamps of the source files that the archive
contains. This makes checksums for build generated archives very volatile even through the files they contain might be
identical as the previous. For more stable checksums between builds, you can use the Zip task’s input files instead.
In fact, the plugin’s default configuration of checksum.defaultSource=auto should automatically use input files over
output if they are available and give you this behavior.
Prior to groovy 2.4, the groovy compiler embedded timestamps directly within the class files. Because of this the checksums for compiled classes will always be different between builds making them useless for detecting material changes between builds. See the following references for more detail.