简体   繁体   English

Jenkins 多分支管道在不相关的分支上触发管道

[英]Jenkins multibranch pipeline triggers pipeline on unrelated branches

I have a problem with Jenkins multibranch pipleline using JenkinsFile and the GIT plugin.我在使用 JenkinsFile 和 GIT 插件时遇到了 Jenkins 多分支管道问题。

The problem is that every push to staging branch triggers the pipeline of master as well.问题是每次推送到暂存分支也会触发 master 的管道。 The desired behavior is that push to staging branch only triggers the pipleine for staging, and push to master branch only triggers the pipeline for master所需的行为是推送到登台分支仅触发用于登台的管道,而推送到主分支仅触发主管道

This is my JenkinsFile这是我的 JenkinsFile

#!/usr/bin/env bash
pipeline {
    agent any
    triggers {
        pollSCM('*/1 * * * *')
    }
    environment {
        GCLOUD_PATH="/var/jenkins_home/GoogleCloudSDK/google-cloud-sdk/bin"
    }
    stages {
        stage('Git Checkout'){
            steps{
              // Clean Workspace
              cleanWs()
              // Get source from Git
              git branch: 'staging', 
                credentialsId: ****', 
                url: 'git@github.com:***/****.git'
            }    
        }
        stage('Update Staging') {
            when {
                branch 'staging'
            }
            environment{
                INSTANCE="***"        
            }
            steps {
                sshagent(credentials : ['****']) {
                    sh 'ssh -tt -o StrictHostKeyChecking=no jenkins@"${INSTANCE}" sudo /opt/webapps/****/deploy.sh firstinstance'
                }
            }
        }
        stage('Update Production') {
            when {
                branch 'master'
            }
            environment{
                gzone="us-central1-a"
            }
            steps {
                    sh '''
                        #!/bin/bash
                        echo "${BRANCH_NAME}"
                        export instances=$("${GCLOUD_PATH}"/gcloud compute instances list --filter="status:(running) AND tags.items=web" --format="value(name)")
                        FIRST=1
                        for instance in ${instances}
                        do
                            echo "### Running Instance: ${instance} ###"
                            if [[ $FIRST == 1 ]]; then
                                echo "first instance"
                                ${GCLOUD_PATH}/gcloud compute ssh jenkins@${instance} --zone ${gzone} '--ssh-flag=-tt -i /root/.ssh/id_rsa -o StrictHostKeyChecking=no' --command="echo first"
                            else
                                ${GCLOUD_PATH}/gcloud compute ssh jenkins@${instance} --zone ${gzone} '--ssh-flag=-tt -i /root/.ssh/id_rsa -o StrictHostKeyChecking=no' --command="sudo uptime"
                            fi
                            FIRST=0
                        done
                    '''

            }
        }
    }
    post {
        success {
            cleanWs()
        }
    }

}

I'll share some logs: The is a log for master branch我将分享一些日志:这是 master 分支的日志

http://34.69.57.212:8080/job/tinytap-server/job/master/2/pollingLog/  returns
Started on Dec 10, 2019 1:42:00 PM
Using strategy: Specific revision
[poll] Last Built Revision: Revision 12ecdbc8d2f7e7ff1f578b135ea0b23a28d7672d (master)
using credential ccb9a735-04d9-4aab-8bab-5c86fe0f363c
 > git --version # timeout=10
using GIT_ASKPASS to set credentials 
 > git ls-remote -h -- https://github.com/tinytap/tinytap-web.git # timeout=10
Found 222 remote heads on https://github.com/tinytap/tinytap-web.git
[poll] Latest remote head revision on refs/heads/master is: 12ecdbc8d2f7e7ff1f578b135ea0b23a28d7672d - already built by 1
Using strategy: Default
[poll] Last Built Revision: Revision f693e358ce14bc5dfc6111e62ed88e6dd1d0dfc9 (refs/remotes/origin/staging)
using credential 17f45a89-da78-4969-b18f-cb270a526347
 > git --version # timeout=10
using GIT_SSH to set credentials jenkins key
 > git ls-remote -h -- git@github.com:tinytap/tinytap-web.git # timeout=10
Found 222 remote heads on git@github.com:tinytap/tinytap-web.git
[poll] Latest remote head revision on refs/heads/staging is: 907899a0e7e131e9416ee65aad041c8da111e2fe
Done. Took 1 sec 
Changes found 

The is a log for master branch, but only staging had a new commit :这是 master 分支的日志,但只有 staging 有一个新的提交:

http://34.69.57.212:8080/job/tt-server/job/master/3/pollingLog/    returns
Started on Dec 10, 2019 1:55:00 PM
Using strategy: Specific revision
[poll] Last Built Revision: Revision 12ecdbc8d2f7e7ff1f578b135ea0b23a28d7672d (master)
using credential ****-****-****-****-5c86fe0f363c
 > git --version # timeout=10
using GIT_ASKPASS to set credentials 
 > git ls-remote -h -- https://github.com/tt/tt-web.git # timeout=10
Found 222 remote heads on https://github.com/tt/tt-web.git
[poll] Latest remote head revision on refs/heads/master is: 12ecdbc8d2f7e7ff1f578b135ea0b23a28d7672d - already built by 2
Using strategy: Default
[poll] Last Built Revision: Revision 907899a0e7e131e9416ee65aad041c8da111e2fe (refs/remotes/origin/staging)
using credential ****-****-****-****-cb270a526347
 > git --version # timeout=10
using GIT_SSH to set credentials jenkins key
 > git ls-remote -h -- git@github.com:tt/tt-web.git # timeout=10
Found 222 remote heads on git@github.com:tt/tt-web.git
[poll] Latest remote head revision on refs/heads/staging is: eab6e8bc6d8586084e9fe9856dec7fd8b31dd098
Done. Took 0.98 sec 
Changes found 

Notice "changes found" even though head did not change on master branch即使主分支上的头部没有更改,请注意“发现更改”

Jenkins ver.詹金斯版。 2.190.1 Git plugin ver 4.0.0 Git client plugin ver 2.9.0 2.190.1 Git 插件 4.0.0 版 Git 客户端插件 2.9.0 版

I use this plugin - https://github.com/lachie83/jenkins-pipeline and it works fine for me.我使用这个插件 - https://github.com/lachie83/jenkins-pipeline ,它对我来说很好用。 You need to have separate if blocks for each branch and then the stage block inside it.每个分支都需要单独的 if 块,然后是其中的 stage 块。 Example below:下面的例子:

#!/usr/bin/groovy

@Library('https://github.com/lachie83/jenkins-pipeline@master')

def pipeline = new io.estrado.Pipeline()
def cloud = pipeline.getCloud(env.BRANCH_NAME)
def label = pipeline.getPodLabel(cloud)

// deploy only the staging branch
if (env.BRANCH_NAME == 'staging') {
    stage ('deploy to k8s staging') {
      //Deploy to staging
    }
}
// deploy only the master branch
if (env.BRANCH_NAME == 'master') {
    stage ('deploy to k8s production') {
      //Deploy to production
    }
}

I think you have some logical omissions in your Jenkinsfile.我认为您的 Jenkinsfile 中有一些逻辑上的遗漏。 As it currently stands, you poll SCM for changes.按照目前的情况,您可以轮询 SCM 以了解更改。 If any change is detected, first stage 'Git Checkout' will checkout staging branch (always).如果检测到任何更改,第一阶段“Git Checkout”将检出暂存分支(始终)。 Then you have another stage which does something if the branch is 'staging' (which it is, because it's hardcoded to checkout that branch above) etc. This will be the first thing to fix - if SCM changes are detected, checkout the right branch.然后你有另一个阶段,如果分支是“暂存”(它是这样,因为它是硬编码来检查上面的那个分支)等等。这将是首先要修复的 - 如果检测到 SCM 更改,检查正确的分支. How - there are a few options.如何 - 有几个选项。 I usually use 'skipDefaultCheckout()' in 'options' together with explicit checkout in my first pipeline stage:我通常在“选项”中使用“skipDefaultCheckout()”,并在我的第一个管道阶段使用显式结帐:

        steps {
            sshagent(['github-creds']) {
                git branch: "${env.BRANCH_NAME}", credentialsId: 'github-creds', url: 'git@github.com:x/y.git'
            }
        }

The second thing is that you try to squeeze handling two different branches into a single Jenkinsfile.第二件事是您尝试将两个不同的分支处理压缩到一个 Jenkinsfile 中。 This is not how it should be done.这不是应该做的。 Jenkins wil use Jenkinsfile from a given branch - just make sure Jenkinsfile on staging contains what you want it to contain, same with Jenkinsfile on master. Jenkins 将使用来自给定分支的 Jenkinsfile - 只需确保暂存上的 Jenkinsfile 包含您希望它包含的内容,与 master 上的 Jenkinsfile 相同。

Hope it helps.希望能帮助到你。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM