CircleCI2.0 でphan でPHPの構文解析。結果をsaddler でGithub でコメントする

# やりたいこと

+ 新規プロジェクトをPHPで作ることになりました
+ テストをしっかりやりたく、PHP でのテストには以下が有効だと結論づけました
+ [Phan](https://github.com/phan/phan)
+ 今回は、このPhanのテストをCircleCIで動かすことを目的とします

# 早速ですが実装部分

## .circleci/config.yml

__プログラム__

```yml

jobs:
  build:
    docker:
      - image: circleci/php:7.1-node-browsers 
    environment:
    working_directory: ~/repo 
    steps:
      - checkout 
      - run: sudo apt install -y zlib1g-dev ruby
      - run: sudo docker-php-ext-install zip
      - run:
          name: Install php-ast
          command: |
            cd ~
            git clone https://github.com/nikic/php-ast
            cd php-ast
            phpize
            ./configure
            make
            sudo make install
            echo -e "extension=ast.so" | sudo tee /usr/local/etc/php/php.ini > /dev/null
            cd ../
      - run: sudo composer self-update
      - run: sudo gem install bundler
      # php cache
      - restore_cache: 
          keys:
            - composer-v1-{{ checksum "composer.lock" }}
            - composer-v1-
      - run: composer install -n --prefer-dist
      - save_cache: 
          key: composer-v1-{{ checksum "composer.lock" }}
          paths:
            - vendor
      # ruby cache
      - restore_cache:
          keys:
            - bundle-v2-{{ checksum "Gemfile.lock" }}
            - bundle-v2-
      - run:
          name: Bundle Install
          command: bundle check || bundle install
      - save_cache:
          key: bundle-v2-{{ checksum "Gemfile.lock" }}
          paths:
            - vendor/bundle

      - run: ./vendor/bin/phpunit tests
      - run: ./bin/phan_inspect.sh
      - store_artifacts:
          path: docs/coverage
          destination: coverage
```

__解説__

+ 基本的にCircleCI が用意してくれた物を使ってます
+ php-ast のinstall は`command` を駆使ししてがんばります。
    + 汚いのでいいやり方あれば教えて欲しい
+ saddler を動かすために、`ruby` 入れたり、`bundler` いれたりしてます
    + ruby とPHP が入ったimage 作れよという話もありますが、基本的にCircleCIが用意してくれた物を使おうという縛りプレイ中だったので、作りませんでした
    
## composer.json

__プログラム__

```json
{
    "autoload": {
        "psr-4": {
            "Sample\\": "src/"
        }
    },
    "require": {},
    "require-dev": {
        "phpunit/phpunit": "7.0.*",
        "phan/phan": "^1.1"
    },
    "scripts": {
        "update-coverage": "vendor/bin/phpunit --bootstrap tests/bootstrap.php --configuration tests/phpunit.xml --coverage-html=docs/coverage"
    }
}

```

__解説__

+ あまり解説することないです
+ phan 書きました

## Gemfile

__プログラム__

```ruby
source "https://rubygems.org"

gem "checkstyle_filter-git"
gem "saddler"
gem "saddler-reporter-github"
```

__解説__

+ dev 限定しなかったのはCircleCI でしか使わないと思ったからです
+ dev 限定してもいいと思います

## bin/phan_inspect.sh

__プログラム__

```bash
#!/bin/bash

echo "Start"

TARGET_BRANCH=$CIRCLE_BRANCH
COMMON_PULL_REQUEST=$CIRCLE_PULL_REQUEST

if [[ ${CIRCLE_PULL_REQUEST} =~ ([0-9]+)$ ]]; then
  PULL_REQUEST_NUM=${BASH_REMATCH[1]}
fi

url="https://api.github.com/repos/$CIRCLE_PROJECT_USERNAME/$CIRCLE_PROJECT_REPONAME/pulls/$PULL_REQUEST_NUM"

TARGET_BRANCH=$(
  curl -s -H "Authorization: token $GITHUB_ACCESS_TOKEN" "$url" | jq '.base.ref' | tr -d '"'
)

TARGET_LIST=`git diff --name-only origin/$TARGET_BRANCH | grep -e '.php$'`

if [ -z "$TARGET_LIST" ]; then
    echo "PHP file not changed."
    exit 0
fi

RESULT=`vendor/bin/phan -f $TARGET_LIST -m checkstyle`

RESULT_TEXT=`echo $RESULT | bundle exec saddler report \
    --require saddler/reporter/text \
    --reporter Saddler::Reporter::Text`
if [ -n "$RESULT_TEXT" ]; then
    if [ -n "$COMMON_PULL_REQUEST" ]; then
        `echo $RESULT | bundle exec saddler report \
            --require saddler/reporter/github \
            --reporter Saddler::Reporter::Github::PullRequestReviewComment`
    fi

    echo ""
    echo "An error has been detected,this following:"
    echo "$RESULT_TEXT"
    exit 1
else
    echo "Passed"
    exit 0
fi

```

__解説__

+ Github でプルリクが来たら`phan` が動き、コメントまでつけてくれます
+ `GITHUB_ACCESS_TOKEN` をCircleCI 上の管理画面より設定して下さい
    + `private` リポジトリを想定してるので、`public` の人はいらないかも
+ 変化部分だけをレビューしてくれます
+ `Saddler::Reporter::Text` でCircleCIの実行結果にもコメントを残すようにしました

# おわりに

+ 初めてCircleCI2.0 触りましたが、凝ったことをしようとすると設定が汚くなるなと思いました
+ 一つの機能を一つのリポジトリに詰め込みすぎず、いい感じに分割できれば使いやすそうですね！