本番環境での継続的な統合と配信のためのGitLab CI。 パート2:困難を克服する


この記事では、パイプラインの詳細な説明を含む最初のパートを続けます。

画像

...そして、その実装で発生した問題とその解決策について説明します。

だから、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.ステージ間の依存関係


実装方法に関する別の問題は、自動タスクと手動タスク、ステージ間の依存関係における混乱と見なすことができます。 自動タスクは常にパイプラインの開始時に開始され、その起動は前の段階での自動タスクの結果のみに依存します。 同時に、手動タスクとその実装のステータスは完全に無視されます。

つまり、第一に、自動タスクはパイプラインの作成時にのみ起動されます。第二に、手動タスクが正常に完了するとパイプライン内にある自動タスクが開始される場合、そのようなプロセスを実行できません。 このドキュメントでは、基本的に自動タスクの動作について説明しています。 手動タスクは「単独で」実行され、前の段階のタスクのステータスに関係なく、いつでも起動できます。

このテーマにはいくつかのチケットがあり、手動および自動タスクの動作を変更することが提案されています。


しかし、これらの提案は互いに矛盾しているようです。 この場合でも、独立して実行できる手動タスクと、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_USER_EMAIL 。変数GITLAB_USER_IDおよびGITLAB_USER_EMAIL転送してcurl経由で要求できるREST APIが必要GITLAB_USER_EMAIL 。 このようなREST APIの作成は、この記事の範囲外です。

上記の例では、依存関係をチェックするスクリプトは.gitlab-ci.yml保存されています。 これは、多くのプロジェクトがあり、何かを修正する必要がある場合(たとえば、qaの新しい環境が表示されたり、運用前の環境が増えたりする場合)、非常に不便です。 スクリプトを1つの外部スクリプトに配置することでこれを決定しました。このスクリプトは、各リポジトリには保存されませんが、ランナーのいるマシンにインストールされます。

このようなスクリプトで使用できる環境変数はいくつかあります。 これらの変数に基づいて、スクリプトは実行中のタスクの種類を決定し、前の段階のファイルからこのタスクを実行できるかどうかを確認します。 必要に応じて、外部RESTサービスを介してユーザーのアクセスを確認します。 スクリプトには、タスクのために完了する必要がある指示が含まれており、正常に実行された後、次のタスクが応答するファイルを作成します。

通常、パイプラインには多くのタスクのバリエーションはありませんが、スクリプトでは次の3つを把握しています。

  1. 組立説明書
  2. 展開手順
  3. 指示を 承認し承認ません

指示は環境変数も受け取り、特定のタスクに合わせて調整できます。 環境には多くのビルドオプションと展開オプションがあり、GitLabのプロジェクトの数も全員で異なるため、このようなスクリプトの実装を引用する必要はないと考えています。 ただし、質問がある場合は、コメントで議論しましょう。

結論の代わりに


この記事がGitLab CIの新しい興味深い機能を明らかにし、独自のクールなパイプラインを実装するための出発点となることを願っています。



PS https://-/ci/lint.gitlab-ci.ymlをチェックすることを忘れないでください。 時間を節約!

Source: https://habr.com/ru/post/J332842/


All Articles