自Jenkins / Hudson上次构建以来如何获取已更改文件的列表

时间:2011-06-07 03:43:27

标签: hudson jenkins

我已经设置了Jenkins,但我想知道在当前版本和之前版本之间添加/更改了哪些文件。我想运行一些长时间运行的测试,具体取决于源树的某些部分是否已更改。

在浏览过互联网之后,我发现在Hudson / Jenkins中没有提到这种能力,尽管建议使用SVN后提交钩子。也许这很简单,每个人(除了我)都知道怎么做!

这可能吗?

10 个答案:

答案 0 :(得分:16)

我是按照以下方式完成的。我不确定这是否是正确的方法,但似乎有效。您需要安装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();

此处,修改后的列表包含重复的文件/名称,如果它在当前构建窗口中已多次提交。

答案 1 :(得分:5)

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`

答案 2 :(得分:4)

如果要轮询更改并使用SVN更新,CI服务器将显示更改列表。但是,您似乎希望根据修改的文件来更改构建的行为。我不认为只有詹金斯才能做到这一点。

提交后挂钩是一个合理的想法。您可以参数化作业,并让您的钩子脚本根据提交的更改使用参数值设置启动构建。我不确定对你来说有多难。

但是,您可能需要考虑将其拆分为两个单独的作业 - 一个在每次提交时运行,另一个用于您并不总是需要的长时间运行的测试。就个人而言,我更喜欢在执行之间保持一致的工作行为。否则可追溯性会受到影响。

答案 3 :(得分: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()
  }
}

答案 4 :(得分:3)

您可以使用Jenkins Remote Access API获取当前版本的机器可读描述,包括其完整更改集。这里的细微之处在于,如果您配置了“静默期”,Jenkins可能会将多个提交批处理到同一个存储库中,因此依赖单个修订版号有点天真。

我喜欢让我的Subversion post-commit挂钩相对简单,并将其移交给CI服务器。为此,我使用wget来触发构建,就像这样......

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

然后在Jenkins端配置作业以执行利用BUILD_URL环境变量的Python脚本,并从中构造API的URL。 URL最终看起来像这样:

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

这是一些可以在shell脚本中运行的示例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']

答案 5 :(得分:2)

#!/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 shell脚本中。如果没有检测到文件,它将exit 0,即SUCCESS ...这样你就可以在签到存储库时触发,但是在感兴趣的文件夹中的文件发生变化时进行构建。

但是......如果您想按照上一次构建中的更改来按需构建(即点击立即构建),您可以将_affected_files更改为:

_affected_files=`curl --silent $JOB_URL'lastSuccessfulBuild/api/json' | python -c "$python_func"`

答案 6 :(得分:1)

使用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
    }
  }
}

请参阅 How to access changelogs in a pipeline job

答案 7 :(得分:0)

注意:您必须使用Jenkins自己的SVN客户端来获取更改列表。通过shell构建步骤执行此操作不会列出构建中的更改。

答案 8 :(得分:0)

很简单,但这对我有用:

$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

答案 9 :(得分:0)

我尝试将其添加到注释中,但注释中的代码为no way

只想从heroin的答案中美化代码:

def changedFiles = []
def changeLogSets = currentBuild.changeSets
for (entries in changeLogSets) {
    for (entry in entries) {
        for (file in entry.affectedFiles) {
            echo "Found changed file: ${file.path}"
            changedFiles += "${file.path}"
        }
    }
}

在某些情况下请注意git插件返回空的changeSet,例如:

  • 首先在新创建的分支中运行
  • “立即构建”按钮构建

有关更多详细信息,请参见https://issues.jenkins-ci.org/browse/JENKINS-26354