2016-04-19 18 views
26

我想在詹金斯的所有版本中使用Jenkins文件,并且我有以下问题。 我们基本上是3种构建:Jenkinsfile和分支机构的不同策略

  • 拉请求建立 - 这将是合并后的代码审查掌握的,如果建筑工作
  • 手动拉请求构建 - 构建,做同样的以上,但可以由用户手动触发(例如,如果我们有一些不稳定的测试)
  • 最初的连续交付管道 - 这将构建代码,部署到存储库,从目标服务器上的存储库安装工件,并启动在那里应用

我应该如何将所有上述内容包含到单个Jenkins文件中。 现在我唯一的想法是做一个巨人,如果这将检查它是哪个分支并且将执行这些步骤。

所以我有两个问题:

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 

编辑:基于去除意见问题

+0

的可能的复制[詹金斯多枝管道:什么是分支名变量(http://stackoverflow.com/questions/32789619/jenkins-multibranch-pipeline-what-是分支名称变量) –

回答

5

1)我不知道这是否是合适的,但如果它解决您的问题,我认为是够恰当的。

2)为了知道分支的名称,你可以使用BRANCH_NAME变量,它的名字取自分支名称。

${env.BRANCH_NAME} 

下面是答案: Jenkins Multibranch pipeline: What is the branch name variable?

+10

其实它是'$ {env.BRANCH_NAME}' –

+0

是的,你是对的 –

0

的问题2你可以做

SH '混帐分支> GIT_BRANCH' 高清gitBranch = READFILE 'GIT_BRANCH'

因为你是从git退房

4

我们遵循使用的模型用于构建,根据需要对其进行调整,其中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() 
    } 
} 

注意:你可以找到我们的全球流水线库here的代码。

+0

我会说,这对我很有帮助,但为什么使用release.groovy文件包括在vars/...下的release.groovy的方法,并让它们全局访问而无需加载release.groovy?我只问,因为我即将走下一条类似的道路,我的'根'Jenkinsfile仅包含管道配置,由来自vars/...的方法包装,定义了整个构建,加载变量/ ...方法并根据需要提供全局库。这里的目标是让最终用户通过定义必要的配置并调用其构建类型来编写自己的Jenkins文件。 – user797963

+0

下面是一个链接,可以更好地解释我要做什么:https://jenkins.io/doc/book/pipeline/shared-libraries/#defining-a-more-structured-dsl。 Jenkinsfile将包含buildPlugin {}中的所有必要配置,buildPlugin.groovy文件将包含运行整个构建的多个阶段和步骤(不仅仅是链接中的简单示例)。 – user797963

+0

您当然可以将'release.groovy'中的代码推送到您的全局管道库中,但您应该避免出现这样的情况,即您的代码必须专用于旨在服务的库中的单个构建ALL构建。 – rbellamy

12

您可以添加如果多个阶段的语句,如果你想根据分支跳过多个阶段,如:

stage("Deploy"){ 
    if(env.BRANCH_NAME == 'master'){ 
    // Deploy steps here 
    } 
} 

if(env.BRANCH_NAME == 'master'){ 
    stage("Upload"){ 
     // Artifact repository upload steps here 
     } 
    stage("Deploy"){ 
     // Deploy steps here 
     } 
    } 

,或者你可以把它作为添加到各个阶段

+0

简单而优秀! – oblivion

0

不知道这是你想要的.. 我更喜欢,因为它看起来更有条理。

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