web-dev-qa-db-ja.com

Jenkinsfileの別のブランチをチェックアウトすることは不可能ですか?

BitBucketには、masterdevelopの2つのブランチがあります。また、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/masterおよびOrigin/developが、何らかの理由で後者のみを出力します。

私は読み返して、これを行うためのあらゆる方法を考え出しました。たとえば、Jenkins用のSSHエージェントプラグインをインストールして、Jenkinsfileを次のように変更しました。

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の問題のようです。私は自分が望むものに似た何かをするフリースタイルの仕事をしていて、それはうまく機能しています。

12
Thomas Kåsene

数時間の試行錯誤の後、可能な解決策を思いつきました。マットの答えに部分的に基づいていますが、機能させるために変更する必要がありました。

マットは本質的に正しかった:checkout scmは単に必要なことを実行できるほど柔軟ではなかったため、GitSCMを使用してカスタマイズする必要がありました。主な関心点は次のとおりです。

  • 拡張されたLocalBranchを追加して、切り離されたHEADだけでなく、実際のブランチにチェックアウトするようにしました。
  • ワークスペース内のすべてを削除し、完全なクローンを強制するために、拡張子WipeWorkspaceを追加しました。私はこれが私の質問に対する解決策の一部ではないと思いますが、それはまだあると便利です。
  • リポジトリはプライベートであるため、credentialsIdプロパティを使用してSSH認証情報を指定しました。

何らかの理由で、checkoutステップが実行されると、ブランチのチェックアウトのみが行われ、リモートブランチを追跡するようには設定されません。よりエレガントなソリューションが見つかるまで、手動でこれを行う必要がありました。

すべて完了したら、通常のsh "git checkout master"そしてsh "git Push"、私がsshagentステップでそれらを囲んでいる限り。

結果として生成されるJenkinsfileの動作例を以下に追加しましたが、まだ初期段階にあるため、本番に近いものには使用しないでください。たとえば、ハードコーディングされたバージョン番号と、現在のブランチのチェックはありません。

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: '[email protected]:NAVFREG/jenkinsfile-tests.git']],
            doGenerateSubmoduleConfigurations: false
        ])
    }

    stage('Release') {
        // Preparing Git
        sh "git branch -u Origin/develop develop"
        sh "git config user.email \"[email protected]\""
        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"
        }
    }
}
15
Thomas Kåsene

Gitのクローン作成とプルのために作成されたJenkins Pipelineの組み込み関数を使用できます。また、ブランチを個別のディレクトリに複製することをお勧めします。

checkout([$class: 'GitSCM',
  branches: [[name: '*/branch_name']],
  doGenerateSubmoduleConfigurations: false,
  extensions: [[$class: 'RelativeTargetDirectory',
    relativeTargetDir: 'different_directory']],
  submoduleCfg: [],
  userRemoteConfigs: [[url: '[email protected]:org/repo.git']]])
5
Matt Schuchard

上記の2つの答えを得ることができませんでした。ブランチを指定して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

リモートフェッチ設定を変更し、デフォルトのcheckout scmトリガーされたジョブのJenkinsfileのステップ:

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

これはこの答えのおかげです https://stackoverflow.com/a/39986737/198888

これにより、ジェンキンスを GitSCMスクリプト承認 に設定する必要もなくなります。

3
swoop81

問題は、Jenkinsが、検出されたブランチのみでOriginを定義していることです。

@ swoop81の答えは機能していますが、1つのブランチだけをチェックアウトしたい場合は、このブランチのみをフェッチできます。

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>
1
D0m3