Use Case
We've setup a pre-commit git hook that lints declarative pipelines (Jenkinsfiles). Currently all Jenkinsfiles in the repository are linted every time git commit
is issued. I am looking to improve the process by only linting Jenkinsfiles that have changed since the last Gradle execution. We are using Gradle (v7.5.1) to orchestrate tasks like Spotless check/apply and Jenkinsfile linting.
Example
I've registered two tasks in build.gradle. One task rounds up all Jenkinsfiles in the repository and the other lints them. For the purposes of brevity I've simplified the tasks listed below.
def jenkinsfiles = []
task getJenkinsfiles {
doLast {
jenkinsfiles = ['Jenkinsfile1', 'Jenkinsfile2', 'Jenkinsfile3']
//println(jenkinsfiles)
}
}
task lintJenkinsfiles {
dependsOn getJenkinsfiles
inputs.file(jenkinsfiles)
outputs.file('lintJenkinsfile.cache')
doLast {
println(jenkinsfiles)
}
}
Results
getJenkinsfiles
executes first without issue. If I uncomment println(jenkinsfiles)
in getJenkinsfiles
task, the value is printed to the console. However, lintJenkinsfiles
fails and states that the path may not be null or empty string. path='[]'
.
How does one reference a variable populated in task1 as an input in task2?
CodePudding user response:
I created the following task that's inspired by Torek's comment on my original question.
- Get all changed files using
git status --short
. Split the result by newline. - Iterate over each entry. Each entry will be in the format of
<status> <filename>
(i.e.,M test.txt
,M test.txt
,MM test.txt
). See thegit-status
page for more information. - If the entry's key (status) does not contain 'D' (deleted), add it to the
jenkinsfiles
list.
task lintJenkinsfiles {
def jenkinsfiles = []
def statusFileEntries = 'git status --short'.execute().text.split('\n')
for (def statusFileEntry : statusFileEntries) {
def statusFileEntryCapture = statusFileEntry =~ /^\s{0,1}(\w{1,2})\s{1,2}(.*Jenkinsfile)$/
if (statusFileEntryCapture.matches() && !statusFileEntryCapture[0][1].contains('D')) {
jenkinsfiles = statusFileEntryCapture[0][2].trim()
}
}
inputs.files(jenkinsfiles)
outputs.file('lintJenkinsfiles.cache')
doLast {
if (!jenkinsfiles.isEmpty()) {
println("Linting: ${jenkinsfiles}")
}
}
}