CircleCI2.0上でDangerを使ってみる

※ 12/19 以前、githubのアクセストークンの設定のところを自分のアカウントと書いてて、リンクしていただいた@chamaoさんの記事を見て、　「あっ」って、なったので文章を一部修正、スクリーンショットの追加をしました。

##導入した理由

プロジェクトによって「この作業やった時は、必ず前に〜つけて」みたいなルールが違うところがあったり、覚えるのが大変。。。
「お前それ、あげる前にちゃんと動かした？」、「TODO残ってるんだけど？？？」みたいなことを逐一言うのは正直疲れるし、実装以外の部分の指摘をするためにコミット内容に目を通すのも時間がかかる。


![pose_necchuu_computer_man2.png](https://qiita-image-store.s3.amazonaws.com/0/84002/b9be53ca-6801-f542-ff81-a249e859f46f.png)



少しでも「何か忘れてない？」チェックの負担を軽減できないかと思い、`DengerFile`と言うファイルで設定したルールの通りに自動チェックをしてくれる `Danger`を導入をしてみた。

![danger2.png](https://qiita-image-store.s3.amazonaws.com/0/84002/a37a7c56-b75a-54c2-0784-462c4ab3be8b.png)


※この記事は、CircleCI2.0が扱えると言う前提として書いてるので、CIについての解説はないです。

#導入

##1. Danger動かすためにconfig.ymlにdanger用のjobを追加する

下記を.circleci配下の.config.ymlに記述する。

```yml
version: 2

# Define the jobs for the current project.
jobs:
  danger:
    docker:
      - image: dantoml/danger:latest
        environment:
         - TZ: "/usr/share/zoneinfo/Asia/Tokyo"
         - LANG: ja_JP.UTF-8
         - LC_ALL: C.UTF-8
         - LANGUAGE: ja_JP.UTF-8
    steps:
      - checkout
      - run: gem install danger-todoist
      - run: danger
```

* このJobでやっていること
    * dockerを使ってDangerが動く環境を丸っと持ってくる
    * コードをチェックアウトしてくる
    * dangerを実行

※ DangerのDockerImageはロケールがjaになっていない・文字コードがASCⅡになっているので、
environmentに下記設定をする必要がある。

```
environment:
         - TZ: "/usr/share/zoneinfo/Asia/Tokyo"
         - LANG: ja_JP.UTF-8
         - LC_ALL: C.UTF-8
         - LANGUAGE: ja_JP.UTF-8
```

##2. Dagnerfileを生成する
### Dangerfileとは
PullRequest時にチェックする項目(ルール)を記述するファイルである。

### ファイルを生成
`$ danger` コマンド実行時に、このDangerfileと言う設定ファイルを見に行くので、基本的にはプロジェクトのRootに(サブディレクトリでも行けるような情報もちらっとみた気がする)
テキストファイルを作成し、名前をDangerfileに変更する。

<img width="119" alt="スクリーンショット 2018-10-03 15.12.53.png" src="https://qiita-image-store.s3.amazonaws.com/0/84002/b2d87621-8c81-59cb-4dfa-305c334da145.png">


##3. DangerFileにルールを記述する

DangerfileにはRubyを使ってルールを記述していく。
※danger-jsとういうjavascript版も存在する

ルールには警告「warn」と失敗[failure]又は[fail]がある。


以下は、チェック時に、PullReqを出した先がmasterだった場合Buildを失敗扱いにすると言う記述。

```ruby
fail("The merge destination is not a `develop branch`") if github.branch_for_base == "master"
```

以下は、チェック時に、PullRequestのDescriptionが書かれていないのを警告扱いにすると言う記述。

```ruby
warn("There is no description for PullRequest. Please enter a description.") if !github.pr_body.include?
```


とりあえずルールざっくりと設定。
あくまでお試しなので、実際に使うときは条件を変える必要がある。

```ruby

#Ciスキップ
if git.commits.first.message =~ /\[ci skip\]/ || github.pr_body =~ /\[ci skip\]/
  warn "Test stage is skipped"
  File.open(".ci_skip", "w")
end

#developブランチではなく、masterブランチにマージしようとしていなかの確認
fail("The merge destination is not a `develop branch`") if github.branch_for_base == "master"

#PullRequestのDescription有無を確認
warn("There is no description for PullRequest. Please enter a description.") if !github.pr_body.include? "Description"

#PullRequestにラベルが貼られているかを確認
fail "Please add labels to this PR" if github.pr_labels.empty?

#PullRequestのタイトルにfeat(client)が含まれているか確認
if github.pr_title =~ /\[feat(client)\]/

else
  fail("PullRequest's title is not in the specified format")
end

```

##4. GithubApiを使うための準備
Dangerfileに記述したルールに、githubのApiを使っているためアクセストークンを生成する必要がある。
（`github.pr_body.include`とか　 `github.pr_labels.empty`とか）

※12/19　修正と追加

まず、Dangerを扱うにあたって専用のGithubアカウントを用意する。
(公式に以下のような記載がったので修正しました。)
![スクリーンショット_2018-12-19_10_43_28.png](https://qiita-image-store.s3.amazonaws.com/0/84002/ed3a3bb3-4100-716a-ca9f-bb4c9e1d70fa.png)


次に、Dangerに使用するGithubアカウントの~~自分~~のプロフィールページを開く。
プロフィールの左側にメニューが表示されているので、一番下の Developer settingsをクリックする。
![スクリーンショット_2018-10-02_17_49_03.png](https://qiita-image-store.s3.amazonaws.com/0/84002/fdca023d-7f01-673b-1d30-16dea2e759e4.png)

OAuth Appsに切り替わるので、次に Personal acces tokensをクリックする。
![スクリーンショット_2018-10-02_17_59_18.png](https://qiita-image-store.s3.amazonaws.com/0/84002/ae91acf1-d307-63fc-4e67-791d3bcfce78.png)

AccessToken 一覧が表示され、ページの右上辺りに[Generate new token]と言う名前でボタンが
表示されるのでクリックする。
![スクリーンショット_2018-10-02_18_10_27.png](https://qiita-image-store.s3.amazonaws.com/0/84002/99b48381-9142-4b88-5cd5-2b561d4add3e.png)


次に下記の公式の引用を元に、アクセストークンに必要な権限を付与する。
権限付与に関しては以下のように公式から推奨されているものがある。

>#TOKENS FOR OSS PROJECTS
We recommend giving the token the smallest scope possible. This means just public_repo, this scopes limits Danger’s abilities to just writing comments on OSS projects. Because the token can be quite easily be extracted from the CI environment, this minimizes the chance for bad actors to cause chaos with it.
#TOKENS FOR CLOSED SOURCE PROJECTS
We recommend giving access to the whole repo scope, and its children.

引用元 : Danger Getting Set Up
引用元URL :https://danger.systems/guides/getting_started.html

簡単に要約すると、
公開リポジトリについては 可能な限り最小限の権限を付与するpublic_repoを、
非公開リポジトリについては、repoを付与することを推奨とする。


![スクリーンショット_2018-10-02_18_30_59.png](https://qiita-image-store.s3.amazonaws.com/0/84002/e2f3a8a8-3973-d53c-7e13-5004e6dc021e.png)

作成が完了すると、以下のようにトークンが生成される。
<img width="748" alt="スクリーンショット 2018-10-03 16.06.31.png" src="https://qiita-image-store.s3.amazonaws.com/0/84002/1685a994-8e67-3547-aa00-f24671bef4ae.png">

次に、生成したtokenをCircleCiの`Environment Variables`に`DANGER_GITHUB_API_TOKEN `と言う名前で登録する。

Environment Variablesへの登録の仕方は、
まず、CircleCiのプロジェクト画面の左上にある歯車マークをクリックする。

<img width="1147" alt="スクリーンショット_2018-10-03_19_52_13.png" src="https://qiita-image-store.s3.amazonaws.com/0/84002/2ac3a888-c780-fd98-83be-7cfb62c9396a.png">

プロジェクトの設定画面が表示され、左側にメニューが表示される。
メニューから`Environment Variables`を選択する。

<img width="1169" alt="スクリーンショット_2018-10-03_19_54_02.png" src="https://qiita-image-store.s3.amazonaws.com/0/84002/7adeb998-940c-aa4a-ed26-5336ac3edb6a.png">

環境変数一覧の画面に遷移後、「add Variable」ボタンをクリックする。

<img width="1145" alt="スクリーンショット_2018-10-03_19_58_06.png" src="https://qiita-image-store.s3.amazonaws.com/0/84002/7ad81abd-9f94-05ec-1664-0971349326d7.png">

Nameに`DANGER_GITHUB_API_TOKEN`
ValueにToken生成時に表示された値を入れる。
忘れてしまった場合は、忘れたTokenの編集画面の「Regenerate token」で新しいtoken生成することができる。 
![スクリーンショット_2018-10-05_11_02_47.png](https://qiita-image-store.s3.amazonaws.com/0/84002/3a60b841-2fca-8af0-be94-7b5bbc524de2.png)


##確認
実際にPullReqestを出して動作を確認する。

まずは、CircleCiの方を見る。

![スクリーンショット 2018-10-02 10.49.03.png](https://qiita-image-store.s3.amazonaws.com/0/84002/8cbfbe9f-3d58-9b3e-cd32-2a3415a24417.png)

DangerFileで設定した、Failに設定した項目3つと、warnで出力するようにした項目1つが出力されていることが確認できる。

次に、githubの方を確認する。

<img width="713" alt="スクリーンショット 2018-10-02 10.52.20.png" src="https://qiita-image-store.s3.amazonaws.com/0/84002/b8b04039-83f0-3d20-876a-800d20fb3150.png">


こちらでも、設定した通りに、failで設定した項目には「禁止マーク」がつき、warnに設定した項目には「注意マーク」がついて出力される。

次に、Dangerにて指摘されている部分を一個、修正してみる。

まずは、PRにラベルがついていないので、適当にLabelをつける。
![スクリーンショット 2018-10-02 11.06.34.png](https://qiita-image-store.s3.amazonaws.com/0/84002/374211be-acbe-533b-90d4-c5ae8f32ff26.png)

そして、再度CIを回す

###CicleCi側
![スクリーンショット 2018-10-02 11.16.12.png](https://qiita-image-store.s3.amazonaws.com/0/84002/0a4062da-d8d9-fbb9-ecf0-5819001ea1ff.png)

###Github側
<img width="707" alt="スクリーンショット 2018-10-02 11.16.23.png" src="https://qiita-image-store.s3.amazonaws.com/0/84002/295c6eba-59d7-a4da-1765-235c2a40128e.png">

上記のスクリーンショットのように修正されると、確認が取れたものから指摘項目が消えていく。

Workflowの組み方次第では、Dangerによってチェックされた項目を全て修正しないとBuildさせないマンとかできるので、細かい指摘事項修正してPushするごとに長時間のBuildが走るなんてことを防ぐことができそう。
(生産性が下がらない程度に程々に設定しよう)


##色々試してみよう

Dangerには、色々プラグインが用意されていて、LGTMが出せるやつや・Shellスクリプトをチェックしてくれるやつ、
TODOとついた箇所を探して、リスト化、警告してくれるもの等が存在する。

以下、公式サイトのPluginから確認できる。
https://danger.systems/ruby/

Dangerのプラグインを使うときは、実行する前に

```
steps:
  - run: gem install `プラグイン名`
```
を実行してれば使える。(本当はdangerのimageをforkして追加 or 自作した方がいいのだろうけど。。。)


また、DagnerのPluginは自作することも可能なので、DangerFileに大量に書いてたものを、メソッドの呼び出しで一括でチェックを走らせるプラグインとか、プロジェクト毎にこのプラグイン入れて、DangerFileに書いておけば良いといといったことが出来るので便利。

公式にてプラグインのテンプレートは用意されている。
https://github.com/danger/danger-plugin-template

##最後に
DangerFileに記載するルールについては、結構色々な人がブログに書いていたり、
勉強会のスライドも存在していたのでその辺を参考にしたり、周りの人によく注意される部分などを、設定してみるところから
始めみてはいかがでしょうか。(自分の場合、昔はよく某vvさんとか、某egskさんにべしべしされてたなと、懐かしみを得ながら設定ファイルを書いていました。)

やりようによっては、テストが実行されていたか？みたいなテストの実行時の成果物が新しいかどうか、コードスタイルもチェックできるだとか。

それでは、良い継続的インテグレーションライフを。