-->
ads here

Tạo quy trình CI/CD với Travis CI

advertise here
Xin chào các bạn, bài viết lần này sẽ đề cập một vấn để liên quan đến DevOps một chút, đó là CI/CD: Continuous Integration/ Continuos Delivery hay Tích hợp liên tục/Chuyển giao liên tục. Cụ thể, trong bài viết này mình sẽ mô phỏng lại quy trình CI/CD với Travis CI.
Nội dung bài viết như sau:
  1. Giới thiệu về CI/CD
  2. Travis CI là gì?
  3. What are we going to build?
  4. Config CI/CD
    enter image description here

1. Giới thiệu về CI/CD

CI/CD là hai mô hình phát triển phần mềm hiện đại, được sử dụng rất phổ biến hiện nay với mục đích giảm thời gian từ khi một dòng code được viết ra ở development environment đến khi nó được user sử dụng ở production

Continuos Integration

Khái niệm

CI là quá trình yêu cầu developer tích hợp code lên repository liên tục, mỗi lần tích hợp như vậy, code sẽ được verify bằng một qúa trình build tự động nhằm phát hiện ra bug ngay sau khi code đó được tích hợp lên giúp cho việc fix bug sớm hơn. Bạn có thể tưởng tượng quá trình CI như sau:
  1. Push code lên git repository
  2. Một quy trình tự động được kích hoạt, code sẽ được build, test sẽ chạy
  3. Kết quả của quá trình này sẽ được report lại và gửi cho những người có liên quan
  4. Nếu tất cả các test đều pass, có nghĩa code vừa mới tích hợp đã an toàn, có thể merge vào nhánh chính (master/release), nếu không thì developer sẽ được báo là test case nào fail và fix nó và thực hiện lại quy trình CI cho đến khi pass.

Lợi ích

Một số lợi ích to lớn của CI có thể kể đến như sau:
  • Ít bug hơn: vì mỗi khi tích hợp nếu test fail thì developer sẽ phải ngay lập tức fix để code pass nên giảm thiểu rủi ro bug khi lên đến production
  • Tránh được trường hợp một tính năng mới được tích hợp sẽ gây lỗi ở các tính năng khác

Continuous Delivery

Khái niệm

CD là quá trình tự động deploy ứng dụng sau khi CI đã thành công.

Với CD, chúng ta có thể:

  • Dễ dàng deploy ứng dụng của chúng ta với rủi ro thấp hơn
  • Khách hàng có thể thấy được tiến trình cải tiến liên tục của sản phẩm
  • Giảm bớt thời gian “chết” trong quá trình phát triển phần mềm vì không cần phải đợi release.

2. Về Travis-ci

Travis-ci là một dịch vụ Continuous integration được dùng để build và test các project trên Github. Bạn có thể dùng https://travis-ci.org cho các public project của mình trên Github, nếu muốn dùng cho các private project thì bạn phải sử dụng https://travis-ci.com. Trong bài viết này chúng ta cũng sẽ sử dụng travis-ci.org.
enter image description here

Một số tính năng nổi bật của travis-ci:

  • Setup very fast: chỉ cần login bằng tài khoản Github của mình, sau đó chọn project muốn sử dụng CI/CD và push code lên Github rồi để Travis làm phần việc còn lại
  • Support multiple platform: Rất nhiều database cũng như các service khác được cài sẵn để đáp ứng cho nhu cầu của bạn
  • Test your pull request: Đảm bảo mỗi PR của bạn đều được test trước khi merge vào nhánh chính
  • Deploy everywhere: Travis hỗ trợ nhiều nền tảng để deploy ứng dụng của bạn. Chỉ cần tất cả các test đã pass thì khi đó môi trường staging hay production của bạn sẽ sẵn sàng được cập nhật mới nhất

3. What are we going to build?

Trong bài viết này mình sẽ dựng một express server đơn giản với 1 route duy nhất là / trả về trình duyệt 1 dòng "HELLO". Thêm vào đó mình có cấu hình eslint và viết 1 unit-test testcase để dùng mô phỏng quá trình Continous Integration. Cuối cùng mình sẽ deploy ứng dụng này lên Heroku và cấu hình để thực hiện Continous Delivery mỗi khi CI passed.

3.1. Init project

Tạo 1 thư mục và khởi tạo NPM project


$ mkdir travis-ci-cd && npm init

3.2. Cài đặt dependencies

Tải các package cần thiết cho project

$ yarn add express mocha chai chai-http eslint eslint-config-standard eslint-plugin-import eslint-plugin-node eslint-plugin-promise eslint-plugin-standard

3.3. Create index.js

Tạo file index.js với nội dung như sau:


const  express  =  require('express')
const  app  =  express()

app.get('/',  (req,  res)  =>  {
 res.send('HELLO')
})
const  server  =  app.listen(process.env.PORT  ||  3000,  ()  =>  {
 console.log('App running on port 3000')
})

module.exports =  server

Trong file package.json, ta thêm script start để chạy project


{
 ...
 "scripts":  {
  "start":  "node index.js"
 },
 ...
}

Ta test thử bằng cách chạy lệnh $ yarn run start sẽ thấy kết quả như sau:
enter image description here
Mở trình duyệt và gõ http://localhost:3000 ta sẽ thấy hiển thị 1 dòng HELLO. Như vậy phần server đã hoàn thành.

3.4. Write test

Tiếp theo ta sẽ viết unit test cho project này bằng cách tạo một file index.spec.js có nội dung như sau:


const  chai  =  require('chai')
const  chaiHttp  =  require('chai-http')
const  server  =  require('./index')
const  should  =  chai.should()
chai.use(chaiHttp)

describe('test',  ()  =>  {
 it('should return HELLO string',  (done)  =>  {
  chai.request(server)
  .get('/')
  .end((_err,  res)  =>  {
   res.should.have.status(200)
   res.text.should.be.a('string')
   res.text.should.be.eql('HELLO')
   done()
  })
 })
})
Sau đó vào file package.json thêm 1 script để chạy test như sau


{
 ...
 "scripts":  {
  "start":  "node index.js",
  "test": "mocha '**/*.spec.js'"
 },
 ...
}

Với script này, mỗi khi ta chạy lệnh yarn run test thì ta sẽ chạy hết tất cả các file test (file có định dạng là .spec.js)
Thử chạy ta được kết quả như sau:
enter image description here

3.5. Setup ES lint

Trước tiên ta tạo 1 file .eslintrc để cấu hình ESlint, trong project này mình sẽ config ESLint theo chuẩn StandardJS.


{
 "extends":  "standard"
}
Sau đó vào file package.json thêm 1 script để chạy linter như sau


{
 ...
 "scripts":  {
  "start":  "node index.js",
  "lint":  "eslint *.js",
  "test": "mocha '**/*.spec.js'"
 },
 ...
}

Và chạy yarn run lint để thấy kết quả như sau
enter image description here
Như các bạn thấy, hiện tại ở file test của chúng ta chưa đúng chuẩn của StandardJS. Sửa lại bằng việc thêm dòng
/* eslint-disable no-unused-vars, no-undef */ trên cùng của file index.spec.js và chạy lại lệnh yarn run lint thì ta thấy được toàn bộ project đã được viết theo chuẩn StandardJS
Như vậy ta đã xong phần project, tiếp theo chúng ta sẽ tiến hành cấu hình CI/CD với Travis-ci

4. Config CI/CD with Travis-ci

4.1. Cấu hình Continuous Integration

Qúa trình Continuous của sẽ gồm 2 phần, phần 1 kiểm tra linting của project có đúng theo chuẩn hay không (chuẩn ở đây là StandardJS) và phần thứ 2 là kiểm tra xem tất cả các test có được pass hay không.
Bước đầu tiên, chúng ta cần push code của chúng ta lên github và kết nối Travis-ci với project này.
enter image description here
Tiếp theo, ta sẽ tạo 1 file .travis.yml, file này sẽ chứa tất cả các cấu hình của CI/CD


language:  node_js
node_js:
 -  '8'
cache:  yarn
script:
 -  echo 'Build starts!!'
 -  echo 'Installing Deps!'
 -  yarn
 -  echo 'Linting!'
 -  yarn lint
 -  echo 'Testing!'
 -  yarn test

Chúng ta hãy cùng tìm hiểu thêm về file cấu hình này:
  • language: node_js dòng này sẽ thông báo cho Travis ci biết rằng project này sẽ sử dụng Node JS, từ đó Travis CI sẽ setup để có thể phù hợp với project này
  • node_js: - '8': dùng để xác định version của nào của NodeJS sẽ được sử dụng
  • script ở đây ta sẽ định nghĩa các câu lệnh của quá trình Continuous Integration, như ta thấy,
    • echo 'Build starts!!'đầu tiên sẽ echo ra màn hình dòng Build starts!! để báo hiệu quá trình bắt đầu
    • echo 'Installing Deps!': In ra dòng Installing Deps để báo hiệu bắt đầu cài đặt các dependencies
    • yarn: Thực hiện tải về và cài đặt các package
    • echo 'Linting!': Bắt đầu thực hiện linting
    • yarn lint thực hiện kiểm tra ESLint
    • echo 'Testing!': Bắt đầu chạy test
    • yarn test: Thực thi test
Trong quá trình này, nếu có bất kì lỗi xảy ra ở đâu đều sẽ được thông báo và log lại trên Travis-ci. Tuỳ vào cấu hình của bạn, Travis có thể sẽ gửi thông báo đến qua email hoặc kênh chat của bạn (Slack chẳng hạn) báo rằng việc có lỗi xảy ra khi thực hiện CI
Sau khi hoàn thành file cấu hình, ta push code lên master branch. Việc này sẽ trigger cho Travis ci thực hiện Continuous Integration và ta có log như sau:
enter image description here
Và đây là kết quả khi build thành công
enter image description here

4.2. Cấu hình Continuous Delivery

Trong phần Continuous Delivery này, chúng ta sẽ cấu hình sao cho, sau khi chúng ta chạy CI thành công (tức là một tính năng mới được test xong hoặc một bug nào đó được fix và passed được quá trình CI) thì code sẽ được tự động deploy lên server production hay staging theo ý muốn của chúng ta. Cụ thể trong bài viết này, mình sẽ setup để code sẽ được tự động deploy lên Heroku
Đầu tiên chúng ta cần tạo một Herokup app như sau:
  1. Các bạn đăng nhập vào Heroku. Nếu chưa có tài khoản hãy đăng ký mới
  2. Tiếp theo chúng ta tạo 1 app trên Heroku với tên travis-ci-cd chẳng hạn
    enter image description here
  3. Sau khi tạo app xong, chúng ta tiến hành generate API key. Travis sẽ dùng key này để có thể access vào Heroku app của chúng ta và tiến hành deploy. Cách tạo key, các bạn có thể xem tại đây.
  4. Quay lại file .travis.yml, ta thêm đoạn này vào để cấu hình cho CD


deploy:
 provider:  heroku
 api_key:
  secure:  <YOUR API KEY>
 app:  travis-ci-cd
Đoạn code này sẽ thông báo cho Travis biết rằng, chúng ta sử dụng Heroku để deploy, đồng thời cho Travis API key để access vào app travis-ci-cd của chúng ta. Đến đây chúng ta đã xong phần cấu hình CD.
Push code này lên, thì Travis sẽ được trigger và chạy CI, nếu CI passed thì sẽ tiến hành deploy code của chúng ta lên Heroku
Các bạn có thể vào đây để thấy kết quả HELLO giống như ta đã chạy ở local.

Kết

Trong bài viết này mình đã giới thiệu một cách cấu hình CI/CD cực kì cơ bản và hoàn toàn miễn phí cho các bạn. Chúng ta thấy được rằng CI/CD sẽ giúp chúng ta tiết kiệm nhiều thời gian và tiền bạc cũng như tăng hiểu quả làm việc cũng như những giá trị đem đến cho khách hàng. Với combo Github + Travis-ci, các bạn có thể tự tin setup CI/CD cho các open source project của mình một cách hoàn toàn miễn phí.
Hi vọng qua bài viết này, bạn đã có thể xây dựng cho riêng mình một CI/CD process với Travis CI hoặc ứng dụng vào các project của các bạn trong công việc. Nếu các bạn thấy bài viết này hữu ích, hãy share cho bạn bè cùng đọc. Hay nếu có ý kiến đóng góp đừng ngần ngại để lại comment phía dưới bài viết nhé. Thanks!
P/S: Mình có để link Github cho các bạn tham khảo.

Reference

Advertisement
COMMENTS ()