- CI là viết tắt của Continuous Integration (Tích hợp liên tục)
- CI là phương pháp phát triển phần mềm đòi hỏi các thành viên trong nhóm phải tải code của họ lên kho lưu trữ thường xuyên, lý tưởng là nhiều lần trong ngày.
- Mỗi lần họ làm, mã được xác minh bởi một bản dựng tự động, bộ kiểm tra chạy các công cụ phân tích mã tĩnh chuyên dụng kiểm tra các lỗ hổng bảo mật, lỗi và tất cả các loại không chính xác.
- Điều này rất tốt cho cả nhóm giúp giảm bớt vấn đề và phát triển phần mềm nhanh hơn
Thông thường, các lập trình viên thường làm việc độc lập trong 1 thời gian dài và chỉ merge code vào nhánh master khi họ đã hoàn thành công việc. Chưa kể đến sau khi merge còn cần phải chờ review, có khi phải đợi đến vài ngày hay cả tuần. Điều này dẫn đến việc merge code gặp khó khăn, tiêu tốn nhiều thời gian, và đồng thời cũng tạo ra nhiều bugs, conflicts... khi mà code không được cập nhật trong thời gian dài.
CI giúp tìm ra bug ngay từ sớm trong quá trình phát triển, giúp việc sửa chữa tốn ít công sức hơn, từ đó cải thiện chất lượng phần mềm, giảm thời gian review code, đồng thời rút ngắn thời gian release các chức năng mới của sản phẩm. Việc test tự động được chạy với mỗi lần commit hay pull, đảm bảo nhánh master luôn trong trạng thái ổn định, không bug.
Với continuos integration, lập trình viên thường sử dụng git để commit hay merge code của họ vào các central repo như GitHub, GitLab...
Trên hình là 1 workflow phổ biến của CI. Thường thì mình sẽ thêm 1 bước là chạy test tại local trước, kiểm tra thật kỹ code của mình, khi xác định không có lỗi thì mới push lên. Làm như vậy sẽ giảm số lần test trên server, vì CI được dùng chung cho cả team, tài nguyên có hạn, nếu quá nhiều build cùng lúc thì sẽ có người phải chờ, và tất nhiên là chẳng ai muốn phải chờ rồi đúng không . Hơn nữa việc đó cũng cho thấy bản thân là người cẩn thận, sẽ được đồng nghiệp đánh giá cao hơn . Sau khi push code lên, thông thường sẽ là gửi pull request vào nhánh master. Lúc này trên server sẽ tự động build và chạy test. Nếu như có lỗi xảy ra thì sẽ được thông báo cho các thành viên trong project, người chịu trách nhiệm cho pull đó ngay lập tức sửa code rồi push lên lần nữa, cứ lặp lại như vậy cho tới khi tất cả các test đều thành công. Tất nhiên đây chỉ là thông qua các test case đã được viết trước, còn về logic của đoạn code thì vẫn cần có người review, nếu ok thì lúc đó mới được merge vào nhánh master.
-
Sau đó bạn clone repository về máy bằng lệnh
-
git clone YOUR_REPOSITORY_URL
Thực hiện theo các hướng dẫn bên dưới để tạo tài khoản CircleCI được liên kết với tài khoản Github và để thiết lập CI cho dự án Ruby on Rails.
- Vào trang web chính thức của CircleCI
- Nhấp vào "Sign up with Github"
Bạn sẽ được chuyển hướng đến bảng điều khiển CircleCI, Trong tab dự án, chọn "Add projects".
Trong thư mục gốc của dự án, tạo tệp cấu hình CircleCI.
cd path/to/your/project/root
mkdir .circleci
touch .circleci / config.yml
Mở tệp cấu hình CircleCI, Mình sẽ config với MySQL, RSpec, RuboCop, Brakeman, Rails Best Practices
Ruby on Rails với MySQL trên CircleCI
MySQL là lựa chọn phổ biến thứ hai cho các ứng dụng Ruby on Rails, chỉ sau PostgreSQL.
Để CircleCI hoạt động, bạn sẽ cần một thiết lập cụ thể trong tệp config/database.yml. Lưu ý rằng dotenv-rails gem được sử dụng.
config/database.yml
default: &default
adapter: mysql2
encoding: utf8
pool: <%= ENV['DB_POOL'] %>
username: <%= ENV['DB_USERNAME'] %>
password: <%= ENV['DB_PASSWORD'] %>
host: <%= ENV['DB_HOST'] %>
port: 3306
development:
<<: *default
database: connect_circleci_demo_development
test:
<<: *default
database: connect_circleci_demo_test
production:
<<: *default
database: connect_circleci_demo_production
.circleci/config.yml
# Ruby CircleCI 2.0 configuration file
#
# Check https://circleci.com/docs/2.0/language-ruby/ for more details
#
version: 2
jobs:
build:
parallelism: 1
working_directory: ~/Documents/project/app
docker:
- image: circleci/ruby:2.6.5-node
environment:
PGHOST: 127.0.0.1
PGUSER: app
RAILS_ENV: test
- image: circleci/postgres:10-alpine-ram
environment:
POSTGRES_USER: app
POSTGRES_DB: test_coding_test
POSTGRES_PASSWORD: ''
- image: redis
- image: circleci/node:8.11-browsers
steps:
- checkout
- run:
name: Update Node.js
command: |
curl -sSL "https://nodejs.org/dist/v10.16.0/node-v10.16.0-linux-x64.tar.xz" | sudo tar --strip-components=2 -xJ -C /usr/local/bin/ node-v10.16.0-linux-x64/bin/node
# Download and cache dependencies
- restore_cache:
keys:
- app-v1-dependencies-{{ checksum "Gemfile.lock" }}
# fallback to using the latest cache if no exact match is found
- app-v1-dependencies-
- run:
name: Install Rails Dependencies
command: |
bundle install --jobs=4 --retry=3 --path vendor/bundle
- save_cache:
paths:
- ./vendor/bundle
key: app-v1-dependencies-{{ checksum "Gemfile.lock" }}
- restore_cache:
name: Restore Yarn Package Cache
keys:
- yarn-packages-{{ .Branch }}-{{ checksum "yarn.lock" }}
- yarn-packages-{{ .Branch }}
- yarn-packages-master
- yarn-packages-
- run:
name: Install Dependencies
command: |
yarn install
- save_cache:
name: Save Yarn Package Cache
key: yarn-packages-{{ .Branch }}-{{ checksum "yarn.lock" }}
paths:
- node_modules/
# Database setup
- run:
name: Set up DB
command: |
bundle exec rake db:create
bundle exec rake db:migrate
# - run: bundle exec rake db:create
# - run: bundle exec rake db:schema:load
# Run rubocop
- run:
name: Run rubocop
command: bundle exec rubocop
# run tests!
- run:
name: run tests
command: |
mkdir /tmp/test-results
bundle exec rspec --format progress \
--format RspecJunitFormatter \
--out /tmp/test-results/rspec.xml \
--format progress \
spec
# collect reports
- store_test_results:
path: /tmp/test-results
- store_artifacts:
path: /tmp/test-results
destination: test-results
Mình sẽ giải thích từng phần để các bạn dễ hình dung nhé .
version: version của CircleCI, hiện nay đã ra tới 2.1 nhưng trong project của mình vẫn là 2 thôi, chưa có thời gian update mà
jobs: các job cần phải thực hiện mỗi khi build trên CircleCI.
build: tên job.
docker: là executor, nói đơn giản là nơi để thực hiện các job. Có 3 loại executor khác nhau: docker, machine và macos.
image: tên image sẽ được sử dụng trong docker, và những image này được lấy từ dockerhub. Trong nddblog mình sử dụng 2 image là ruby - dùng để chạy project và postgres - dùng để lưu trữ dữ liệu.
environment: các biến môi trường của từng image. RAILS_ENV cài đặt môi trường rails trên CircleCI là test. POSTGRES_USER cài đặt username cho database. Lưu ý username ở đây và trong file config/database.yml phải giống nhau.
working_directory: thư mục lưu trữ source code. steps: các bước thực hiện trong job.
checkout: lấy code của nhánh đang build từ github hoặc bitbucket về.
restore_cache: restore các dependencies đã được cache từ lần build trước nếu có.
run: thực hiện các command line. Trong file mình có 4 lệnh run lần lượt là cài đặt các dependencies, tạo vào migrate database, chạy test rubocop và chạy rspec test. Nếu các bạn cần chạy lệnh nào khác có thể thêm thoải mái.
save_cache: lưu cache lại các dependencies.
store_test_results: lưu các kết quả test ra file để hiển thị trên CircleCI.
store_artifacts: lưu các kết quả của artifacts ra file để hiển thị trên CircleCI (artifacts là các file như file ảnh, logs, coverage reports....).
Trên đây mình đã giải thích những key quan trọng cần có của 1 file config.yml. Dựa vào đó chắc hẳn các bạn đã có thể tạo ra file riêng cho project của mình rồi nhỉ . Sau khi đã thêm file config.yml vào project thì hãy commit và push file đó lên repo của mình