2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?