Cài CI cho Rails project bằng CircleCI

Đăng bởi Lưu Đại vào ngày 02-02-2024

1. Đôi điều về CircleCI & CI

- Trước tiên phải chia sẻ về CI, CI là một công cụ để tích hợp tự động và thường xuyên code lên source code (theo redhat). Còn hiểu nôm na là một tập hợp các hành động được thực hiện mỗi khi có source code có sự kiện xảy ra trên source code. Một trong những công cụ thường thấy nhất là github action (vì nó free, nếu dùng github thì sẵn hàng luôn không phải liên kết source code đi đâu nữa).
- CI thường được dùng để chạy unit test, kiểm tra xem code có bị lỗi convention syntax nào không
- Để chạy CI thì cần có một server riêng để build môi trường từ source code và chạy các job trên môi trường này (vd: cài gem, cài nodejs, chạy lệnh tạo db ảo, chạy test,...). Đối với github action thì các file config môi trường thường được lưu trong thư mục .workflows. CircleCI thì sẽ lưu trong thư mục .circleci
- CircleCI cung cấp một server để chạy CI. Thật ra nó còn có nhiều tính năng khác bao gồm cả Continuous Delivery (CD) nhưng trong phạm vi mình tìm hiểu để sử dụng thì mình chỉ dùng một phần chức năng của CI thôi. 

2. Cài CircleCI cho Rails project

- Yêu cầu: Phải có một Rails project sẵn (với unit test, hoặc ít nhất là file rubocop để test xem CircleCI đã chạy được chưa và file docker). Một tài khoản CircleCI nếu chưa có thì tạo trên trang circleci
- Sau khi tạo tài khoản, circleci sẽ hỏi bạn source code mà bạn muốn tích hợp CircleCI được lưu ở đâu. Nó sẽ có màn hình như ảnh dưới đây. Từ đây có thể thấy được CircleCI có đi đêm với 3 ông lớn trong ngành là GitLab, Github, BitBucket.
image.png

Vì mình dùng github nên mình chọn github và chọn đúng 1 project mình muốn liên kết thôi. Sau đó circleci bắt mình tạo 1 project tương ứng trên app của họ (có thể trùng hoặc khác tên với repo trên github cũng được) và cung cấp cho circleci 1 private key để nó có thể truy cập + tạo pull request lên source code của bạn. 
Sau bước này circleci gen ra cho mình một file config mẫu. Sau một hồi sửa để có thể dùng được thì file config của mình có dạng như sau. 
# This config was automatically generated from your source code
# Stacks detected: deps:node:.,deps:ruby:.,package_manager:yarn:
version: 2.1
orbs:
  ruby: circleci/ruby@2.0.1
jobs:
  test-ruby:
    # Install gems, run rails tests
    docker:
      - image: cimg/ruby:3.0.0-node
        environment:
          - RAILS_ENV=test
      - image: circleci/postgres:9.5-alpine
    steps:
      - checkout
      - ruby/install-deps
      - run:
          name: Wail for db
          command: dockerize -wait tcp://localhost:5432 -timeout 1m
      - run:
          name: prepare db
          command: bundle exec rails db:prepare
      - run:
          name: rails test
          command: bundle exec rspec

workflows:
  build-and-test:
    jobs:
      - test-ruby

Giải thích một chút các config của circleci: 
  • version: đây là version của circleci ở file này đang dùng circleci version 2.1
  • orbs: đây là một config mẫu của bên circleci nhằm gom nhóm lại những config thường được sử dụng để tiết kiệm thời gian config cho người dùng. 
  • jobs: đây là những bước sẽ được thực hiện khi tạo commit, push code lên các nhánh trên github. CircleCI dùng docker để tạo môi trường chạy các job nên trong jobs có mục docker. Ở đây mình dùng postgresql và ruby thôi chứ không viết cả redis vào vì redis của mình chỉ dùng để chạy backgroundjobs + cronjobs. 
  • steps: Các câu lệnh sẽ chạy trong jobs. 
- Bước cuối cùng là chuyển các biến env vào trong config trên webapp cirlceci. Vì trong code mình có sử dụng Rails credentials nếu viết biến vào file config push lên source code thì sẽ bị lộ nên tốt hơn hết là import từng biến vào trong config của circleci.
image.png