【CircleCI】config.yml 入門

# 概要
今更ながら実務にてcircleCIを使ってCI環境を1から構築するという経験をしました。
その中でこれがcircleCIの基本なのかと思う部分もありましたので、備忘として残そうと思います。
これからcircleCIを導入する方、設定値の概念がわからずどうすればいいのかわからないという方に参考になればと思います。

# CircleCIとは
Saas型のCI/CDサービスです。Saas型であるという点が特徴です。
CircleCIはクラウド上のコンテナを実行環境として使用することができます。
基本的にはコンテナ(docker)を使って実行環境を整えていくことが多いのではと思います。

# config.yml
CI/CDの設定は全て`.circleci/config.yml` に記載します。
`.circleci`ディレクトリは対象Gitリポジトリのトップに置きます。

# はじめに
まずはとにかく簡単な記述でもいいので動かしてみます。
下記のようなconfig.ymlを作成しました。

```yml
version: 2.1

jobs:
  build:
    docker:
      - image: cimg/base:2022.04
    steps:
      - run: echo "start circleCI!"
```
- `version`: config.ymlのバージョンです。過去にはバージョン1がありましたが、今後作成するのであれば2か2.1にしてください
- `jobs`: CI上で動かす動作の単位のことです。今回は`build`というjob名で作成しています。後に説明をしますが、`workflow`機能を使わない場合は`build`というjobが必要です。
- `docker.image`: jobを実行する環境のことです。今回はcircleCIが提供している`cimg/base`というubuntuを選択しました。ubuntuに限らずcircleCIが提供しているコンビニエンスイメージを使用すると、ビルドに必要な最低限のものが入っているため手軽です。
- `steps`: 具体的にどんな動作を行うかを記述できます。今回はそのまま`start circleCI!`という文字を標準出力するだけです。

実行結果
![スクリーンショット 2022-06-28 11.40.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/434850/8665aa30-2205-2c27-54b9-b14e23be74c1.png)

# shellファイルを実行する
今はただ文字列を標準出力しただけです。ですが当然ながら実案件ではより複雑な処理を書く場合もあります。
そんな時はshellファイルを分離させて、circleCIからそのshellファイルを実行するということもできます。

こんなshellファイルを作成しました。
```shell
#!/bin/sh
echo "i am qiita.sh!"
```

config.ymlはこのように変更します。
```yml
version: 2.1

jobs:
  build:
    docker:
      - image: cimg/base:2022.04
    steps:
      - checkout
      - run: sh ./qiita.sh 
```
`checkout`という記述を追加しているのですが、この記述によりcircleCI上でgithubのコードをフェッチできます。
今回の場合、githubに`qiita.sh`というファイルが追加されたため`checkout`でフェッチしないとshellファイルを実行することができません。

実際に動かすと実行できています。
![スクリーンショット 2022-06-28 12.00.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/434850/e2959453-6bc5-f565-6c7c-0c8c6773a93f.png)


# 複数の実行環境で動かす
ubuntuの環境を作ってその中でshellを実行することができるようになりました。
ですがCI上で別の環境を作って動かしたいということもあると思います。
そこで、node環境を構築する記述を作成しました。
```yml
version: 2.1

jobs:
  ubuntu_build:
    docker:
      - image: cimg/base:2022.04
    steps:
      - checkout
      - run: sh ./qiita.sh 
  node_build:
    docker:
      - image: cimg/node:16.15.0
    steps:
      - checkout
      - run: npm install

workflows:
  version: 2
  ci:
    jobs:
      - ubuntu_build:
          name: ubuntu_build
      - node_build:
          name: node_build
```
`ubuntu_build`: 元々buildというjob名だったのですが、nodeのbuildも追加したので名前を変えました
`node_build`: circleCIが提供するnodeのコンビニエンスイメージを使って実行環境を作成します。ルートディレクトリのpackage.jsonに記載されているライブラリを環境にインストールしたいので、`checkout`をした後にnpm installをしています。
`workflows`: buildというjobがなくなったので追加しました。 workflows機能では、複数のjobの実行順序などをなどを束ねて定義することができます。

実際に実行するとこのような見え方になります。
![スクリーンショット 2022-06-28 12.14.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/434850/b9d7cb43-d989-a526-72cc-197b0ed3b467.png)

# executorsの利用
今用意している記述は非常にシンプルなものですが、例えばubuntu_buildで使用したubuntuの実行環境を別のjobでも使いまわしたい、ということもあるかと思います。
そんな時は`executors`を使います。
`executors`を使うことで実行環境の定義だけを設定値として切り出し、様々なjobで使い回すことができます。
これによりjobsの作成の都度dockerのimageを指定するということをしなくても良くなります。

```yml
version: 2.1

executors:
  ubuntu:
    docker:
      - image: cimg/base:2022.04
  
  node:
    docker:
      - image: cimg/node:16.15.0

jobs:
  echo_qiita_shell:
    executor:
      name: ubuntu
    steps:
      - checkout
      - run: sh ./qiita.sh 
  
  echo_hello:
    executor:
      name: ubuntu
    steps:
      - run: echo "hello!!"

  npm_install:
    docker:
      - image: cimg/node:16.15.0
    steps:
      - checkout
      - run: npm install

workflows:
  version: 2
  ci:
    jobs:
      - echo_qiita_shell:
          name: echo_qiita_shell
      - echo_hello:
          name: echo_hello
      - npm_install:
          name: npm_install
          
```
`executors.ubuntu`: 今まで使用していたubuntuの設定をexecutorsとして切り出しています。
`executors.node`: 今まで使用していたnodeの設定をexecutorsとして切り出しています。
`jobs.echo_qiita_shell`: executorにubuntuを指定しています。`ubuntu_build`からrenameしました。今まで通りqiita.shを実行します。
`jobs.echo_hello`: executorにubuntuを指定しています。`echo_qiita_shell`と同じ実行環境となります。`hello！！`を標準出力します。
`jobs.npm_install`: executorにnodeを指定しています。`node_build`からrenameしました。今まで通りnpm installを行います。

実際に動かすとこのようになります。
![スクリーンショット 2022-06-28 12.33.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/434850/5fe96665-c495-1bf2-4f3e-407d04e3d86f.png)

# circleCI Orbsの利用
[circleCI Orbs](https://circleci.com/docs/ja/2.0/orb-concepts)という機能があります。
公式のドキュメントでは下記のように説明されています。
> CircleCI Orb とは、ジョブ、コマンド、Executor などの、共有可能な設定要素をパッケージ化したものです。

つまりサーバーサイドやフロントエンドの開発などで使われるライブラリなどのように、既に出来上がっている機能をこのorbsを使うことでimportできます。
実際に使ってみました。

```yml
version: 2.1

orbs:
  shellcheck: circleci/shellcheck@3.1.1

executors:
  ubuntu:
    docker:
      - image: cimg/base:2022.04

  node:
    docker:
      - image: cimg/node:16.15.0

jobs:
  echo_qiita_shell:
    executor:
      name: ubuntu
    steps:
      - checkout
      - run: sh ./qiita.sh 
  
  echo_hello:
    executor:
      name: ubuntu
    steps:
      - run: echo "hello!!"

  npm_install:
    docker:
      - image: cimg/node:16.15.0
    steps:
      - checkout
      - run: npm install

workflows:
  version: 2
  shellcheck:
    jobs:
      - shellcheck/check:
          name: shellcheck qiita.sh
          dir: ./
    
  ci:
    jobs:
      - echo_qiita_shell:
          name: echo_qiita_shell
      - echo_hello:
          name: echo_hello
      - npm_install:
          name: npm_install
```
`orbs`: importしたいorbsを指定します。今回はshellcheckというlintツールをimportしました。
`workflows.shellcheck.jobs.shellcheck/check`: [ドキュメント](https://circleci.com/developer/ja/orbs/orb/circleci/shellcheck)を参考にしつつshellcheckをする工程をworkflowsに追加しました。

実際に動かすと`shellcheck qiita.sh`が実行されているのがわかります。
![スクリーンショット 2022-06-28 12.46.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/434850/151bfed8-3e82-21b5-e414-0523815d4572.png)

# さいごに

トレタでは一緒に開発する仲間を募集しています。<br>
興味がある方は是非カジュアル面談へお越しください！

https://www.wantedly.com/companies/toreta/projects