web-dev-qa-db-ja.com

Jenkinsマルチブランチパイプラインジョブで1つのディレクトリのみを構築するにはどうすればよいですか?

2つのサブディレクトリProject1、Project2を持つmultibranch-testというgithubリポジトリがあります。

PS C:\Repos\multibranch-test> tree . Folder PATH listing for volume Windows Volume serial number is 2085-6D3D C:\REPOS\MULTIBRANCH-TEST ├───Project1 └───Project2

各サブディレクトリには、Jenkinsfileとそのプロジェクトのコードがあります。

Jenkinsには、Project1用とProject2用の2つのマルチブランチパイプラインジョブがあります。 Project1の構成で、Project2のサブディレクトリにコミットがプッシュされた場合にProject1をビルドするためのプッシュ通知またはポーリングは必要ありません。

したがって、Project1では、追加の動作を構成しました。

  • 高度なクローンの動作:浅いクローンがチェックされます
  • スパースチェックアウトパスはProject1#に設定されます
  • ポーリングは特定のパスのコミットを無視します
    • 含まれる地域: Project1/*
    • 除外地域: *
  • ビルド構成:スクリプトパス:Project1/Jenkinsfile

何が起こっているのかというと、サブディレクトリProject2のmasterにコミットをプッシュすると、Project1とProject2の両方のジョブがビルドされます。 Project2だけをビルドしたい。誰かが私が間違っていることを指摘できますか?

両方のプロジェクトのJenkinsfilesは類似しており、次のようになります。

#!groovy
node  {
    stage ('checkout') {
        checkout scm
    }

    stage ('build') {
        dir ('Project1') {
            bat 'powershell -Command gci'
            bat 'powershell -Command gci env:'
            bat 'powershell -File .\\Project1.ps1'
        }
    }
10
Mark Allison

これは私たちにとって大きな問題でしたが、いくつかの回避策で解決することができました。

GitHubコミットフックによってトリガーされるマスターJenkinsジョブがあります。最後のコミット以降に何が変更されたかを把握し、他のサービス固有のJenkinsジョブをトリガーします。

ここで指定されていない他のいくつかの規則(サービス、ディレクトリ、Jenkinsジョブの命名規則など)がありますが、これが誰かの助けになることを願っています。

ソリューションの各コンポーネントの内訳は次のとおりです。

  1. モノリポジトリ内の各サービスのJenkinsジョブと対応するJenkinsファイル。

C:\REPOS\MULTIBRANCH-TEST\Project1\Jenkinsfile(ここにビルドロジック)C:\REPOS\MULTIBRANCH-TEST\Project2\Jenkinsfile(ここにビルドロジック)

  1. 前回のコミット以降に変更されたもののリストを取得するシェルスクリプト( このブログ投稿 から採用)。

C:\REPOS\MULTIBRANCH-TEST\change-sets.sh

    #!/usr/bin/env bash

    changeSets=(`git diff-tree --name-status HEAD`)
    for(( i=0; i<${#changeSets[@]}; i++))
    do
      if [ ${changeSets[$i]} == "M" ]
      then
        echo ${changeSets[$i+1]}
      fi
    done
  1. GitHubコミットフックに基づいて構築されたJenkinsジョブ

C:\REPOS\MULTIBRANCH-TEST\Jenkinsfile

    #!/usr/bin/env groovy

    pipeline {
        agent any

        stages {

            stage('Define Services to Build') {
                steps {
                    script {

                        def SERVICES_TO_BUILD = sh script:"./change-sets.sh", returnStdout: true
                        SERVICES_TO_BUILD.split("\n").each {
                            echo "Triggering build for ${it}"
                            try {
                                build job: "${it}", propagate: false, wait: false
                            } catch (ex) {
                                echo "Failed to trigger build for ${it}: ${ex.message}"
                            }

                        }
                    }
                }
            }
        }
    }
12
Garrett Clyde

デフォルトのJenkinsの動作では、レポジトリがコミットを取得するとプロジェクトが再ビルドされるため、レポジトリでのコミットにより、両方のJenkinsプロジェクトのイベントが生成され、両方のビルドがトリガーされます。 Jenkinsのドキュメントをご覧ください: https://jenkins.io/doc/book/pipeline/

Jenkinsの観点からは、変更がプロジェクト1と2のどちらに行われたかを判断するのは困難です。すぐに表示されるのは、「監視対象リポジトリへの新しいコミット」です。

簡単な解決策は、リポジトリをプロジェクトごとに1つずつ2つの別々のリポジトリに分割することです。それらは別々に構築されることになっているので、それは問題ではないはずです。

1
stmi

リポジトリ全体のジョブを作成して、コミットによってもたらされた変更を確認し、プロジェクト1または2、あるいはその両方の対応するJenkinsfileをトリガーすることができます。

0
genmad