首页 文章

在Jenkinsfile中检查不同的分支是不可能的吗?

提问于
浏览
7

我在BitBucket上有两个分支: masterdevelop . 我还在Jenkins服务器上配置了BitBucket Team Folder作业来构建该存储库 . 在 develop 分支上有以下Jenkinsfile:

node {
    stage('Checkout') {
        checkout scm
    }

    stage('Try different branch') {
        sh "git branch -r"
        sh "git checkout master"
    }
}

当Jenkins运行它时,构建在尝试签出 master 时失败:

[Pipeline] stage
[Pipeline] { (Try different branch)
[Pipeline] sh
[e_jenkinsfile-tests_develop-4R65E2H6B73J3LB52BLACQOZLBJGN2QG22IPONX3CV46B764LAXA] Running shell script
+ git branch -r
  origin/develop
[Pipeline] sh
[e_jenkinsfile-tests_develop-4R65E2H6B73J3LB52BLACQOZLBJGN2QG22IPONX3CV46B764LAXA] Running shell script
+ git checkout master
error: pathspec 'master' did not match any file(s) known to git.
[Pipeline] }

我曾期望 git branch -r 命令打印出 origin/masterorigin/develop ,但由于某种原因它只打印后者 .

我已经阅读并试图想出任何方法来做到这一点:例如,我尝试为Jenkins安装SSH代理插件并将Jenkins文件更改为:

node {
    stage('Checkout') {
        checkout scm
    }

    stage('Try different branch') {
        sshagent(['Bitbucket']) {
            sh "git branch -r"
            sh "git checkout master"
        }
    }
}

但它似乎仍未找到 origin/master . 更糟糕的是,SSH代理似乎在尝试签出 master 之前被杀死:

[Pipeline] { (Try different branch)
[Pipeline] sshagent
[ssh-agent] Using credentials ThomasKasene (Used to communicate with Bitbucket)
[ssh-agent] Looking for ssh-agent implementation...
[ssh-agent]   Exec ssh-agent (binary ssh-agent on a remote machine)
$ ssh-agent
SSH_AUTH_SOCK=/tmp/ssh-M6pIguCUpAV4/agent.11899
SSH_AGENT_PID=11902
$ ssh-add /var/jenkins_home/workspace/e_jenkinsfile-tests_develop-4R65E2H6B73J3LB52BLACQOZLBJGN2QG22IPONX3CV46B764LAXA@tmp/private_key_2394129657382526146.key
Identity added: /var/jenkins_home/workspace/e_jenkinsfile-tests_develop-4R65E2H6B73J3LB52BLACQOZLBJGN2QG22IPONX3CV46B764LAXA@tmp/private_key_2394129657382526146.key (/var/jenkins_home/workspace/e_jenkinsfile-tests_develop-4R65E2H6B73J3LB52BLACQOZLBJGN2QG22IPONX3CV46B764LAXA@tmp/private_key_2394129657382526146.key)
[ssh-agent] Started.
[Pipeline] {
[Pipeline] sh
[e_jenkinsfile-tests_develop-4R65E2H6B73J3LB52BLACQOZLBJGN2QG22IPONX3CV46B764LAXA] Running shell script
+ git branch -r
  origin/develop
[Pipeline] sh
$ ssh-agent -k
unset SSH_AUTH_SOCK;
unset SSH_AGENT_PID;
echo Agent pid 11902 killed;
[ssh-agent] Stopped.
[e_jenkinsfile-tests_develop-4R65E2H6B73J3LB52BLACQOZLBJGN2QG22IPONX3CV46B764LAXA] Running shell script
+ git checkout master
error: pathspec 'master' did not match any file(s) known to git.
[Pipeline] }

我最终的计划是将某些东西提交给 develop ,然后将其合并到 master 中,但到目前为止,我的运气很少 . 有没有人有可能的解决方案或解决方法?

PS:这似乎只是Jenkinsfile中的一个问题;我有一个类似于我想要的自由式工作,它工作正常 .

4 回答

  • 0

    您可以使用为Git克隆和拉动创建的Jenkins管道中的内部函数 . 我还建议将分支克隆到单独的目录中 .

    checkout([$class: 'GitSCM',
      branches: [[name: '*/branch_name']],
      doGenerateSubmoduleConfigurations: false,
      extensions: [[$class: 'RelativeTargetDirectory',
        relativeTargetDir: 'different_directory']],
      submoduleCfg: [],
      userRemoteConfigs: [[url: 'git@github.domain:org/repo.git']]])
    
  • 2

    经过几个小时的反复试验,我想出了一个可能的解决方案 . 它部分 Build 在马特的答案上,但我不得不改变它以使其发挥作用 .

    Matt在要点中是正确的: checkout scm 只是不够灵活,不能让我做我需要的东西,所以我不得不使用 GitSCM 来定制它 . 主要兴趣点是:

    • 添加了扩展名 LocalBranch 以确保我签出了一个实际的分支,而不仅仅是一个分离的 HEAD .

    • 添加了扩展名 WipeWorkspace 以删除工作区中的所有内容并强制完全克隆 . 我不认为这是我的问题解决方案的一部分,但它仍然很方便 .

    • 使用 credentialsId 属性指定SSH凭据,因为存储库是私有的 .

    无论出于何种原因,当执行 checkout 步骤时,它仅检出分支,但不将其设置为跟踪远程分支 . 在找到更优雅的解决方案之前,我必须手动执行此操作 .

    完成所有这些后,我可以使用常规 sh "git checkout master" 甚至 sh "git push" ,只要我将它们包含在 sshagent 步骤中 .

    我在下面添加了一个结果Jenkins文件的工作示例,但请记住,它不应该用于任何接近 生产环境 的东西,因为它仍处于起步阶段;例如,硬编码的版本号并且不检查您所在的分支 .

    node {
        mvnHome = tool 'Maven'
        mvn = "${mvnHome}/bin/mvn"
    
        stage('Checkout') {
            checkout([
                $class: 'GitSCM',
                branches: scm.branches,
                extensions: scm.extensions + [[$class: 'LocalBranch'], [$class: 'WipeWorkspace']],
                userRemoteConfigs: [[credentialsId: 'Bitbucket', url: 'git@bitbucket.org:NAVFREG/jenkinsfile-tests.git']],
                doGenerateSubmoduleConfigurations: false
            ])
        }
    
        stage('Release') {
            // Preparing Git
            sh "git branch -u origin/develop develop"
            sh "git config user.email \"jenkins@thomaskasene.com\""
            sh "git config user.name \"Jenkins\""
    
            // Making and committing new verison
            sh "${mvn} versions:set -DnewVersion=2.0.0 -DgenerateBackupPoms=false"
            sh "git commit -am \"Released version 2.0.0\""
    
            // Merging new version into master
            sh "git checkout master"
            sh "git merge develop"
            sh "git checkout develop"
    
            // Making and committing new snapshot version
            sh "${mvn} versions:set -DnewVersion=3.0.0-SNAPSHOT -DgenerateBackupPoms=false"
            sh "git commit -am \"Made new snapshot version 3.0.0-SNAPSHOT\""
    
            // Pushing everything to remote repository
            sshagent(['Bitbucket']) {
                sh "git push"
                sh "git checkout master"
                sh "git push"
            }
        }
    }
    
  • 4

    我无法得到上面的两个答案 . 我通过指定一个分支来触发Jenkins管道作业,并试图检查失败的作业中的另一个分支(开发):

    error: pathspec 'develop' did not match any file(s) known to git.
    

    我可以在失败的工作中看到这一点,这表明只提取了触发分支:

    git fetch --no-tags --progress https://<github URL> +refs/heads/branch-name:refs/remotes/origin/branch-name
    

    我通过更改远程获取配置并通过在触发的作业的Jenkinsfile中执行默认的 checkout scm 步骤后执行以下操作来获取所有分支:

    sh """
        git config remote.origin.fetch '+refs/heads/*:refs/remotes/origin/*'
        git fetch --all
    """
    

    这要归功于这个答案https://stackoverflow.com/a/39986737/1988883

    这也避免了必须为GitSCM script approvals配置Jenkins,我必须这样做才能尝试上面的两个解决方案

  • 3

    问题是Jenkins只用发现的分支定义了 origin .

    @swoop81回答是有效的,但如果您只想结帐一个分支,则只能获取此分支 .

    git config --add remote.origin.fetch +refs/heads/<branch-name>:refs/remotes/origin/<branch-name>
    git fetch --no-tags https://<github-url> +refs/heads/<branch-name>:refs/remotes/origin/<branch-name>
    

相关问题