web-dev-qa-db-ja.com

Jenkinsビルドで使用するgitブランチを動的に選択する方法

Jenkinsビルドサーバーの新しいプロジェクト構成を作成しようとしています。私がやろうとしていることを単純化するために、2つのコンポーネントのみを使用して問題を説明します。

コンポーネントA

  • このコンポーネントを変更すると、CIサーバーでこのプロジェクトのビルドがトリガーされます。
  • CIサーバーには、変更とビルドを監視するためにブランチが静的に構成されています。例えば。マスターまたは開発ブランチ。
  • このコンポーネントには、依存するComponentBの必要なバージョンを含む構成ファイルが含まれています。

コンポーネントB

  • このコンポーネントへの変更は、CIサーバーでのこのプロジェクトのビルドをトリガーしません(ComponentBの開発をカバーする別のプロジェクトがあります)。
  • コンポーネントの個々のバージョンにタグが付けられます
  • ComponentAの構成ファイルには、ComponentBの必要なバージョンがあります
  • CIサーバーは、ComponentAの構成ファイルが何らかの方法で解析されるまで、チェックアウトするブランチ(タグ)を認識しません。

ジェンキンスでこれを達成する正しい方法は何ですか?構成ファイルを解析し、Gitプラグインを作成してComponentBの期待されるバージョンに基づいてブランチをチェックアウトするというこの動的な動作を追加する方法を見つけようとしていましたが、今のところ手がかりがありません。

次のステップでは、構成ファイルにワイルドカード(5.3。*など)を含めることもできます。そのため、ワイルドカードに一致する最新のComponentBのタグを見つける必要があります。

編集

今、私は問題をあまりにも単純化しすぎていることがわかり、単純化のために、主な制限はもはや存在しません。

主な制限は、コンポーネントAとBを一緒にビルドする必要があることです。 1つの実行可能ファイル/ライブラリを形成し、ビルドスクリプトには両方のコンポーネントのソースファイルが必要なので、個別にビルドすることはできません。

なぜこのような奇妙な構成なのかと尋ねたら、コンポーネントAとBに説明を加えましょう。

  • ComponentA:ネイティブプラットフォーム固有のコード
  • ComponentB:プラットフォームに依存しないネイティブコード

コンポーネントAsは多数ある場合があります-各プラットフォームに1つですが、コンポーネントBは1つだけです。特定のAをBにマージすると、単一プラットフォームの完全なソースコードが生成されますが、すべてのプラットフォームがBの最新バージョンに更新されるわけではないため、制御が必要ですビルドに使用するBのバージョン。

22
Ladislav Mrnka

目的を達成するための1つのオプションは、次のセットアップを使用することです。

2つのJenkinsジョブを作成します。

  • 「コンポーネントA」(SCMの変更時に自動的にトリガーされます)
  • 「コンポーネントB」(「手動」トリガー)

ステップ1

「コンポーネントB」のbranchbuild parameter を定義します。

enter image description here

このパラメーターを「Git Plugin」ブランチ指定子として使用します。

enter image description here

これで、適切なブランチ(タグ)パラメーターを指定することにより、手動で「コンポーネントB」ビルドをトリガーできるようになります。 tags/5.3.0

ステップ2

新しい「実行シェル」ビルドステップを「コンポーネントA」ビルドに追加します。これにより、ワークスペースの構成ファイルから「コンポーネントB」バージョンが抽出され、「コンポーネントB」ビルドパラメータでb.propertiesファイルが準備されます。 。

enter image description here

Parameterized Trigger Jenkinsプラグインをインストールし、新しい「Trigger/call builds on other projects」ビルドステップを「Component A」ジョブに追加します。

enter image description here

b.propertiesファイルをビルドパラメーターのソースとして使用します。

これで、「コンポーネントA」が再ビルドされるたびに、ターゲットのブランチ/タグをビルドパラメーターとして、新しい「コンポーネントB」ビルドがトリガーされます。

ワイルドカードサポートの追加

ワイルドカードバージョンをサポートする場合は、git ls-remoteコマンドを使用して、次のような最新のタグを見つけることができます。

#B=$(obtain B version from the config file in a usual way)   

LATEST=$(\
    git ls-remote --tags YOUR_REPOSITORY_URL "$B"\
    |cut -d / -f3|sort -r --version-sort|head -1\
)

cat <<EOF > b.properties
    branch=tags/$LATEST
EOF

これにより、リモートの「コンポーネントB」リポジトリにある「B」バージョンパターンに一致するすべてのタグがリストされ、LATEST変数に最新のバージョン番号が保存されます。

これを「コンポーネントA」ジョブの「シェルを実行」ステップに追加すると、次のようなバージョン番号パターンを処理できるはずです:5.3.*

問題は、シェルスクリプトがJenkinsデーモンユーザーとして実行されるため、リモートGitリポジトリにアクセスするために適切な資格情報を設定する必要があることです(たとえば、ssh pubkey経由)。

または、 Credentials Binding Plugin を調べて、Jenkins自体に保存されているGit資格情報を再利用することもできます。

Jenkins 2.0スタイルパイプラインの使用

また、Jenkins 2.0スタイル Pipeline を使用して、手元のタスクを解決することもできます。これにより、コンポーネントAとBのコードを単一のワークスペースにチェックアウトし、一般的なビルドステップを適用できます。彼らへ。

パイプラインは次のようになります。

node {

   //Settings
   def credentialsId = '8fd28e34-b04e-4bc5-874a-87f4c0e05a03'    
   def repositoryA = 'ssh://[email protected]/projects/a.git'
   def repositoryB = 'ssh://[email protected]/projects/b.git'

   stage('Checkout component A') {
      git credentialsId: credentialsId , 
      url: repositoryA , branch : "master"
   }

   stage("Resolve and checkout component B") {
      def deps = readProperties file: 'meta.properties'
      echo "Resolved B version = ${deps['b']}"

      dir("module/b") {
           //Clone/Fetch Component B 
           checkout scm:[
                $class: 'GitSCM', 
                userRemoteConfigs: [[url: repositoryB, credentialsId: credentialsId]], 
                branches: [[name: 'refs/tags/*']]
           ], 
           changelog: false, poll: false

           //Checkout the tag, matching deps['b'] pattern     
           sshagent([credentialsId]) {
                sh "git checkout \$(git tag -l \"${deps['b']}\" |sort -r --version-sort|head -1)"
           }
      }
   }

   stage("Build A+B") {
        //Apply a common build step
   }

}

ここでは、 Pipeline Utility Steps Plugin の一部である "readProperties"コマンドを使用して、meta.propertiesから "Component B"バージョンパターンを抽出します。 readYaml、readJSONコマンドも利用できます。

次に、changelog: false, poll: falseフラグを使用して "コンポーネントB"をフェッチ/クローンし、SCMポーリングに登録されないようにして、現在のワークスペースの "module/b"フォルダーに入れます。

次に、シェルコマンドを呼び出して、上記で取得したバージョンパターンに基づいてタグを選択し、チェックアウトします(5.3。*スタイルのワイルドカードも機能するはずです)。

sh呼び出しは sshagent でラップされ、Jenkins資格情報ストアからの適切な資格情報を再利用します。

18
zeppelin

Credentials Binding Plugin の使用は非常にうまく機能しました(@zeppelinも言及)

手順:

グローバル認証情報セクション:

  1. タイプのAdd Credentials "パスワード付きのユーザー名"。これは、HTTPSプロトコルを使用するコンポーネントBリポジトリgitサーバーのユーザー名とパスワードである必要があります(SSHオプションはこの目的には適していません)

enter image description here

Jenkinsのジョブ構成:

  1. コンポーネントAを通常のSource Code Managementに、Gitセクションのすべての必須フィールド(Repositoriesブランチなど)。
    • リポジトリをサブディレクトリに置くと、より明確できれいになります:Additional BehavioursCheck out to a sub-directoryを選択してcomponent_aを選択します
  2. 必ず[Build TriggersBuild when a change is pushed to GitHubをチェックインしてください。
  3. ビルド環境セクションで、Use secret text(s) or file(s)にチェックマークを付けます

    • Variableに何らかの名前を付けます:MY_CRED
    • Credentialsで、ステップ1で作成した特定の資格情報を選択します。

    enter image description here

  4. Execute ShellコードでMY_CREDを使用すると、コンポーネントBリポジトリにアクセスできます。

    DIR="component_b"
    if [ "$(ls -A $DIR/.git)" ]; then
        cd $DIR
        git fetch
    else
        git clone https://[email protected]/proj/component_b.git $DIR 
        cd $DIR
    fi
    git show
    

    enter image description here

    • :ログにはユーザーとパスワードが表示されないため、安全である必要があります。次のように表示されます:git clone 'https://****@github.com/proj/component_b.git' component_b
  5. コンポーネントAからの構成のすべての解析を実行して、目的のタグを取得します:TAG=$(cat ./component_a/config.cfg | grep ... | sed ...)

  6. 目的のタグをチェックアウトします:cd component_b; git checkout -f $TAG
    • 注:-f forceタグ。
  7. コードを実行して、必要に応じてテストします...
2
Chananel P

1-プロジェクトBをプロジェクトAのサブリポジトリとして追加すると、解決策になりますか?

2-(Bの完全なソースコードを含める場合は、実際に回避する必要があります):BのビルドをいくつかのB_buildsリポジトリにプッシュし、このリポジトリをAのサブリポジトリとして追加することが解決策となります?


理由:ABの間の依存関係をより明確にする1つの方法は、リポジトリの依存関係内でそれを表現することです。

これには、Aプロジェクトを管理するときに追加のステップを追加する必要があります。

update `B` sub repo in `A` project, and Push this to `A`

Bの新しいバージョンを作成するたびに。

ただし、Aのバージョンが統合された時期について、Bから明確なビューが得られます(例:「B 2.0.1から始まるA 4.3.2のみを使用しました」)、 Aにプッシュすると、通常のJenkinsフローがトリガーされます。

1
LeGEC