[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

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ử…