この記事では、パイプラインの詳細な説明を含む最初のパートを続けます。
...そして、その実装で発生した問題とその解決策について説明します。
だから、GitLab CIはユーザーごとにタスクを分離し、他のタスクのステータスに対するタスク実行の依存関係を記述するためのディレクティブを提供しないため、作成された.gitlab-ci.ymlはパイプラインを完全に実装することができず、また個々のユーザーのみに
.gitlab-ci.yml
変更を許可します。
1.変更からの.gitlab-ci.ymlの保護
git push
権限を持つユーザーは、
.gitlab-ci.yml
を変更して
.gitlab-ci.yml
を中断できます。 この問題はGitLabチケットで議論されています:少なくとも- #24794と#20826で同僚の提出。
すぐに保護を実装するかどうかを言うのはまだ難しいですが、現時点では、簡単なバージョンで小さなパッチを実装しました:一部のユーザーのみが
.gitlab-ci.yml
への変更でコミットをプッシュできます-通常、これはDevOpsコマンドですなぜなら 責任の範囲内でのアセンブリと展開。
パッチを適用することに加えて、ブール列
ci_admin
をユーザーとともにテーブルに追加する必要があります。 列で
true
に設定されている
.gitlab-ci.yml
は、
.gitlab-ci.yml
を変更して
git push
を実行できます。
2.タスクスクリプトの変数
簡単に解決できることが判明した2番目の問題は、ユーザーIDと彼のメールを含むタスクスクリプトの
GITLAB_USER_ID
および
GITLAB_USER_EMAIL
環境変数です。 これらの変数を使用して、ユーザーがタスクを実行できるかどうかを判断できます。 チケット#21825のソリューションとして実装され、メインブランチ(上流)で採用され、バージョン8.12以降のGitLab CIで利用可能です:
3.ステージ間の依存関係
実装方法に関する別の問題は、自動タスクと手動タスク、ステージ間の依存関係における混乱と見なすことができます。 自動タスクは常にパイプラインの開始時に開始され、その起動は前の段階での自動タスクの結果のみに依存します。 同時に、手動タスクとその実装のステータスは完全に無視されます。
つまり、第一に、自動タスクはパイプラインの作成時にのみ起動されます。第二に、手動タスクが正常に完了するとパイプライン内にある自動タスクが開始される場合、そのようなプロセスを実行できません。 このドキュメントでは、基本的に自動タスクの動作について説明しています。 手動タスクは「単独で」実行され、前の段階のタスクのステータスに関係なく、いつでも起動できます。
このテーマにはいくつかのチケットがあり、手動および自動タスクの動作を変更することが提案されています。
- #25892:[CI]手動ステージの後のステージは自動的に開始されません
- #26499:アップストリームジョブが再試行される場合、後続のジョブを再試行する
- #20594:手動ジョブが依存関係を無視する
しかし、これらの提案は互いに矛盾しているようです。 この場合でも、独立して実行できる手動タスクと、1つ以上のタスクが正常に完了したことに応答する必要がある手動タスクが必要です。 少し考えた後、タスクアーティファクトとスクリプトを使用して、前の段階のファイルの存在を確認するというアイデアが生まれました。
タスクアーティファクトは、
artifact
ディレクティブで指定されたファイルであり、後続のステージの他のすべてのタスクで(タスクが正常に完了した後に)利用可能になります。 ただし、ここには落とし穴があります。ステージのすべてのタスクからのファイルは、以降のステージで使用可能になり、このセットから何も削除できません。 同時に、タスクアーティファクトファイルは、同じステージの他のタスクでは使用できません。
2つの例についてさらに詳しく考えてみましょう。 最初に、 テストおよびステージングの段階の例によって:
パイプラインの説明によると、テスターの環境への展開タスク( qa- *に展開 )は、すべてのテストが完了した後にのみ実行でき、残りのタスクにはそのような依存関係はありません。 このロジックを実装するには、成功したテストの最後に、タスクの名前を含む
touch
ファイルを作成し、 qa- *へのタスクデプロイメントの開始時に、 ステージング段階でこれらのファイルの存在を確認します。
テスト統合とqa-1タスクリストへのデプロイの例を次に示します。
test integration: stage: testing tags: [deploy] script: - mkdir -p .ci_status - echo "test integration" - touch .ci_status/test_integration artifacts: paths: - .ci_status/ deploy to qa-1: tags: [deploy] stage: staging when: manual script: - if [ ! -e .ci_status/test_unit -o ! -e .ci_status/test_integration -o ! -e .ci_status/test_selenium ]; then echo " "; exit 1; fi - echo "execute job ${CI_BUILD_NAME}" - touch .ci_status/deploy_to_qa_1 artifacts: paths: - .ci_status/
artifact
ディレクティブが追加されました。これは、タスクが完了して次のタスクの前に解凍された後にGitLab CIがアーカイブに保存するリポジトリへのパスを定義します。 すべてのファイルをリストしないようにするために、タスクの実行中に作成するのに害のない
.ci_status
ディレクトリーが
.ci_status
ています(
mkdir -p
)。
ソース :ステージングステージがテストに依存している.gitlab-ci.ymlファイルは、 ここから入手できます 。
2番目の例はもう少し複雑です。これは、 承認段階に対する生産段階の依存関係です。
承認タスクではなく承認タスクは、 本番タスクがチェックするファイルを作成します。 これは前の例と同じ方法で実行できますが、 NOT承認および承認タスクがスイッチとして機能するようにします。 この作業は、別のタスクから成果物ファイルを削除できないという事実によって妨げられています。 したがって、タスクはファイルを作成するだけでなく、ファイルにタイムスタンプを書き込みます。 実稼働タスクへのデプロイの開始時にチェックが実行されます。タスクからのファイルにさらに承認タイムスタンプがある場合、続行できますが、そうでない場合、タスクはエラーで終了します。
approve: script: - mkdir -p .ci_status - echo $(date +%s) > .ci_status/approved artifacts: paths: - .ci_status/ NOT approve: script: - mkdir -p .ci_status - echo $(date +%s) > .ci_status/not_approved artifacts: paths: - .ci_status/ deploy to production: script: - if [[ $(cat .ci_status/not_approved) > $(cat .ci_status/approved) ]]; then echo " -"; exit 1; fi - echo "deploy to production!"
承認タスクが完了 すると 、 実稼働環境 へのデプロイが正常に実行されます。
NOT承認タスクが完了すると、それに続く実稼働タスクへのデプロイは失敗します。
ソース :
- 生産段階が承認段階に依存するオプション.gitlab-ci.yml 。
- 結果の.gitlab-ci.ymlのフルバージョン 。ディレクティブとステージの依存関係のみが含まれます。
次は?
一部のユーザーのみに特定のタスクを解決するという要件は、暗黙のうちに残っています。 この段階で、これを実装する方法が明らかになり
GITLAB_USER_EMAIL
。変数
GITLAB_USER_ID
および
GITLAB_USER_EMAIL
転送してcurl経由で要求できるREST APIが必要
GITLAB_USER_EMAIL
。 このようなREST APIの作成は、この記事の範囲外です。
上記の例では、依存関係をチェックするスクリプトは
.gitlab-ci.yml
保存されています。 これは、多くのプロジェクトがあり、何かを修正する必要がある場合(たとえば、qaの新しい環境が表示されたり、運用前の環境が増えたりする場合)、非常に不便です。 スクリプトを1つの外部スクリプトに配置することでこれを決定しました。このスクリプトは、各リポジトリには保存されませんが、ランナーのいるマシンにインストールされます。
このようなスクリプトで使用できる環境変数はいくつかあります。 これらの変数に基づいて、スクリプトは実行中のタスクの種類を決定し、前の段階のファイルからこのタスクを実行できるかどうかを確認します。 必要に応じて、外部RESTサービスを介してユーザーのアクセスを確認します。 スクリプトには、タスクのために完了する必要がある指示が含まれており、正常に実行された後、次のタスクが応答するファイルを作成します。
通常、パイプラインには多くのタスクのバリエーションはありませんが、スクリプトでは次の3つを把握しています。
- 組立説明書
- 展開手順
- 指示を 承認し 、 承認しません 。
指示は環境変数も受け取り、特定のタスクに合わせて調整できます。 環境には多くのビルドオプションと展開オプションがあり、GitLabのプロジェクトの数も全員で異なるため、このようなスクリプトの実装を引用する必要はないと考えています。 ただし、質問がある場合は、コメントで議論しましょう。
結論の代わりに
この記事がGitLab CIの新しい興味深い機能を明らかにし、独自のクールなパイプラインを実装するための出発点となることを願っています。
PS
https://-/ci/lint
で
.gitlab-ci.yml
をチェックすることを忘れないでください。 時間を節約!