web-dev-qa-db-ja.com

Jenkins / Hudsonで最後のビルド以降に変更されたファイルのリストを取得する方法

Jenkinsをセットアップしましたが、現在のビルドと前のビルドの間に追加/変更されたファイルを確認したいと思います。ソースツリーの特定の部分が変更されたかどうかに応じて、いくつかの長期実行テストを実行したいと思います。

インターネットを精査しても、SVNポストコミットフックを使用するよう提案されましたが、Hudson/Jenkins内でこの機能について言及することはできません。たぶんそれはとても簡単なので、誰もが(私を除いて)それを行う方法を知っているでしょう!

これは可能ですか?

32
Allan

変更をポーリングしてSVN更新を使用している場合、CIサーバーは変更のリストを表示します。ただし、変更されたファイルに応じてビルドの動作を変更したいようです。ジェンキンスだけでそれを行うためのすぐに使える方法はないと思います。

コミット後のフックは合理的なアイデアです。ジョブをパラメーター化し、コミットされた変更に応じて設定されたパラメーター値を使用してフックスクリプトにビルドを起動させることができます。それがあなたにとってどれほど難しいのか分かりません。

ただし、これを2つの個別のジョブに分割することを検討することもできます。1つはコミットごとに実行され、もう1つは必ずしも必要ではない長時間実行されるテスト用です。個人的には、実行間でジョブの動作の一貫性を保つことを好みます。そうしないと、トレーサビリティが低下します。

4
Zac Thompson

私はそれを次の方法で行いました。それが正しい方法かどうかはわかりませんが、うまくいっているようです。 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();を実行しました。

ここで、現在のビルドウィンドウ中に複数回コミットされた場合、変更されたリストには重複したファイル/名前が含まれます。

18
Srini
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`
5
jollychang

ビルドフロープラグインと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
Noel Yap

Jenkins Remote Access 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環境変数を作成し、そこからAPIのURLを作成します。 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']
3
Joe Holloway
#!/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
hhony

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> <% } %>
2
Ankit

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

パイプラインジョブで変更ログにアクセスする方法を参照してください。

1
heroin

それは簡単ですが、これは私にとってはうまくいきます:

$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
Ashu

注:変更リストを取得するには、JenkinsのSVNクライアントを使用する必要があります。シェルビルドステップで実行しても、ビルドの変更はリストされません。

0
Edson Medina