Как получить список измененных файлов с момента последней сборки в 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