web-dev-qa-db-fra.com

Comment déclencher une construction uniquement si des modifications sont apportées à un ensemble de fichiers particulier

Comment dire à Jenkins/Hudson de déclencher une construction uniquement pour les modifications apportées à un projet particulier dans mon arbre Git?

76
xavier.seignard

Le plugin Git a une option (région exclue) pour utiliser des expressions rationnelles afin de déterminer si la construction doit être ignorée en fonction du fait que les fichiers de la validation correspondent ou non à l'expression régulière de la région exclue.

Malheureusement, le plugin Git n'a pas de fonctionnalité "région incluse" pour le moment (1.15). Cependant, quelqu'un a publié sur GitHub des correctifs qui fonctionnent sur Jenkins et Hudson et qui implémentent la fonctionnalité souhaitée.

C'est un peu difficile à construire, mais cela fonctionne comme annoncé et a été extrêmement utile car l'un de mes arbres Git a plusieurs projets indépendants.

https://github.com/jenkinsci/git-plugin/pull/49

Mise à jour: Le plugin Git (1.16) a maintenant la fonctionnalité de région "incluse".

61
Aaron Kushner

En gros, vous avez besoin de deux emplois. Un pour vérifier si les fichiers ont changé et un pour faire la construction réelle:

Travail n ° 1

Cela devrait être déclenché lors de modifications dans votre référentiel Git. Il vérifie ensuite si le chemin que vous spécifiez ("src" ici) a été modifié, puis utilise CLI de Jenkins pour déclencher un second travail.

export JENKINS_CLI="Java -jar /var/run/jenkins/war/WEB-INF/jenkins-cli.jar"
export JENKINS_URL=http://localhost:8080/
export GIT_REVISION=`git rev-parse HEAD`
export STATUSFILE=$WORKSPACE/status_$BUILD_ID.txt

# Figure out, whether "src" has changed in the last commit
git diff-tree --name-only HEAD | grep src

# Exit with success if it didn't
$? || exit 0

# Trigger second job
$JENKINS_CLI build job2 -p GIT_REVISION=$GIT_REVISION -s

Travail n ° 2

Configurez ce travail pour prendre un paramètre GIT_REVISION comme suit, afin de vous assurer de générer exactement la révision que le premier travail a choisi de générer.

Parameterized build string parameterParameterized build Git checkout

32
peritus

Bien que cela n'affecte pas les travaux individuels, vous pouvez utiliser ce script pour ignorer certaines étapes si la dernière validation ne contenait aucune modification:

/*
 * Check a folder if changed in the latest commit.
 * Returns true if changed, or false if no changes.
 */
def checkFolderForDiffs(path) {
    try {
        // git diff will return 1 for changes (failure) which is caught in catch, or
        // 0 meaning no changes 
        sh "git diff --quiet --exit-code HEAD~1..HEAD ${path}"
        return false
    } catch (err) {
        return true
    }
}

if ( checkFolderForDiffs('api/') ) {
    //API folder changed, run steps here
}
5
FrankerZ

Si la logique de sélection des fichiers n’est pas anodine, je déclencherais l’exécution du script à chaque modification, puis rédigerais un script pour vérifier si une construction était effectivement nécessaire, puis le déclencher si c’était le cas.

2
Uri Cohen

Vous pouvez utiliser plugin générique Webhook Trigger pour cela.

Avec une variable comme changed_files et expression $.commits[*].['modified','added','removed'][*].

Vous pouvez avoir un texte de filtre comme $changed_files et filtre l'expression rationnelle comme "folder/subfolder/[^"]+?" si folder/subfolder est le dossier qui doit déclencher les générations.

1
Tomas Bjerre

J'ai répondu à cette question dans un autre post:

Comment obtenir la liste des fichiers modifiés depuis la dernière construction dans Jenkins/Hudson

#!/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;

Vous pouvez ajouter le contrôle directement en haut de l'exécutif du shell du travail, et il sera exit 0 si aucune modification n'est détectée ... Par conséquent, vous pouvez toujours interroger le niveau supérieur de l'archivage pour déclencher une construction.

1
hhony