CircleCI config.yml ひな型 Rails 6 / PostgreSQL / Rspec

※[orbと最新のimageを使った版](https://qiita.com/kazutosato/items/3f08a4da350a395f3bd2)も参照してください。

次のページに以前あったサンプルをコピペして改造したものです（現在は内容がだいぶ変わっています）。
https://circleci.com/docs/2.0/language-ruby/

```yml:config.yml
version: 2.1
orbs:
  ruby: circleci/ruby@0.1.2 

jobs:
  build:
    docker:
      - image: circleci/ruby:2.6.6-buster-node-browsers
        environment:
          RAILS_ENV: test
          PGHOST: 127.0.0.1
          PGUSER: circleci
          TZ: "/usr/share/zoneinfo/Asia/Tokyo"
      - image: circleci/postgres:11.7
        environment:
          POSTGRES_USER: circleci
          POSTGRES_DB: blog_rails6_test
          POSTGRES_HOST_AUTH_METHOD: trust # パスワードなし
          TZ: "/usr/share/zoneinfo/Asia/Tokyo"
    steps:
      - checkout
      - restore_cache:
          keys:
            - blog-bundle-v1-{{ checksum "Gemfile.lock" }}-{{ checksum "yarn.lock" }}
            - blog-bundle-v1-
      - run:
          name: Bundler and Yarn
          command: |
            gem install bundler -v '2.1.4' -N
            bundle -v
            bundle install --jobs=3 --retry=3 --path vendor/bundle
            yarn install
      - save_cache:
          paths:
            - ./vendor/bundle
            - ./node_modules
          key: blog-bundle-v1-{{ checksum "Gemfile.lock" }}-{{ checksum "yarn.lock" }}
      - run:
          name: DB Initializing
          command: |
            dockerize -wait tcp://localhost:5432 -timeout 1m
            bundle exec rake db:schema:load
      - run:
          name: rspec
          command: |
            bundle exec rspec --format RspecJunitFormatter \
                              --out test_results/rspec.xml \
                              --format documentation
      - store_test_results:
          path: test_results
```

以下、自分向け解説。

<del>[orbs](https://circleci.com/orbs/) とは何だかわからない。あとで調べる。</del> → 新しい記事 [orbと最新のimageを使った版](https://qiita.com/kazutosato/items/3f08a4da350a395f3bd2) へ。

```yaml
orbs:
  ruby: circleci/ruby@0.1.2 
```

E2Eテスト（headless Chrome）を使う場合は、「-node-browsers」を選ぶこと。

```yaml
      - image: circleci/ruby:2.6.6-buster-node-browsers
```

PostgreSQLをパスワードなしで使う場合はこの環境変数が必要。

```yaml
          POSTGRES_HOST_AUTH_METHOD: trust # パスワードなし
```

Webpackerを使っている場合は、node_modulesのキャッシュを作る。Gemfile.lockに加えてyarn.lockの変更で更新されるようにする。

```yaml
      - restore_cache:
          keys:
            - blog-bundle-v1-{{ checksum "Gemfile.lock" }}-{{ checksum "yarn.lock" }}
            - blog-bundle-v1-
# 中略
      - save_cache:
          paths:
            - ./vendor/bundle
            - ./node_modules
          key: blog-bundle-v1-{{ checksum "Gemfile.lock" }}-{{ checksum "yarn.lock" }}
```

Bundlerのバージョンを上げているときはインストールが必要。

```yaml
            gem install bundler -v '2.1.4' -N
```

PostgreSQLが立ち上がるのを待つ。本当に必要かどうかわからない。

```yaml
            dockerize -wait tcp://localhost:5432 -timeout 1m
```

[RSpec JUnit Formatter](https://github.com/sj26/rspec_junit_formatter) の形式でログを出力し、`store_test_results` で保存する。すると、CircleCIのサイトで次のリンクから結果が見えるようになる。

<img width="500" alt="circleci-test-results.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308595/01167a0b-b9c5-665b-6143-db30aa2cbb45.png">


```yaml
      - run:
          name: rspec
          command: |
            bundle exec rspec --format RspecJunitFormatter \
                              --out test_results/rspec.xml \
                              --format documentation
      - store_test_results:
          path: test_results
```

GemfileでRSpec JUnit Formatterを入れておく。

```Gemfile
group :test do
# 略
  gem 'rspec_junit_formatter'
end
```

## パラレル実行

parallelism に数を指定したうえで、

```yaml
jobs:
  build:
    parallelism: 2
```

`circleci tests` コマンドを埋め込んでspecファイルを分ける。`circleci tests glob` に渡す引数の書式は、Rubyの[Dir.glob](https://docs.ruby-lang.org/ja/latest/method/Dir/s/=5b=5d.html)と同じ。

```yaml
      - run:
          name: rspec
          command: |
            bundle exec rspec --format RspecJunitFormatter \
                              --out test_results/rspec.xml \
                              --format documentation \
                              $(circleci tests glob "spec/**/*_spec.rb" | circleci tests split)
```

特定のディレクトリを除きたいときは、次のような感じで。

```yaml
      - run:
          name: rspec
          command: |
            bundle exec rspec --format RspecJunitFormatter \
                              --out test_results/rspec.xml \
                              --format documentation \
                              $(circleci tests glob "spec/{controllers,forms,models,services}/**/*_spec.rb" | circleci tests split)
```

## structure.sqlを使っている場合

structure.sqlを使っている場合は、postgresql-clientのインストールが必要。

```yaml
      - run:
          # db:structure:loadに必要
          name: Install postgresql-client 
          command: |
            sudo apt-get update || true
            sudo apt install -y postgresql-client
```

db:schema:load の代わりに db:structure:load とする。

```yaml
      - run:
          name: DB Initializing
          command: |
            dockerize -wait tcp://localhost:5432 -timeout 1m
            bundle exec rake db:structure:load
```

## READMEにバッジを表示する

```README.md
[![blog-rails6-vuejs](https://circleci.com/gh/kazubon/blog-rails6-vuejs.svg?style=shield)](https://app.circleci.com/pipelines/github/kazubon/blog-rails6-vuejs)
```