Как получить список измененных файлов с момента последней сборки в Jenkins / Hudson - PullRequest
32 голосов
/ 07 июня 2011

Я настроил Jenkins, но я хотел бы узнать, какие файлы были добавлены / изменены между текущей сборкой и предыдущей сборкой.Я хотел бы запустить несколько длительных тестов в зависимости от того, были ли изменены определенные части дерева исходного кода.

Поискав в Интернете, я не могу найти упоминания об этой способности в Хадсон / Дженкинс, хотя были высказаны предложенияиспользовать SVN-хуки.Может быть, это так просто, что все (кроме меня) знают, как это сделать!

Возможно ли это?

Ответы [ 10 ]

17 голосов
/ 28 февраля 2012

Я сделал это следующим образом. Я не уверен, что это правильный путь, но, похоже, он работает. Вам нужно установить плагин 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();.

Здесь измененный список содержит дубликаты файлов / имен, если он был зафиксирован более одного раза в текущем окне сборки.

5 голосов
/ 14 марта 2012
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 голосов
/ 25 сентября 2014

Использование плагина 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()
  }
}
4 голосов
/ 07 июня 2011

Сервер CI покажет вам список изменений, если вы запрашиваете изменения и используете обновление SVN.Однако вы, похоже, хотите изменить поведение сборки в зависимости от того, какие файлы были изменены.Я не думаю, что есть какой-либо из готовых способов сделать это с одним Дженкинсом.

Хук после фиксации - разумная идея.Вы можете параметризовать задание, и ваш скрипт-хук запускает сборку со значением параметра, установленным в соответствии с зафиксированными изменениями.Я не уверен, насколько это может быть сложно для вас.

Однако, вы можете разделить это на два отдельных задания - одно, выполняемое при каждом коммите, и отдельное для длительных тестов.что тебе не всегда нужно.Лично я предпочитаю поддерживать постоянное поведение на работе между казнями.В противном случае прослеживаемость страдает.

3 голосов
/ 03 апреля 2012

Вы можете использовать Jenkins API удаленного доступа , чтобы получить машиночитаемое описание текущей сборки, включая ее полный набор изменений. Тонкость здесь заключается в том, что если у вас настроен «тихий период», Jenkins может пакетировать несколько коммитов в один и тот же репозиторий в одну сборку, поэтому полагаться на один номер ревизии немного наивно.

Мне нравится сохранять свои простейшие хуки Subversion после фиксации и передавать их на CI-сервер. Для этого я использую wget для запуска сборки, что-то вроде этого ...

/usr/bin/wget --output-document "-" --timeout=2 \
    https://ci.example.com/jenkins/job/JOBID/build?token=MYTOKEN

Затем задание настраивается на стороне Jenkins для выполнения сценария Python, который использует переменную среды BUILD_URL и строит из этого URL-адрес для API. URL в конечном итоге выглядит так:

https://ci.example.com/jenkins/job/JOBID/BUILDID/api/json/

Вот пример кода Python, который можно запустить внутри сценария оболочки. Я упустил все средства обработки ошибок или 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']
2 голосов
/ 05 октября 2016
#!/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 ... таким образом, вы всегда можете инициировать при входе в репозиторий, но создавать при изменении файлов в интересующей папке.

Но ... Если вы хотите построить по требованию (например, нажав Build Now ) с изменением с последней сборки .. вы бы изменили _affected_files на:

_affected_files=`curl --silent $JOB_URL'lastSuccessfulBuild/api/json' | python -c "$python_func"`
2 голосов
/ 04 января 2013

Через 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> <% } %>
1 голос
/ 15 января 2018

С конвейерами 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
    }
  }
}

См. Как получить доступ к журналам изменений в конвейерном задании .

0 голосов
/ 19 июля 2018

Это просто, но у меня это работает:

$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
0 голосов
/ 28 сентября 2011

Примечание. Чтобы получить список изменений, вы должны использовать собственный SVN-клиент Jenkins. Выполнение этого на этапе сборки оболочки не приведет к перечислению изменений в сборке.

...