我在使用JenkinsFile和GIT插件的Jenkins多分支pipleline时遇到问题。
问题在于,每次对暂存分支的推动都会触发master的管道。 理想的行为是,推送到暂存分支只会触发pipleine进行暂存,而推送到master分支只会触发用于master的管道
这是我的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()
}
}
}
我将分享一些日志: 这是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
这是master分支的日志,但只有阶段进行了新的提交:
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
即使主分支上的head不变,也请注意“发现更改”
詹金斯版2.190.1 Git插件4.0.0版 Git客户端插件2.9.0版
答案 0 :(得分:2)
我使用此插件-https://github.com/lachie83/jenkins-pipeline,对我来说效果很好。您需要为每个分支有单独的if块,然后在其中有一个stage块。下面的示例:
#!/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
}
}
答案 1 :(得分:0)
我认为您在Jenkins文件中有一些逻辑上的遗漏。按照目前的情况,您可以轮询SCM进行更改。如果检测到任何更改,则第一阶段“ Git Checkout”将(始终)签出登台分支。然后,如果分支处于“暂存”状态(因为它已被硬编码以检出上面的分支)等,您将有另一个阶段进行操作。这将是首先要解决的问题-如果检测到SCM更改,则检出正确的分支。如何-有几种选择。我通常在第一个管道阶段在“选项”中同时使用“ skipDefaultCheckout()”和显式检出:
steps {
sshagent(['github-creds']) {
git branch: "${env.BRANCH_NAME}", credentialsId: 'github-creds', url: 'git@github.com:x/y.git'
}
}
第二件事是您尝试将两个不同的分支压缩到一个Jenkinsfile中。这不是应该怎么做。 Jenkins将使用给定分支中的Jenkinsfile-只需确保暂存中的Jenkinsfile包含您想要包含的内容,与master上的Jenkinsfile相同。
希望有帮助。