Подтвердить что ты не робот

Jenkinsfile и различные стратегии для веток

Я пытаюсь использовать файл Jenkins для всех наших сборок в Jenkins, и у меня возникла следующая проблема. У нас в основном есть 3 вида сборок:

  • сборка по запросу - он будет объединен с мастером после проверки кода, и если сборка работает
  • сборка по запросу вручную - сборка, которая выполняет те же действия, что и выше, но может быть запущена пользователем вручную (например, в случае нестабильного теста)
  • начальный конвейер непрерывной доставки - он создаст код, развернет его в хранилище, установит артефакты из хранилища на целевом сервере и запустит там приложение

Как я должен содержать все вышеперечисленные сборки в один Jenkinsfile. Прямо сейчас единственная идея, которую я имею, состоит в том, чтобы создать гиганта, если он проверит, какая это ветвь и сделает шаги.

Итак, у меня есть два вопроса:

1. Это подходящий способ сделать это в Jenkinsfile?

  1. Как получить имя выполняемой в данный момент ветки в виде многоотраслевого задания?

Для справки, вот мой текущий 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

РЕДАКТИРОВАТЬ: удален вопрос, основанный на мнении

4b9b3361

Ответ 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 {
                ...
            }
        }