LoginSignup
2
1

More than 3 years have passed since last update.

CircleCIでRubocopとRSpecを走らせてECSにデプロイする

Last updated at Posted at 2020-11-07

この記事で扱うこと

  • CircleCIでRubocopとRSpecを使用した自動テスト
  • CircleCI orbsを使用したCI/CDパイプラインの構築

扱わないこと

  • CircleCIの初期設定
  • RubocopやRSpecの導入方法

config.ymlの完成形

以下の公式ページを参考にしています
https://circleci.com/docs/ja/2.0/configuration-reference/#requires

version: 2.1

orbs:
  aws-ecr: circleci/aws-ecr@6.12.2
  aws-ecs: circleci/aws-ecs@1.3.0

references:
  defaults: &defaults
    working_directory: ~/myqpp

  ruby-docker-image: &ruby-docker-image
    #steps共通のプライマリコンテナ
    image: circleci/ruby:2.6.4-node-browsers
    #プライマリコンテナの環境変数
    environment:
      RAILS_ENV: test
      MYSQL_HOST: 127.0.0.1
      MYSQL_USERNAME: "db_name"
      MYSQL_PASSWORD: ""
      MYSQL_PORT: 3306

  mysql-docker-image: &mysql-docker-image
    image: circleci/mysql:8.0.19
    command: [--default-authentication-plugin=mysql_native_password]
    environment:
      MYSQL_ALLOW_EMPTY_PASSWORD: true
      MYSQL_ROOT_HOST: "%"

jobs:
  checkout_code:
    <<: *defaults
    docker:
      - *ruby-docker-image
      - *mysql-docker-image
    steps:
      - checkout
      - save_cache:
          key: v1-repo-{{ .Environment.CIRCLE_SHA1 }}
          paths:
            - ~/project

  test:
    <<: *defaults
    docker:
      - *ruby-docker-image
      - *mysql-docker-image
    steps:
      #ソースコードをworking dirにチェックアウト
      - checkout
      - restore_cache:
          keys:
            - v1-dependencies-{{ checksum "Gemfile.lock" }}
            - v1-dependencies-
      #ruby依存関係
      - run: gem install bundler -v 2.1.4
      - run: bundle install --jobs=4 --retry=3 --path vendor/bundle
      - save_cache:
          key: vi-dependencies-{{ checksum "Gemfile.lock" }}
          paths:
            - ./vendor/bundle
      #DBの待機/セットアップ
      - run: mv -f ./config/database.yml.ci ./config/database.yml
      - run: dockerize -wait tcp://127.0.0.1:3306 -timeout 120s
      - run: bundle exec rails db:create db:schema:load --trace
      #Rubocop自動化
      - run:
          name: start RuboCop
          command: bundle exec rubocop
      #RSpec自動化
      - run:
          name: start RSpec
          command: |
            mkdir /tmp/test-reports
            TEST_FILES="$(circleci tests glob "spec/**/*_spec.rb" | \
              circleci tests split --split-by=timings)"
            bundle exec rspec \
              --format progress \
              --format RspecJunitFormatter \
              --out /tmp/test-results/rspec.xml \
              --format progress \
              $TEST_FILES
      #レポートと結果を保存
      - store_artifacts:
          path: /tmp/test-reports
          destination: tr1
      - store_test_results:
          path: /tmp/test-reports

workflows:
  version: 2.1
  test_code:
    jobs:
      - checkout_code
      - test:
          requires:
            - checkout_code

  # ECRとECSを使用してRailsのデプロイ
  build-and-deploy-rails:
    jobs:
      - aws-ecr/build-and-push-image:
          filters:
            branches:
              only: master
          account-url: AWS_ECR_ACCOUNT_URL
          region: AWS_REGION
          aws-access-key-id: AWS_ACCESS_KEY_ID
          aws-secret-access-key: AWS_SECRET_ACCESS_KEY
          extra-build-args: "--build-arg RAILS_MASTER_KEY=${RAILS_MASTER_KEY}"
          create-repo: true
          dockerfile: ./Dockerfile
          repo: "${AWS_RESOURCE_NAME_PREFIX_WEB}"
          tag: "${CIRCLE_SHA1}"
      - aws-ecs/deploy-service-update:
          requires:
            - aws-ecr/build-and-push-image
          family: "${ECS_TASK}"
          cluster-name: "${ECS_ARN}"
          service-name: "${ECS_SERVICE}"
          container-image-name-updates: "container=${AWS_RESOURCE_NAME_PREFIX_WEB},tag=${CIRCLE_SHA1}"

  #nginxのデプロイ
  build-and-deploy-nginx:
    jobs:
      - aws-ecr/build-and-push-image:
          filters:
            branches:
              only: master
          account-url: AWS_ECR_ACCOUNT_URL
          region: AWS_REGION
          aws-access-key-id: AWS_ACCESS_KEY_ID
          aws-secret-access-key: AWS_SECRET_ACCESS_KEY
          create-repo: true
          dockerfile: ./nginx/Dockerfile
          repo: "${AWS_RESOURCE_NAME_PREFIX_NGINX}"
          tag: "${CIRCLE_SHA1}"
      - aws-ecs/deploy-service-update:
          requires:
            - aws-ecr/build-and-push-image
          family: "${ECS_TASK}"
          cluster-name: "${ECS_ARN}"
          service-name: "${ECS_SERVICE}"
          container-image-name-updates: "container=${AWS_RESOURCE_NAME_PREFIX_NGINX},tag=${CIRCLE_SHA1}"

jobsで2つの実行処理を設定して、workflowで2つのjobの並列実行を定義しています。

自動テスト

RSpecを実行する

以下の公式リファレンスが有用です。
https://circleci.com/docs/ja/2.0/language-ruby/

このとき注意する必要があるのは、MySQL8以上を使用している方です。
8.0以降で認証方法が変わったようなので以下を追加することで対応します。

image: circleci/mysql:8.0.19
    command: [--default-authentication-plugin=mysql_native_password] #追加

orbsを使用したビルド&デプロイ

以下の公式リファレンスを読めばECSにデプロイできます
https://circleci.com/docs/ja/2.0/ecs-ecr/

ここで気をつけることはCircleCIで設定した環境変数をしっかり対応させることです。
環境変数さえ正しく設定できていればCI/CDパイプラインの構築ができます。

config.ymlをリファクタリングする

繰り返し使用している箇所に関しては、可読性を高めるためにリファクタリングしています。

&(アンカー) で定義
*(エイリアス) で定義したものを実行

おまけ

以下の公式からCircleCI CLIをインストール。
https://circleci.com/docs/ja/2.0/local-cli/

(Mac/Linuxの場合)
curl -fLSs https://circle.ci/cli | bash

このCircleCI CLIで設定ファイルが有効かチェックすることができます。

$ circleci config validate

記事を読んでいただきありがとうございました

CircleCIは日本語のドキュメントもあり設定ファイルの書き方、
さらにはRSpec等のテスト実行の設定に関してもしっかり記載があります。

日本語ドキュメントが用意されているありがたみを感じながらこの記事も書きました。

参考

https://discuss.circleci.com/t/solved-mysql-8-0-without-mysql2-authentication-plugin-caching-sha2-password-cannot-be-loaded/25791

https://patorash.hatenablog.com/entry/2018/06/24/122210

https://circleci.com/docs/ja/2.0/configuration-reference/#requires

https://circleci.com/docs/ja/2.0/workflows/

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1