この記事は、多数の同様のアプリケーションのアセンブリ記述を管理する問題を解決します。 GitLab CIをプロジェクトで機能させるには、リポジトリに
.gitlab-ci.yml
ファイルを追加する必要があります。 しかし、100のリポジトリで、これが同じ内容のファイルである場合はどうでしょうか? 一度リポジトリに分解しても、後でそれを変更する方法はありますか? しかし、1つの
.gitlab-ci.yml
でアセンブリが不十分な場合はどうでしょうか
Dappfile
または
Dappfile
、異なるスクリプト、HelmのYAMLファイルの構造が必要ですか? それらを更新する方法は?
何百もの類似のアプリケーションを組み立てるタスクの解決をどこから始めますか? もちろん、GitLab CIを指定して別のリポジトリの
.gitlab-ci.yml
を使用したり、他のリポジトリのファイルから
.gitlab-ci.yml
を
.gitlab-ci.yml
たりできるかどうかを確認してください...
そのような機会を探して、次の問題がすぐに現れます。
- .gitlab-ci.ymlに「include」キーを追加します。
- あるプロジェクトから別のプロジェクトの `.gitlab-ci.yml`に共通のCI / CDコンテンツをインポート/インクルードします(EEのみ?) 。
- 追加にはgitlab-ci YAML形式の機能が含まれます 。
ある種の一般的な
.gitlab-ci.yml
を持つ能力はコミュニティに興味があることが
.gitlab-ci.yml
ます。 別のリポジトリ内のファイルからインクルードセクションを追加する決定は非常に単純なようです。これは長年のプログラミングの実践に基づいており、誰にも明らかです。 ただし、ソースツリーの場合はコンセプトが適切に機能しますが、いくつかのGitリポジトリの場合は、このソリューションにこのような欠点があります。
- インクルードでは、ファイルを接続するブランチを指定する必要があるため、アセンブリは再生されません。
- インクルードでは、ファイルの接続元のブランチを指定する必要があるため、有効な
.gitlab-ci.yml
をキャッシュし、保存して、それに基づいて再構築する必要があります。 - 一部のプロジェクトでは、パラグラフ1を解決する必要がありますが、一部のプロジェクトでは、パラグラフ2は相互に排他的です。
- 接続されたファイルで何かが変更された場合、
.gitlab-ci.yml
基本的に変更しようとしているプロジェクトを変更しますが、変更履歴は表示されません。
同様のアプリケーションの場合、さらに2つのマイナスが追加されます。
- 何百もの同一の
.gitlab-ci.yml
の問題は残っています。 - 追加ファイルの更新に関する問題も残っています。
別の角度から見る
includeを使用したソリューションはプルモデルです。 アセンブリプロジェクトは、CI構成の一部を描画します。 プルをプッシュに置き換えると、次のようになります。
- common-ci-configプロジェクトが作成されます。このプロジェクトには、共通の
.gitlab-ci.yml
およびアセンブリに必要なその他のファイルが保存されます。 - gitlab-ci-distributorユーザーが作成され、希望するプロジェクトに(マスター)をプッシュする権利が与えられます。
このオプションは次のように機能します
.gitlab-ci.yml
ci-configプロジェクト
.gitlab-ci.yml
他の何百ものプロジェクトに共通の
.gitlab-ci.yml
ファイルを保存します。 このファイルが変更されると、 gitlab-ci-distributorは他のプロジェクトにコミットします。
ビルドファイルの場合、選択できます:コミットに追加するか、プロジェクトの
.gitlab-ci.yml
で、ビルドタスクで、 common-ci-configプロジェクトの
git clone
を追加します。
このアプローチの利点:
- 各プロジェクトでは、
.gitlab-ci.yml
、誰が変更したかが明確になります。 有効な.gitlab-ci.yml
を保存する問題は.gitlab-ci.yml
。 各プロジェクトでは、フルバージョンはインクルードなしで常に表示されます。 - アセンブリ時にアセンブリファイルの最新バージョンが不要なプロジェクトでは、コミットによってアセンブリファイルが追加されます。
- アセンブリ時に常に最新バージョンが必要なプロジェクトでは、アセンブリファイルが複製されます。
- いくつかのファイルをコミットに追加できます。また、一部はクローンコピーから使用できます。
- スクリプト呼び出しで
.gitlab-ci.yml
インクルードコンセプトを実装できます。 つまり、アセンブリ中に.gitlab-ci.yml
が常に最新バージョンのテスト構成を使用するようにしたい場合、テストはcommon-ci-configプロジェクトのスクリプトに送信されます。
GitLab API
そのため、問題が特定され、解決策があります。 続行するには、GitLab API( GitLab Webサイトのドキュメント)について話す必要があります。 次の方法が必要です。
- ファイルのコミット。 APIには2つのオプションがあります。1つのファイルを変更する方法と、複数のファイルを使用するコミットコンストラクターです 。 2番目のオプションはもう少し複雑ですが、より多くの機能があります。
- プロジェクトのリストを取得する 。 この方法は、どのプロジェクトをコミットする必要があるかを見つけるのに役立ちます。
- 現在のコミットに関する情報 。 このメソッドは、コミットとその作成者のメッセージを一般リポジトリから残りにコピーするために必要です。
APIメソッドはcurlを使用して呼び出すことができ、応答として返されるJSONはjq( フィルタードキュメンテーション )を使用して処理できます。
メソッドを呼び出すには、アクセストークンを作成する必要があります。 これについてはこの記事でさらに説明しますが、今のところは、グループ内のプロジェクトのリストを取得する方法の例です。
$ curl -s --header "PRIVATE-TOKEN: $TOKEN" https://gitlab.example.com/api/v4/groups/group-of-alike-projects/projects?simple=true | \ jq -r '.[] | "\(.path_with_namespace)\t\(.id)"' group-of-alike-projects/project-pasiphae 7 group-of-alike-projects/project-megaclite 6 group-of-alike-projects/project-helike 5 group-of-alike-projects/project-erinome 4 group-of-alike-projects/project-callisto 3 group-of-alike-projects/project-aitne 2 group-of-alike-projects/project-adrastea 1
GitLabを構成する
APIメソッドを呼び出すことは、許可なしでは不可能です。 GitLabは、アクセストークンを介して承認を提供します。 このようなトークンを取得するには、必要なリポジトリを管理する権限を付与される別のユーザーを作成する必要があります。 これをgitlab-ci-distributorユーザーとします:
次に、このユーザーになり、アクセストークンを作成する必要があります。
アセンブリファイルを管理する必要があるプロジェクトにアクセスするには、 gitlab-ci-distributorユーザーをグループに追加する必要があります。
プロジェクト共有ファイルはプロジェクトcomm-ci-configに保存されます。 プロジェクトは、別のグループ(たとえば、 infra)で作成する必要があります。 プロジェクト設定で、受信したトークンの値を持つ秘密変数が追加されます。
説明されているアクションは、管理者によって1回実行されます。 さらに、すべての構成はcommon-ci-configリポジトリー内のファイルを介して行われます。
Common-ci-configリポジトリ
これで、GitLab CIを介してAPIの操作をテストできます。 これを行うには、単純な
.gitlab-ci.yml
common-ci-config
.gitlab-ci.yml
追加され
.gitlab-ci.yml
:
stages: - distribute distribute: stage: distribute script: - ./distribute.sh
...および
distribute.sh
スクリプト。これまでのところ、選択したグループのコミットおよびプロジェクトに関する情報が表示されます。
#!/usr/bin/env bash curl -s --header "PRIVATE-TOKEN: $DISTRIBUTOR_TOKEN" https://gitlab.example.com/api/v4/projects/infra%2Fcommon-ci-config/repository/commits/$CI_COMMIT_SHA | jq '.' curl -s --header "PRIVATE-TOKEN: $DISTRIBUTOR_TOKEN" https://gitlab.example.com/api/v4/groups/group-of-alike-projects/projects?simple=true | \ jq -r '.[] | "\(.path_with_namespace)\t\(.id)"'
ジョブ結果の配布 :
Running with gitlab-runner 10.1.0 (c1ecf97f) on gitlab (d82a6d8f) Using Shell executor... Running on gitlab... Fetching changes... HEAD is now at 08dcc92 Initial .gitlab-ci.yml and distribute.sh Checking out 08dcc92a as master... Skipping Git submodules setup $ ./distribute.sh { "id": "08dcc92abf0d951194ad1ffcc23deeb875855320", "short_id": "08dcc92a", "title": "Initial .gitlab-ci.yml and distribute.sh", "created_at": "2017-10-25T16:35:15.000+03:00", "parent_ids": [ "d9bdea91d081025c2af658209f23f684c96b5cee" ], "message": "Initial .gitlab-ci.yml and distribute.sh\n", "author_name": "root root", "author_email": "root.root@gitlab.example.com", "authored_date": "2017-10-25T16:35:15.000+03:00", "committer_name": "root root", "committer_email": "root.root@gitlab.example.com", "committed_date": "2017-10-25T16:35:15.000+03:00", "stats": { "additions": 0, "deletions": 0, "total": 0 }, "status": "running", "last_pipeline": { "id": 2, "sha": "08dcc92abf0d951194ad1ffcc23deeb875855320", "ref": "master", "status": "running" } } group-of-alike-projects/project-pasiphae 7 group-of-alike-projects/project-megaclite 6 group-of-alike-projects/project-helike 5 group-of-alike-projects/project-erinome 4 group-of-alike-projects/project-callisto 3 group-of-alike-projects/project-aitne 2 group-of-alike-projects/project-adrastea 1 Job succeeded
distribute.shスクリプトの完了
スクリプトは、共通の
.gitalb-ci.yml
を配布し
.gitalb-ci.yml
。 common-ci-configプロジェクトの
.gitlab-ci.yml
プロジェクトと混同しないように、ファイルは
common
ディレクトリーにあります。 ファイルには、簡単な自動タスクが記述されています。
# common/.gitlab-ci.yml stages: - build build: stage: build script: - echo Building project $CI_PROJECT_PATH
distribute.sh
スクリプトには、すでにコミットに関する情報とプロジェクトのリストが含まれています。 プロジェクトへの美しいコミットを取得するには、作成者の名前とメール、およびコミットの完全なメッセージを強調する必要があります。 また、受信したプロジェクトにループを追加し、各プロジェクトに対してコミットを作成するメソッドを呼び出す必要があります。
変更
distribute.sh
れた
distribute.sh
:
#!/usr/bin/env bash COMMIT_INFO=$(curl -s --header "PRIVATE-TOKEN: $DISTRIBUTOR_TOKEN" https://gitlab.example.com/api/v4/projects/infra%2Fcommon-ci-config/repository/commits/$CI_COMMIT_SHA) # , jq -r MESSAGE=$(echo "$COMMIT_INFO" | jq '.message') AUTHOR_NAME=$(echo "$COMMIT_INFO" | jq -r '.author_name') AUTHOR_EMAIL=$(echo "$COMMIT_INFO" | jq -r '.author_email') CONTENT=$(base64 -w0 common/.gitlab-ci.yml) PAYLOAD=$(cat <<- JSON { "branch": "master", "commit_message": $MESSAGE, "author_name": "$AUTHOR_NAME", "author_email": "$AUTHOR_EMAIL", "actions": [ { "action": "update", "file_path": ".gitlab-ci.yml", "content": "$CONTENT", "encoding": "base64" } ] } JSON ) echo "$PAYLOAD" curl -s --header "PRIVATE-TOKEN: $DISTRIBUTOR_TOKEN" https://gitlab.example.com/api/v4/groups/group-of-alike-projects/projects?simple=true | \ jq -r '.[] | "\(.path_with_namespace)\t\(.id)"' | \ while read project do name=`echo $project | awk '{print $1}'` id=`echo $project | awk '{print $2}'` echo Update project $name curl -s --request POST --header "PRIVATE-TOKEN: $DISTRIBUTOR_TOKEN" \ --header "Content-Type: application/json" \ --data "$PAYLOAD" https://gitlab.example.com/api/v4/projects/$id/repository/commits done echo Stop
ジョブ結果の配布 :
group-of-alike-projects / project-pasiphaeプロジェクトでは、コミットは次のようになります。
group-of-alike-projects / project-pasiphaeプロジェクトのビルドタスクの結果:
タスクを実行するユーザーはgitlab-ci-distributorであることがわかります。 しかし同時に、コミットの作成者はcommon-ci-configでコミットしたユーザーです。
同時自動ビルドを無効にする
distribute.sh
スクリプトは、一度に複数のプロジェクトにコミットを追加します。 これにより、新しいパイプラインが作成され、アセンブリタスクが同時に起動されます。 この効果は必ずしも必要ではありません。
.gitlab-ci.yml
を更新するコミット
.gitlab-ci.yml
ビルド
.gitlab-ci.yml
ようにするには、最初に警告メッセージで条件を設定できます。
script: - 'if [ "x$GITLAB_USER_NAME" == "xgitlab-ci-distributor" ] ; then echo -e "\033[0;31m\n\n .gitlab-ci.yml .\n\n\033[0m"; exit 1; fi'
注意!
GITLAB_USER_NAME
変数はGitLab 10.0 (2017年9月22日リリース )に登場しました。 以前のバージョンでは
GITLAB_USER_ID
のみがあり、条件にはユーザーIDを使用する必要があります。 このIDは、たとえば、
script: [export]
または次のAPIリクエストを使用してタスクを実行することで見つけることができます。
curl -s --header "PRIVATE-TOKEN: $DISTRIBUTOR_TOKEN" https://gitlab.example.com/api/v4/users?username=gitlab-ci-distributor | jq '.[] | .id'
結果:
このタスクを通常のユーザーから再度実行すると、すべてが成功します。
おわりに
一般に、この情報は、大規模プロジェクト管理を独自に実験し続けるのに十分です。
実験を簡素化し、記事で説明されていることを繰り返すために、たとえばgitlab-vagrantプロジェクトを使用して、仮想マシンにGitLabをインストールできます。
Vagrantfile
を修正する必要があることに注意してください。ベースイメージを
ubuntu/xenial64
変更し、メモリ
vb.memory = "3072"
を増やします。 そして、起動後、 指示に従ってgitlab-runnerを追加します 。
ソリューションの開発時に、次のリソースが使用されました。
PS
私たちのブログも読んでください(そして、新しい出版物を見逃さないように購読してください!) :