Jenkinsのビルドサーバー用に新しいプロジェクト設定を作成しようとしています。私がやろうとしていることを単純化するために、私は問題を説明するために2つのコンポーネントだけを使用します。
コンポーネントA
コンポーネントB
Jenkinsでこれを実現するための正しい方法は何でしょうか?設定ファイルを解析して、ComponentBの予想されるバージョンに基づいてブランチをチェックアウトするGit Pluginを作るという動的な動作を追加する方法を見つけようとしていたのですが、今のところ手がかりはありません。
次のステップでは、設定ファイルにワイルドカード(5.3.*のような)を入れて、ワイルドカードに一致する最新のComponentB'sタグを見つけるようにすることも考えています。
EDIT
今となっては、問題を単純化しすぎて、単純化したために主な制約がなくなってしまったのだと思います。
主な制限は、コンポーネントAとコンポーネントBを一緒にビルドする必要があることです。これらは1つの実行ファイル/ライブラリであり、ビルドスクリプトは両方のコンポーネントのソースファイルを必要とするため、別々にビルドすることは不可能です。
なぜこのような不思議な構成になっているのかというと、コンポーネントA、コンポーネントBについて説明します:
特定のAをBにマージすると、単一プラットフォーム用の完全なソースコードが作成されますが、すべてのプラットフォームがBの最新バージョンに更新されるとは限らないため、ビルドに使用するBのバージョンを制御する必要があります。
あなたが望むことを実現するための一つの選択肢は、次のような設定を使用することです:
Jenkinsのジョブを2つ作成します:
コンポーネントB"のbranch
ビルドパラメータを定義します:
このパラメータを "Git Plugin" ブランチ指定子として使用します:
これで、手動で "Component B" ビルドを起動することができるようになりました。
ワークスペースの設定ファイルからコンポーネントB"のバージョンを抽出し、コンポーネントB"のビルドパラメータを含むb.properties
ファイルを準備します。
Jenkinsのプラグイン「Parameterized Trigger」(https://plugins.jenkins.io/parameterized-trigger)をインストールし、「コンポーネントA」のジョブに新しいビルドステップ「Trigger/Call Builds on Other Projects"」を追加します:
ビルドパラメータのソースとして b.properties
ファイルを使用します。
これで、"Component A"が再ビルドされるたびに、ターゲットブランチ/タグをビルドパラメータとして、新しい"Component 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
これは、リモートの "Component B" リポジトリにある "B" バージョンパターンに一致するすべてのタグをリストアップし、最新のバージョン番号を LATEST
変数に保存します。
Component A"ジョブの "Execute Shell"ステップに追加してください、
といったバージョン番号のパターンを扱えるようにする必要があります:5.3.*
ただし、このシェルスクリプトはJenkinsのデーモンユーザーとして実行されます、 そのため、リモート Git リポジトリにアクセスするための適切な認証情報が設定されている必要があります (例: ssh pubkey 経由)。
また、Jenkins自体に保存されているGit認証情報を再利用するために、Credentials Binding Plugin を調べてみるのもよいかもしれません。
また、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のコマンドも用意されています。
次に、SCMのポールに登録されないように、changelog: false, poll: false
フラグを付けた "Component B" を、現在のワークスペースの "module/b" フォルダにフェッチ/クローニングします。
次に、シェルコマンドを起動して、上記で取得したバージョンパターンに基づいてタグを選択し、チェックアウトします(5.3.*スタイルのワイルドカードも機能するはずです)。
sh` の呼び出しは sshagent でラップされており、適切な のクレデンシャルをJenkinsのクレデンシャルストアから取得します。
Credentials Binding Plugin]1を使用すると、非常にうまくいきました(@zeppelin氏も言及しています)。
1.タイプのAdd Credentials
を追加します:"Username with password".これは、HTTPSプロトコルを使用したコンポーネントBのリポジトリgitサーバーのユーザー名とパスワードでなければなりません(SSHオプションはこの目的には適していません)。
2.コンポーネントAを通常のソースコード管理のGit
セクションの下にすべての必須フィールド(リポジトリ、ブランチなど)を配置します。
Check out to a sub-directory
を選択し、次のように記述します:Component_a`
3.ビルドトリガー** の「変更がGitHubにプッシュされたときにビルドする」にもチェックを入れてください。
4.ビルド環境]セクションで、[秘密のテキスト(複数可)またはファイル(複数可)を使用する]をチェックします。[ここに画像の説明を入力]333[!
5.これで、Execute shellのコードでMY_CRED
を使用すると、コンポーネントBのリポジトリにアクセスできるようになります:
DIR="component_b";
if [ "$(ls -A $DIR/.git)" ]; then
cd $DIR
ギットフェッチ
然も
git clone https://[email protected]/proj/component_b.git $DIR
cd $DIR
フィー
ギットショー
6.コンポーネントAのconfigをすべて解析して、目的のタグを取得します:TAG=$(cat ./component_a/config.cfg | grep ... | sed ...). 7.目的のTagをチェックアウトする:cd component_b; git checkout -f $TAG
.
-f
フォースタグ。
8.このコードを実行し、希望通りにテストしてください...。1 - プロジェクトB
をプロジェクトA
のサブレポとして追加することは、可能な解決策でしょうか?
2- (Bのソースコード全体を含めることが本当に避けられるなら) : Bのビルドを B_builds
レポジトリにプッシュし、このレポジトリを A
のサブレポとして追加することは、可能なソリューションでしょうか?
理由 : A
と B
の依存関係をより明示的にする一つの方法は、リポジトリの依存関係の中にそれを表現することである。
この場合、A
プロジェクトを管理する際に、余分なステップを追加する必要があります:
update `B` sub repo in `A` project, and push this to `A`
を作成するたびに、B
の新しいバージョンを作成します。
しかし、A
からは、B
のバージョンがいつ統合されたかを明確に把握することができ(例:"我々は、A 4.3.2
から B 2.0.1
しか使っていない)、A
にプッシュすると通常のJenkinsフローが発生します。