Jenkinsfile и различные стратегии для веток
Я пытаюсь использовать файл Jenkins для всех наших сборок в Jenkins, и у меня возникла следующая проблема. У нас в основном есть 3 вида сборок:
- сборка по запросу - он будет объединен с мастером после проверки кода, и если сборка работает
- сборка по запросу вручную - сборка, которая выполняет те же действия, что и выше, но может быть запущена пользователем вручную (например, в случае нестабильного теста)
- начальный конвейер непрерывной доставки - он создаст код, развернет его в хранилище, установит артефакты из хранилища на целевом сервере и запустит там приложение
Как я должен содержать все вышеперечисленные сборки в один Jenkinsfile. Прямо сейчас единственная идея, которую я имею, состоит в том, чтобы создать гиганта, если он проверит, какая это ветвь и сделает шаги.
Итак, у меня есть два вопроса:
1. Это подходящий способ сделать это в Jenkinsfile?
- Как получить имя выполняемой в данный момент ветки в виде многоотраслевого задания?
Для справки, вот мой текущий Jenkinsfile
:
def servers = ['server1', 'server2']
def version = "1.0.0-${env.BUILD_ID}"
stage 'Build, UT, IT'
node {
checkout scm
env.PATH = "${tool 'Maven'}/bin:${env.PATH}"
withEnv(["PATH+MAVEN=${tool 'Maven'}/bin"]) {
sh "mvn -e org.codehaus.mojo:versions-maven-plugin:2.1:set -DnewVersion=$version -DgenerateBackupPoms=false"
sh 'mvn -e clean deploy'
sh 'mvn -e scm:tag'
}
}
def nodes = [:]
for (int i = 0; i < servers.size(); i++) {
def server = servers.get(i)
nodes["$server"] = {
stage "Deploy to INT ($server)"
node {
sshagent(['SOME-ID']) {
sh """
ssh ${server}.example.com <<END
hostname
/apps/stop.sh
yum -y update-to my-app.noarch
/apps/start.sh
END""".stripIndent()
}
}
}
}
parallel nodes
РЕДАКТИРОВАТЬ: удален вопрос, основанный на мнении
Ответы
Ответ 1
Вы можете добавить оператор If для нескольких этапов, если вы хотите пропустить несколько этапов в соответствии с ветвью, как в:
if(env.BRANCH_NAME == 'master'){
stage("Upload"){
// Artifact repository upload steps here
}
stage("Deploy"){
// Deploy steps here
}
}
или вы можете добавить его на отдельный этап, как в:
stage("Deploy"){
if(env.BRANCH_NAME == 'master'){
// Deploy steps here
}
}
Ответ 2
1) Я не знаю, подходит ли это, но если он разрешит вашу проблему, я думаю, что это достаточно уместно.
2) Чтобы узнать имя ветки, вы можете использовать переменную BRANCH_NAME, ее имя берется из имени ветки.
${env.BRANCH_NAME}
Вот ответ:
Jenkins Multibranch pip: Что такое переменная имени ветки?
Ответ 3
Мы следовали модели, используемой fabric8 для сборок, настраивая ее по мере необходимости, где Jenkinsfile
используется для определения логики обработки ветвления и развертывания, а также файл release.groovy
для логики сборки.
Вот как выглядит наш Jenkinsfile
для конвейера, который постоянно разворачивается в DEV из главной ветки:
#!groovy
import com.terradatum.jenkins.workflow.*
node {
wrap([$class: 'TimestamperBuildWrapper']) {
checkout scm
echo "branch: ${env.BRANCH_NAME}"
def pipeline = load "${pwd()}/release.groovy"
if (env.DEPLOY_ENV != null) {
if (env.DEPLOY_ENV.trim() == 'STAGE') {
setDisplayName(pipeline.staging() as Version)
} else if (env.DEPLOY_ENV.trim() == 'PROD') {
setDisplayName(pipeline.production() as Version)
}
} else if (env.BRANCH_NAME == 'master') {
try {
setDisplayName(pipeline.development() as Version)
} catch (Exception e) {
hipchatSend color: 'RED', failOnError: true, message: "<p>BUILD FAILED: </p><p>Check console output at <a href='${env.BUILD_URL}'>${env.JOB_NAME} [${env.BUILD_NUMBER}]</a></p><p><pre>${e.message}</pre></p>", notify: true, room: 'Aergo', v2enabled: false
throw e; // rethrow so the build is considered failed
}
} else {
setDisplayName(pipeline.other() as Version)
}
}
}
def setDisplayName(Version version) {
if (version) {
currentBuild.displayName = version.toString()
}
}
Примечание: вы можете найти код нашей глобальной конвейерной библиотеки здесь.
Ответ 4
на вопросы 2 вы можете сделать
sh 'git branch> GIT_BRANCH' def gitBranch = readFile 'GIT_BRANCH'
так как вы проверяете от мерзавца
Ответ 5
Не знаю, хотите ли вы этого.
Я предпочитаю, потому что он выглядит более структурированным.
Jenkinsfile
node {
def rootDir = pwd()
def branchName = ${env.BRANCH_NAME}
// Workaround for pipeline (not multibranches pipeline)
def branchName = getCurrentBranch()
echo 'BRANCH.. ' + branchName
load "${rootDir}@script/Jenkinsfile.${branchName}.Groovy"
}
def getCurrentBranch () {
return sh (
script: 'git rev-parse --abbrev-ref HEAD',
returnStdout: true
).trim()
}
Jenkinsfile. mybranch.Groovy
echo 'mybranch'
// Pipeline code here
Ответ 6
В моем сценарии мне нужно было запустить этап Deploy Artifactory, только если ветка была master (webhook Gitlab), иначе я не смог бы выполнить развертывание.
Ниже код моего jenkinsfile:
stages {
stage('Download'){
when{
environment name: 'gitlabSourceBranch', value: 'master'
}
steps{
echo "### Deploy Artifactory ###"
}
}
}
Ответ 7
Используя этот пост, это сработало для меня:
stage('...') {
when {
expression { env.BRANCH_NAME == 'master' }
}
steps {
...
}
}