[ROR] Hướng dẫn setup CircleCI & Code Quality

Step 1: Access https://circleci.com/ and authorize a Github, Gitlab or Bitbucket account. I will use a Github account.

Step 2: Click Go to Application in Home page -> Projects

Step 3: Click to Setup Project button in the right Repo you want to setup

Step 4: Select first Radio Button -> Set Up Project

After setup, click Dashboard and display as below

Step 5: Click Project Setting -> SSH Key and check if the ssh key has been linked or not.

Step 6: If you using Git Submodule, please create a Additional SSH Keys

  1. Open terminal and run ssh-keygen -t ed25519 -C "Circle CI".
  2. Click Add SSH Key and enter
  • Hostname: github.com
  • Private Key: cat minh_id_ed25519, copy and paste
  1. Back to Github, select Repository Shared submodule -> Settings -> Deploy Keys -> Add deploy key
  2. Enter Title and Key -> Add Key

Step 7: Back to project setup config CircleCI and Danger

  1. Add to Gemfile
Ruby
gem 'brakeman', require: false
gem 'danger', '9.2.0'
# A Danger plugin to lint Ruby files through danger-brakeman_scanner.</em>
gem 'danger-brakeman_scanner', '0.1.1'
# A Danger plugin to lint Ruby files through rails_best_practices.</em>
gem 'danger-rails_best_practices', '0.1.3'
# A Danger plugin to lint Ruby files through Reek.</em>
gem 'danger-reek', '0.3.0'
# A Danger plugin for running Ruby files through Rubocop.</em>
gem 'danger-rubocop', '0.10.0'
# A Danger plugin to report code coverage generated by SimpleCov in JSON format.</em>
gem 'danger-simplecov_json', '0.3.0'
  1. Create file in .circleci/config.yml and paste code
Ruby
# Best practises:
#   [https://www.netguru.com/blog/top-10-best-practises-to-benefit-more-form-circleci]
#   [https://circleci.com/blog/six-optimization-tips-for-your-config/]
references:
  working_directory: &working_directory ~/quinblog
  images:
    base_image: &base_image
      image: cimg/ruby:3.2.1
      environment:
        TZ: /usr/share/zoneinfo/Asia/Tokyo
        BUNDLE_JOBS: 4
        BUNDLE_RETRY: 3
        BUNDLE_PATH: vendor/bundle
        GEM_PATH: vendor/bundle
        RAILS_ENV: test
    db_image: &db_image
      image: cimg/postgres:14.4
      environment:
        POSTGRES_USER: postgres
        POSTGRES_DB: quinblog_test
        POSTGRES_PASSWORD: postgres
    redis_image: &redis_image
      image: cimg/redis:5.0
    mongodb_image: &mongodb_image
      image: circleci/mongo:3.6
  commands:
    move_database_yml: &move_database_yml
      name: Move database_yml
      command: mv config/database.ci.yml config/database.yml
    move_mongoid_yml: &move_mongoid_yml
      name: Move mongoid_yml
      command: mv config/mongoid.ci.yml config/mongoid.yml
    sync_git_submodule: &sync_git_submodule
      name: Sync git submodule
      command: |
        git submodule sync --recursive --quiet
        git submodule update --init --checkout --recursive --quiet

# Use the latest 2.1 version of CircleCI pipeline process engine.
# See: https://circleci.com/docs/2.0/configuration-reference
version: 2.1

# Orbs are reusable packages of CircleCI configuration that you may share across projects, enabling you to create encapsulated, parameterized commands, jobs, and executors that can be used across multiple projects.
# See: https://circleci.com/docs/2.0/orb-intro/
orbs:
  ruby: circleci/ruby@1.8.0

# Define a job to be invoked later in a workflow.
# See: https://circleci.com/docs/2.0/configuration-reference/#jobs
jobs:
  build:
    working_directory: *working_directory
    resource_class: small
    parallelism: 1
    docker:
      - *base_image
    steps:
      - add_ssh_keys:
          fingerprints:
            - '7c:72:77:4f:79:12:cb:af:c9:84:7b:d1:ab:24:69:41'
      - checkout

      - run: *move_database_yml
      - run: *move_mongoid_yml
      - run: *sync_git_submodule
      - run:
          name: Disabled auto completion
          command: echo 'IRB.conf[:USE_AUTOCOMPLETE] = false' >> ~/.irbrc

      # Restoring and saving cache
      - ruby/install-deps

      - persist_to_workspace:
          root: *working_directory
          paths:
            - ./*

  test:
    working_directory: *working_directory
    resource_class: small
    parallelism: 2
    docker:
      - *base_image
      - *db_image
      - *mongodb_image
      - *redis_image
    steps:
      - attach_workspace:
          at: *working_directory

      - run:
          name: Wait for Postgres DB
          command: dockerize -wait tcp://localhost:5432 -timeout 1m

      - run:
          name: Wait for Mongo DB
          command: dockerize -wait tcp://localhost:27017 -timeout 1m

      - run:
          name: Wait for Redis DB
          command: dockerize -wait tcp://localhost:6379 -timeout 1m

      - run:
          name: Migration DB
          command: |
            bundle exec rails db:schema:load:primary --trace
            bundle exec rails db:create:universal
            bundle exec rails db:schema:load:universal --trace

      - run:
          name: Run rspec
          command: |
            TESTFILES=$(circleci tests glob "spec/**/*_spec.rb" | circleci tests split --split-by=timings --timings-type=classname)
            echo ${TESTFILES}
            bundle exec rspec --profile 10 \
                              --format progress \
                              --format RspecJunitFormatter --out /tmp/test-results/rspec/rspec.xml \
                              ${TESTFILES}

      # Collect test data
      # See: https://circleci.com/docs/collect-test-data
      # See: https://circleci.com/blog/how-to-output-junit-tests-through-circleci-2-0-for-expanded-insights/
      - store_test_results:
          path: /tmp/test-results/rspec/

      - run:
          name: Run danger
          command: bundle exec danger --danger_id=test

  lint:
    working_directory: *working_directory
    resource_class: small
    parallelism: 1
    docker:
      - *base_image
    steps:
      - attach_workspace:
          at: *working_directory

      - run:
          name: Run danger
          command: bundle exec danger --danger_id=lint

# Invoke jobs via workflows
# See: https://circleci.com/docs/2.0/configuration-reference/#workflows
workflows:
  build_and_test:
    jobs:
      - build
      - test:
          context:
            - ctx_renew_api_company
          requires:
            - build
      - lint:
          context:
            - ctx_renew_api_company
          requires:
            - build

Step 8: Config Danger. Create Dangerfile and paste code below:

Ruby
# frozen_string_literal: true

case ENV.fetch('CIRCLE_JOB', nil)

when 'lint'

  ### for Rubocop ###

  rubocop.lint(force_exclusion: true, inline_comment: true)

  ### for rails_best_practices ###

  # rails_best_practices.lint

  ### for Reek ###

  # reek.lint

  ### for brakeman ###

  brakeman.run('.')

  # Ensure there is a summary for a pr

  failure('Please provide a summary in the Pull Request description') if     github.pr_body.include?('___WRITE_HERE___')

  # Ensure that all prs have an assignee

  failure('This PR does not have any assignees yet.') unless github.pr_json['assignee']

  # Warn really big diffs

  warn('We cannot handle the scale of this PR') if git.lines_of_code > 300

  # Note when a pr cannot be manually merged, which goes away when you can

  warn('This PR cannot be merged yet.', sticky: false) unless github.pr_json['mergeable']

 when 'test'

  ### for SimpleCov ###

  coverage_file = 'coverage/coverage.json'

  simplecov.report(coverage_file, sticky: false)

  simplecov.individual_report(coverage_file, Dir.pwd)

end

Step 9: Back to CircleCI -> Click Organization Settings -> Contexts -> Create Context

Step 10: Enter name Context and click Create Context

Step 11: Click Context Name created and add environment for project such as RAILS_MASTER_KEY, RAILS_ENV, RACK_ENV, DANGER_GITHUB_API_TOKEN

Click Add Environment and enter value as below:

Note:

  • RAILS_MASTER_KEY: Open file config/crendentials/test.key on project and copy it.
  • RAILS_ENV: test
  • RACK_ENV: test

After add 3 environments, it will displayed as below:

Step 12: Create DANGER_GITHUB_API_TOKEN

  1. Access https://github.com/settings/tokens and click Generate new token
  1. Write Note and Select Expiration, Scope. I choose Expiration 90 days and click repo
  1. Click Generate Token and Copy this.
  1. Back to Context and Add DANGER_GITHUB_API_TOKEN

Step 12: Push code and runnnnn

0 Shares:
Leave a Reply

Your email address will not be published. Required fields are marked *

You May Also Like
Read More

What’s new in Ruby 3.3.0

Table of Contents Hide YJITRJITIRBRangeRails Range#overlaps?(range)Ruby < 3.3Ruby 3.3Tham khảo Là một developer có niềm đam mê sâu…
Read More

Sentry for Rails

Table of Contents Hide Đặt vấn đềGiới thiệu SentryConfig Sentry cho Rails appSummary Đặt vấn đề Trong quá…
Read More

Setup slack notifications in Rails

Table of Contents Hide Setup Slack:Setup Rails: Slack là một phần mềm Worksplace sử dụng thông dụng rộng…
Read More

Building a GraphQL API in Rails

Table of Contents Hide GraphQL là gì?Thiết Lập Dự Án RailsThêm DependenciesTạo Schema GraphQLĐịnh Nghĩa Các LoạiKiểm Thử…