Пример использования
Мы настроили git-хук перед фиксацией, который анализирует декларативные конвейеры (Jenkinsfiles). В настоящее время все Jenkinsfiles в репозитории анализируются каждый раз, когда выдается git commit
. Я хочу улучшить процесс, проверяя только Jenkinsfiles, которые изменились с момента последнего выполнения Gradle. Мы используем Gradle (v7.5.1) для организации таких задач, как Spotless проверка/применение и анализ Jenkinsfile.
Пример
Я зарегистрировал две задачи в build.gradle. Одна задача собирает все Jenkinsfiles в репозитории, а другая проверяет их. Для краткости я упростил перечисленные ниже задачи.
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)
}
}
Полученные результаты
getJenkinsfiles
выполняется первым без проблем. Если я раскомментирую println(jenkinsfiles)
в задаче getJenkinsfiles
, значение будет выведено на консоль. Однако lintJenkinsfiles
терпит неудачу и заявляет, что path may not be null or empty string. path='[]'
.
Как ссылаться на переменную, заполненную в задаче 1, в качестве входных данных в задаче 2?
Спасибо @torek. Я смог разработать задачу, вдохновленную вашим комментарием.
Я создал следующую задачу, вдохновленную комментарием Торека к моему первоначальному вопросу. Также обратите внимание, что я объединил две задачи в одну, чтобы скрипт Groovy обрабатывался раньше inputs
и outputs
.
git status --porcelain
. Разделите результат на новую строку.<status> <filename>
(т. е. M test.txt
, M test.txt
, MM test.txt
). См. страницу git-status для получения дополнительной информации.jenkinsfiles
.task lintJenkinsfiles {
def jenkinsfiles = []
def statusFileEntries = 'git status --porcelain'.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}")
}
}
}
Примечание: для интерпретации вывода git status
с машинным кодом используйте git status --porcelain
или git status --porcelain=v2
. Старый вывод v1 на самом деле является выводом --short
, так что это то же самое, но использование правильного флага защитит ваш код от обновлений Git в будущем.
Кажется, этот вопрос касается написания кода в Groovy, что делает тег groovy более подходящим. Что касается Git, все, с чем Git может вам помочь, — это
git diff --name-status
между любым заданным набором коммитов; вам нужно знать последнюю фиксацию, где что-то проверялось.