J'ai configuré Jenkins, mais j'aimerais savoir quels fichiers ont été ajoutés/modifiés entre la version actuelle et la version précédente. Je voudrais exécuter des tests longs selon que certaines parties de l'arborescence source ont été modifiées ou non.
Après avoir parcouru Internet, je ne trouve aucune mention de cette capacité dans Hudson/Jenkins bien que des suggestions aient été faites pour utiliser des hooks post-commit SVN. C'est peut-être si simple que tout le monde (sauf moi) sait comment le faire!
Est-ce possible?
Le serveur CI vous montrera la liste des modifications, si vous recherchez des modifications et utilisez la mise à jour SVN. Cependant, vous semblez vouloir changer le comportement de la construction en fonction des fichiers modifiés. Je ne pense pas qu'il existe un moyen original de le faire avec Jenkins seul.
Un hook post-commit est une idée raisonnable. Vous pouvez paramétrer le travail et demander à votre script de raccordement de lancer la génération avec la valeur de paramètre définie en fonction des modifications validées. Je ne sais pas à quel point cela pourrait être difficile pour vous.
Cependant, vous voudrez peut-être envisager de diviser cela en deux tâches distinctes - une qui s'exécute à chaque validation et une autre pour les tests de longue durée dont vous n'avez pas toujours besoin. Personnellement, je préfère garder un comportement professionnel cohérent entre les exécutions. Sinon, la traçabilité en souffre.
Je l'ai fait de la manière suivante. Je ne sais pas si c'est la bonne façon, mais cela semble fonctionner. Vous devez installer le plugin Jenkins Groovy et exécuter le script suivant.
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 () vous donne les changements. Depuis que j'utilise accurev, j'ai fait List<AccurevTransaction> accurevTransList = changeSet.getItems();
.
Ici, la liste modifiée contient des fichiers/noms en double si elle a été validée plus d'une fois au cours de la fenêtre de génération actuelle.
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`
En utilisant le plugin Build Flow et Git:
final changeSet = build.getChangeSet()
final changeSetIterator = changeSet.iterator()
while (changeSetIterator.hasNext()) {
final gitChangeSet = changeSetIterator.next()
for (final path : gitChangeSet.getPaths()) {
println path.getPath()
}
}
Vous pouvez utiliser Jenkins Remote Access API pour obtenir une description lisible par machine de la version actuelle, y compris son ensemble complet de modifications. La subtilité ici est que si vous avez configuré une `` période de silence '', Jenkins peut regrouper plusieurs validations dans le même référentiel dans une seule génération, donc se fier à un seul numéro de révision est un peu naïf.
J'aime garder mes hooks post-commit Subversion relativement simples et remettre les choses au serveur CI. Pour ce faire, j'utilise wget pour déclencher la construction, quelque chose comme ça ...
/usr/bin/wget --output-document "-" --timeout=2 \
https://ci.example.com/jenkins/job/JOBID/build?token=MYTOKEN
Le travail est ensuite configuré côté Jenkins pour exécuter un script Python qui exploite le BUILD_URL
variable d'environnement et construit l'URL de l'API à partir de cela. L'URL finit par ressembler à ceci:
https://ci.example.com/jenkins/job/JOBID/BUILDID/api/json/
Voici un exemple de code Python qui pourrait être exécuté à l'intérieur du script Shell. J'ai laissé de côté tout traitement d'erreur ou authentification HTTP pour garder les choses lisibles ici.
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']
#!/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;
C'est légèrement différent - j'avais besoin d'un script pour Git sur un dossier particulier ... Donc, j'ai écrit un chèque basé sur jollychang .
Il peut être ajouté directement au script shell exec du travail. Si aucun fichier n'est détecté, il exit 0
, c'est-à-dire SUCCESS
... de cette façon, vous pouvez toujours déclencher les archivages dans le référentiel, mais créer lorsque les fichiers du dossier d'intérêt changent.
Mais ... Si vous vouliez construire à la demande (c.-à-d. En cliquant sur Build Now ) avec la modification de la dernière build .. vous changeriez _affected_files
à:
_affected_files=`curl --silent $JOB_URL'lastSuccessfulBuild/api/json' | python -c "$python_func"`
Grâce à 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> <% } %>
Avec les pipelines Jenkins (pipeline prenant en charge le plugin 2.2 ou supérieur des API), cette solution fonctionne pour moi:
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
}
}
}
Voir Comment accéder aux journaux des modifications dans un travail de pipeline.
C'est simple, mais cela fonctionne pour moi:
$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
Remarque: Vous devez utiliser le propre client SVN de Jenkins pour obtenir une liste de modifications. Le faire via une étape de génération Shell ne répertoriera pas les modifications dans la génération.