Como faço para dizer ao Jenkins / Hudson para acionar uma construção apenas para mudanças em um projeto específico em minha árvore Git?
Como faço para dizer ao Jenkins / Hudson para acionar uma construção apenas para mudanças em um projeto específico em minha árvore Git?
Respostas:
O plugin Git tem uma opção (região excluída) para usar regexes para determinar se deve pular a construção com base em se os arquivos no commit correspondem ao regex da região excluída.
Infelizmente, o plugin Git padrão não tem um recurso de "região incluída" no momento (1.15). No entanto, alguém postou patches no GitHub que funcionam no Jenkins e no Hudson e implementam o recurso que você deseja.
É um pouco trabalhoso de construir, mas funciona como anunciado e tem sido extremamente útil, pois uma das minhas árvores Git tem vários projetos independentes.
https://github.com/jenkinsci/git-plugin/pull/49
Atualização: O plugin Git (1.16) agora tem o recurso de região 'incluído'.
Ignored commit c6e2b1dca0d1885: No paths matched included region whitelist
. Qualquer pista? Mais detalhes aqui: stackoverflow.com/questions/47439042/…
Basicamente, você precisa de dois empregos. Um para verificar se os arquivos foram alterados e outro para fazer a compilação real:
Trabalho # 1
Isso deve ser acionado em mudanças em seu repositório Git. Em seguida, testa se o caminho que você especifica ("src" aqui) tem alterações e usa a CLI do Jenkins para acionar um segundo trabalho.
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
Trabalho # 2
Configure este trabalho para receber um parâmetro GIT_REVISION como este, para ter certeza de que está construindo exatamente a revisão que o primeiro trabalho escolheu construir.
$? || exit 0
... test $? -eq 0 || exit 0
talvez?
Se você estiver usando uma sintaxe declarativa de Jenkinsfile para descrever o pipeline de construção, poderá usar a condição do changeset para limitar a execução do estágio apenas para o caso em que arquivos específicos são alterados. Este agora é um recurso padrão do Jenkins e não requer nenhuma configuração / software adicional.
stages {
stage('Nginx') {
when { changeset "nginx/*"}
steps {
sh "make build-nginx"
sh "make start-nginx"
}
}
}
Você pode combinar várias condições usando anyOf
ou allOf
palavras - chave para comportamento OR ou AND de acordo:
when {
anyOf {
changeset "nginx/**"
changeset "fluent-bit/**"
}
}
steps {
sh "make build-nginx"
sh "make start-nginx"
}
Embora isso não afete jobs individuais, você pode usar este script para ignorar certas etapas se o commit mais recente não contiver nenhuma alteração:
/*
* 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
}
api/
pasta.) Se você pudesse corrigir isso, eu adoraria uma alteração sugerida !
Você pode usar o plug-in do acionador do Webhook genérico para isso.
Com uma variável like changed_files
e expression $.commits[*].['modified','added','removed'][*]
.
Você pode ter um texto de filtro $changed_files
e um regexp de filtro como "folder/subfolder/[^"]+?"
se folder/subfolder
for a pasta que deve acionar as compilações.
Eu respondi a essa pergunta em outro post:
Como obter uma lista de arquivos alterados desde a última compilação no 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;
Você pode adicionar a verificação diretamente ao topo do shell exec da tarefa, e isso acontecerá exit 0
se nenhuma alteração for detectada ... Portanto, você sempre pode pesquisar o nível superior para verificações para acionar uma compilação.
Escrevi este script para pular ou executar testes se houver alterações:
#!/bin/bash
set -e -o pipefail -u
paths=()
while [ "$1" != "--" ]; do
paths+=( "$1" ); shift
done
shift
if git diff --quiet --exit-code "${BASE_BRANCH:-origin/master}"..HEAD ${paths[@]}; then
echo "No changes in ${paths[@]}, skipping $@..." 1>&2
exit 0
fi
echo "Changes found in ${paths[@]}, running $@..." 1>&2
exec "$@"
Então você pode fazer algo como:
./scripts/git-run-if-changed.sh cmd vendor go.mod go.sum fixtures/ tools/ -- go test