CircleCIはワークフローの作り方から学ぼう

# CircleCIとは?
「**CircleCIとはなんぞや？**」と聞かれたら、
とりあえず
**`.circleci/config.yml`というYAMLファイルに「ワークフロー」を設定すること**
だと思ってもらって大丈夫だと思います。

# CircleCIは、開発を楽チンにするためにある!
多くのチーム開発において、開発は以下のような順番で行われます。
1. **設計**: 計画を立てる
1. **実装**: 実際にコードを書く
1. **テスト**: バグらないかどうか確認する
1. **デプロイ**: 書いたコードをサーバーにアップロードする

しかし、これらを実際に行うのは非常に大変で、手間がかかります。

現在は、**実装**で書いたコードは**GitHub**(要はコードを保管するGoogleDriveのようなストレージ)にアップロードする(**PUSHする**)ことが普通です。

一つのプロジェクトには一つの**GitHubレポジトリ**(フォルダ)があります。

そして、一つの**GitHubレポジトリ**に一つの**CircleCIプロジェクト**があります。

そして、一つの**CircleCIプロジェクト**に対応する**GitHubレポジトリ**には
**`.circleci/config.yml`** というファイルが存在します。
詳しい手順は以下の記事からどうぞ。
[**(非公開中)プロジェクトにCircleCIを導入する**](example.com)

# ワークフローの一生を見てみよう！
「**ワークフロー**」とは、沢山の処理が集まったものです。
ここから、一つのワークフローが、
1. **なにでできているのか**
1. **どのようにコード化されているのか**
1. **どのように実行が始まるのか**
1. **ワークフローの終わり**

という観点で解説していきます。

## 1. 「ワークフロー」はなにでできているのか
1. **ワークフロー**: 色んなジョブを組み合わせたものこと。
1. **ジョブ**: 色んなステップを組み合わせたもの。
1. **ステップ**: １つの処理のこと。
1. (1) **ワークフロー** > (2) **ジョブ** > (3) **ステップ**
大枠を理解するには、一旦ジョブやステップなどの細かい事項は無視して進めると良いかもしれません。
ただ、実際の業務で使うのであれば、ワークフローの知識だけではたりません。
以下に、ジョブとステップそれぞれの私の記事がございますのでご笑覧ください。

[**(非公開中)ジョブについて**](example.com)
[**(非公開中)ステップについて**](example.com)

## 2. ワークフローはどのようにコード化されているのか
```yaml
workflows:
  version: 2
  1st_workflow:
    jobs: # ここから下にジョブを書いていく
      - job_1_1 # 1つ目のジョブ
      - job_1_2 # 2つ目のジョブ
      - job_1_3 # 3つ目のジョブ...
```
「**1. 「ワークフロー」はなにでできているのか**」でも書いた通り、<br>**ワークフロー**は、いくつかの**ジョブ**からできています(**ジョブ**は1つしかなくても良い)。<br>そして、**ワークフロー**の中の**ジョブ**たちは、すべて**同時並行で実行**されます。

しかし、同時並行で動いて欲しくないこともあります。つまりは
**1つ目が終わったら2つ目、2つ目が終わったら3つ目...**
というように実行させたいこともあります。

その場合は、`requires`という**ステップ**を追加して、以下のような工夫をします。
"require"とは「必要とする」という意味ですね。
つまり、「実行するのに〇〇というジョブが必要」ということを書いているのです。
```yaml
workflows:
  version: 2 # これはワークフロー自体とは関係ない。使うCircleCIのバージョンを指定している。
  1st_workflow:
    jobs:
      - job_1_1:
          # job_1_1内のステップ達...
      - job_1_2:
          requires:
            - job_1_1 # ←これをつけておくと、"job_1_1"の後に下のステップが実行される
          # job_1_2内のステップ達...
      - job_1_3:
          requires:
            - job_1_2 # ←これをつけておくと、"job_1_2"の後に下のステップが実行される
          # job_1_3内のステップ達...
```
## 3. 「ワークフロー」の始まり(トリガー)
実際にコード化することができたら、実行します！
「ワークフロー」は原則、**GitHubにPUSH**された瞬間に実行されます。
* プッシュ(デフォルト)
* スケジュール
1. **設計**: 計画を立てる
1. **実装**: 実際にコードを書く(書き終わったら**GitHubにPUSHする**)
1. **テスト**: バグらないかどうか確認する
1. **デプロイ**: 書いたコードをサーバーにアップロードする

## 4. ワークフローの終わり
ワークフローが
* **RUNNING**：実行中
* **NOT RUN**：まだ実行していない
* **CANCELLED**：実行がキャンセルされた
* **FAILING**：ジョブが失敗したが、ほかのジョブが実行中である
* **FAILED**：ジョブが失敗し、ワークフローの実行が終了した
* **SUCCESS**：ジョブがすべて成功し、ワークフローの実行が終了した
* **ON HOLD**：ジョブが承認されるのを待機している
* **NEEDS SETUP**：ワークフローの設定方法に間違いがある

# ワークフローは沢山追加できる
ここまでワークフローの一生を見てきました。
<br>実は、ワークフローとは1つの`config.yml`に幾つでも定義することができます。
<br>以下のように`workflows`の下に自由に追加できます。
<br>様々なワークフローを定義して、どんどん開発を楽チンにしましょう！
```yaml
workflows:
  version: 2
  1st_workflow: # 実施は自由に「ワークフロー」に名前をつけられるよ
    jobs:
      - job_1_1
      - job_1_2
      - job_1_3
  2nd_workflow: # 実施は自由に「ワークフロー」に名前をつけられるよ
    jobs:
      - job_2_1
      - job_2_2
      - job_2_3
  3rd_workflow: # 実施は自由に「ワークフロー」に名前をつけられるよ
    jobs:
      - job_3_1
      - job_3_2
      - job_3_3
  4th_workflow: # 実施は自由に「ワークフロー」に名前をつけられるよ
    jobs:
      - job_4_1
      - job_4_2
      - job_4_3
  5th_workflow: # 実施は自由に「ワークフロー」に名前をつけられるよ
    jobs:
      - job_5_1
      - job_5_2
      - job_5_3
```
【参考文献】
1. https://circleci.com/docs/
1. 浦井 誠人; 大竹 智也; 金 洋国. **CircleCI実践入門──CI/CDがもたらす開発速度と品質の両立**<br>WEB+DB PRESS plus (Japanese Edition) (p. 147). 株式会社技術評論社. Kindle Edition.