Oct 21, 20263 分 READ

CircleCI ワークフローのターミナル依存関係:重要な処理を必ず実行する

Brice Nkengsa

Staff Software Engineer

ジョブが失敗した、キャンセルされた、あるいはそもそも実行されなかった場合、その後に必要な処理(クリーンアップ、通知、ティアダウン)をうまくトリガーする方法がありません。ジョブを複製したり、壊れやすい回避策の分岐を追加したりせずに、「何があってもこれを実行する」とパイプライン設定で表現する簡単な方法はありませんでした。

ターミナルジョブがこの状況を変えます。

CircleCI のターミナルジョブを使えば、設定を複製したり壊れやすい回避策の分岐を追加したりすることなく、「上流の処理が終わったら、どのような結果でもこれを実行する」と表現できるようになりました。

これが重要な理由

多くのチームは、いずれ次のような問題に直面します。

  • テスト後に一時リソースを必ずクリーンアップする必要がある。
  • パイプラインが最終状態に達したら必ず関係者に通知する必要がある。

これまで、こうしたパターンを実現するには設定を繰り返し書くしかありませんでした。失敗パスごとに複製したジョブ、壊れやすい依存チェーン、そして分岐条件が増えるたびに膨らんでいく読みにくいワークフローです。

ターミナルジョブはこの複雑さを減らし、ワークフローの意図をより明確にします。

ターミナルジョブとは

CircleCI は、requires の terminal 依存状態をサポートするようになりました。これにより、下流の動作をより自然に定義できます。

「どの最終状態でもよい」という意味を 1 つの簡潔な式で表したいときは、terminal を使います。パイプライン設定に「ターミナル」の動作を直接取り入れられます。

主なユースケース

1) エフェメラル環境を必ずティアダウンする

セットアップジョブが成功したら、テストが失敗しても、キャンセルされても、開始されなくても、ティアダウンは実行されるべきです。

workflows:
  main:
    jobs:
      - setup-env
      - integration-test:
          requires:
            - setup-env
      - teardown-env:
          requires:
            - setup-env: success
            - integration-test: terminal

この例では、teardown-env は setup-env の成功を必要としますが、integration-test については最終状態に達することだけを求めます。つまり、統合テストが成功しても、失敗しても、キャンセルされても、開始されなくても、ティアダウンは実行されます。

2) ジョブを複製せずに最終通知を 1 回だけ送る

結果ごとに別々の notify ジョブを作る代わりに、上流の処理が最終状態に達した時点で通知ジョブを 1 回実行します。

workflows:
  main:
    jobs:
      - deploy
      - release:
          requires:
            - deploy
      - notify:
          requires:
            - release: terminal

notify ジョブは、結果にかかわらず release の終了を待ちます。terminal がなければ、release の結果ごとに別々の通知ジョブを用意するか、すべてのパスをカバーする条件分岐のチェーンが必要になります。

実際の効果

この機能により、チームは次のことができます。

  • 繰り返しの多い設定を減らす
  • ワークフローの意図をより明確に表現する
  • クリーンアップパスの漏れによる運用リスクを減らす
  • 信頼性の高い「finally」パターンをプロジェクト全体で標準化する

つまり、設定の回避策が減り、自動化の予測可能性が高まります。

はじめに

まずは、異なる結果に対応するために下流のジョブを複製しているワークフローを特定しましょう。通常、そこが最も早く効果を得られる箇所です。

次に、以下を行います。

  1. 意図が「完了したら実行する」である箇所では、長い結果のリストを terminal に置き換えます。
  2. 代表的なパイプライン 1 つで検証してから、広く展開します。

リリースの詳細は、変更履歴でご覧いただけます。