Как получить список измененных файлов с момента последней сборки в Jenkins/Hudson
Я настроил Jenkins, но я хотел бы узнать, какие файлы были добавлены/изменены между текущей сборкой и предыдущей сборкой. Я хотел бы запустить несколько длительных тестов в зависимости от того, были ли изменены некоторые части исходного дерева.
Поискав в Интернете, я не могу найти упоминания об этой способности в Хадсон/Дженкинс, хотя были сделаны предложения использовать хуки после фиксации SVN. Может быть, это так просто, что все (кроме меня) знают, как это сделать!
Это возможно?
Ответы
Ответ 1
Сервер CI покажет вам список изменений, если вы проводите опрос изменений и с помощью обновления SVN. Однако, похоже, вы хотите изменить поведение сборки в зависимости от того, какие файлы были изменены. Я не думаю, что есть какой-нибудь готовый способ сделать это с Дженкинсом.
Пост-фиксация - разумная идея. Вы можете параметризовать задание, и ваш крюк script запустит сборку с заданным значением параметра в соответствии с внесенными изменениями. Я не уверен, насколько это сложно для вас.
Однако вы можете захотеть разделить это на два отдельных задания - одно, которое выполняется на каждом коммите, и отдельное для длительных тестов, которые вам не всегда нужны. Лично я предпочитаю поддерживать соответствие поведения между казнями. Иначе прослеживаемость страдает.
Ответ 2
Я сделал это следующим образом. Я не уверен, что это правильный путь, но, похоже, он работает. Вам нужно установить плагин Jenkins Groovy и выполнить следующий скрипт.
import hudson.model.*;
import hudson.util.*;
import hudson.scm.*;
import hudson.plugins.accurev.*
def thr = Thread.currentThread();
def build = thr?.executable;
def changeSet= build.getChangeSet();
changeSet.getItems();
ChangeSet.getItems() дает вам изменения. Так как я использую accurev, я сделал List<AccurevTransaction> accurevTransList = changeSet.getItems();
,
Здесь измененный список содержит дубликаты файлов/имен, если он был зафиксирован более одного раза во время текущего окна сборки.
Ответ 3
echo $SVN_REVISION
svn_last_successful_build_revision=`curl $JOB_URL'lastSuccessfulBuild/api/json' | python -c 'import json,sys;obj=json.loads(sys.stdin.read());print obj["'"changeSet"'"]["'"revisions"'"][0]["'"revision"'"]'`
diff=`svn di -r$SVN_REVISION:$svn_last_successful_build_revision --summarize`
Ответ 4
Используя плагин Build Flow и Git:
final changeSet = build.getChangeSet()
final changeSetIterator = changeSet.iterator()
while (changeSetIterator.hasNext()) {
final gitChangeSet = changeSetIterator.next()
for (final path : gitChangeSet.getPaths()) {
println path.getPath()
}
}
Ответ 5
Вы можете использовать Jenkins API удаленного доступа, чтобы получить машиночитаемое описание текущей сборки, включая полный набор изменений. Тонкость здесь заключается в том, что если у вас настроен "тихий период", Jenkins может объединить несколько коммитов в один и тот же репозиторий в одну сборку, поэтому полагаться на один номер версии немного наивно.
Мне нравится сохранять мои крючки post-commit Subversion относительно простыми и передавать вещи на сервер CI. Для этого я использую wget для запуска сборки, что-то вроде этого...
/usr/bin/wget --output-document "-" --timeout=2 \
https://ci.example.com/jenkins/job/JOBID/build?token=MYTOKEN
Затем задание задается на стороне Jenkins для выполнения Python script, который использует переменную среды BUILD_URL
и создает для нее URL-адрес API. URL-адрес заканчивается следующим образом:
https://ci.example.com/jenkins/job/JOBID/BUILDID/api/json/
Вот пример кода Python, который можно запустить внутри оболочки script. Я оставил без всякой обработки ошибок или HTTP-аутентификации, чтобы читать здесь все.
import os
import json
import urllib2
# Make the URL
build_url = os.environ['BUILD_URL']
api = build_url + 'api/json/'
# Call the Jenkins server and figured out what changed
f = urllib2.urlopen(api)
build = json.loads(f.read())
change_set = build['changeSet']
items = change_set['items']
touched = []
for item in items:
touched += item['affectedPaths']
Ответ 6
Через Groovy:
<!-- CHANGE SET -->
<% changeSet = build.changeSet
if (changeSet != null) {
hadChanges = false %>
<h2>Changes</h2>
<ul>
<% changeSet.each { cs ->
hadChanges = true
aUser = cs.author %>
<li>Commit <b>${cs.revision}</b> by <b><%= aUser != null ? aUser.displayName : it.author.displayName %>:</b> (${cs.msg})
<ul>
<% cs.affectedFiles.each { %>
<li class="change-${it.editType.name}"><b>${it.editType.name}</b>: ${it.path} </li> <% } %> </ul> </li> <% }
if (!hadChanges) { %>
<li>No Changes !!</li>
<% } %> </ul> <% } %>
Ответ 7
#!/bin/bash
set -e
job_name="whatever"
JOB_URL="http://myserver:8080/job/${job_name}/"
FILTER_PATH="path/to/folder/to/monitor"
python_func="import json, sys
obj = json.loads(sys.stdin.read())
ch_list = obj['changeSet']['items']
_list = [ j['affectedPaths'] for j in ch_list ]
for outer in _list:
for inner in outer:
print inner
"
_affected_files='curl --silent ${JOB_URL}${BUILD_NUMBER}'/api/json' | python -c "$python_func"'
if [ -z "'echo \"$_affected_files\" | grep \"${FILTER_PATH}\"'" ]; then
echo "[INFO] no changes detected in ${FILTER_PATH}"
exit 0
else
echo "[INFO] changed files detected: "
for a_file in 'echo "$_affected_files" | grep "${FILTER_PATH}"'; do
echo " $a_file"
done;
fi;
Это немного отличается - мне нужен был скрипт для Git для конкретной папки... Итак, я написал чек на основе jollychang.
Его можно добавить непосредственно в сценарий оболочки exec работы. Если никакие файлы не обнаружены, он будет exit 0
, то есть SUCCESS
... таким образом, вы всегда можете инициировать возврат в хранилище, но создавать при изменении файлов в интересующей папке.
Но... Если вы хотите собрать по требованию (то есть щелкнуть Построить сейчас) с изменением с предыдущей сборки.. вы бы изменили _affected_files
на:
_affected_files='curl --silent $JOB_URL'lastSuccessfulBuild/api/json' | python -c "$python_func"'
Ответ 8
Для конвейеров Jenkins (плагин поддержки API для конвейеров 2.2 или выше) это решение работает для меня:
def changeLogSets = currentBuild.changeSets
for (int i = 0; i < changeLogSets.size(); i++) {
def entries = changeLogSets[i].items
for (int j = 0; j < entries.length; j++) {
def entry = entries[j]
def files = new ArrayList(entry.affectedFiles)
for (int k = 0; k < files.size(); k++) {
def file = files[k]
println file.path
}
}
}
См. Как получить доступ к журналам изменений в конвейерном задании.
Ответ 9
Примечание. Чтобы получить список изменений, вы должны использовать собственный SVN-клиент Jenkins. Выполнение этого на этапе сборки оболочки не приведет к перечислению изменений в сборке.
Ответ 10
Это просто, но это работает для меня:
$DirectoryA = "D:\Jenkins\jobs\projectName\builds" ####Jenkind directory
$firstfolder = Get-ChildItem -Path $DirectoryA | Where-Object {$_.PSIsContainer} | Sort-Object LastWriteTime -Descending | Select-Object -First 1
$DirectoryB = $DirectoryA + "\" + $firstfolder
$sVnLoGfIle = $DirectoryB + "\" + "changelog.xml"
write-host $sVnLoGfIle