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 saveChecksums
With 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.propertyFile
is 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.algorithm
is 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.defaultSource
controls 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.taskNameTemplate
controls the naming convention used for generated checksum tasks. In the above example, the generated checksum tasks would betaskOneChecksum
andtaskTwoChecksum
. -
checksum.propertyNameTemplate
controls 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.taskOne
andchecksum.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>.source
is the individual task source configuration. If not set, thechecksum.defaultSource
value is used. See Checksum Source Configuration Options for more detail on the individual options. -
<task>.taskName
explicitly 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>.propertyName
explicitly 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>.include
is the directive to control what files are included in the checksum calculation. The default is to include all files. -
<task>.exclude
is 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.