CI của gitlab

Đến thời điểm hiện nay, tôi thường yêu cầu các dự án của mình phải có CI. Nếu viết bằng script như nodejs thì CI sẽ có nhiệm vụ check syntax, để các thành viên trong nhóm cùng một kiểu viết giống nhau, và chạy các mức test khác nhau như unit test, CDC test.

Điểu tuyệt vời của gitlab là nó đi kèm với bộ CI miễn phí cho cả dự án private (yay). Blog này tôi sẽ trình bày chiến lược để thiết lập env test trên Gitlab CI để build docker image, và upload nó lên gitlab registry.

 

Gitlab runner

Là nơi chương trình test của bạn sẽ được chạy. Bạn có thể có một PC riêng biệt cho việc build và test. Gitlab cung cấp một chương trình khá tiện https://gitlab.com/gitlab-org/gitlab-ci-multi-runner để thiết lập runner cục bộ. Cá nhân tôi chỉ sử dụng multi runner này khi chương trình cần tài nguyên lớn.

Phần lớn thời gian tôi sử dụng shared runner https://about.gitlab.com/gitlab-com/settings/#shared-runners. Xin cảm ơn sự tử tế của Digital Ocean khi cho mỗi build một tài nguyên 4GB chạy trong mỗi máy ảo riêng biệt.

Shared runner chạy trên docker, nên có thể khai báo các docker có sẵn khá tiện (yay).

.gitlab-ci.yml

Là file cấu hình cho gitlab ci. Dưới đây là một ví dụ trong đó khai báo một trạng thái của test pipeline là unit test. Phần sau dựa trên giả thuyết tôi đang xây dựng một web app với nodejs, và chạy unit test với npm run test.

image: node:boron-alpine

stages:
 - unit_test

unit_test_job:
 stage: unit_test
 script:
 - npm install
 - npm run test

Với mỗi git push lên CI được trigger. CI sẽ pull về docker image node:boron-alpine giống với docker chạy trong staging và production environment của web app này. Stages khai báo các bước của CI. Trong trường hợp này, tôi chỉ có một bước duy nhất là unit test khai báo trong unit_test_job.

Đơn giản như vậy.

Nhưng, vì tôi tin vào 12factor, và tôi muốn có quá trình build trước. CI hay staging hay production sẽ khác nhau ở env truyền vào docker như trình bày ở https://12factor.net/build-release-run. Tôi sẽ tạo một job để tạo artifact, và chạy test trên artifact này.

image: docker:1.12
services:
 - docker:dind

stages:
 - build

variables: 
 CONTAINER_TEST_IMAGE: registry.gitlab.com/company/project:$CI_BUILD_REF_NAME
before_script:
 - docker info
build_image_job:
 stage: build
 script:
 - docker build -t $CONTAINER_TEST_IMAGE .
 - docker run $CONTAINER_TEST_IMAGE npm run test

Setup này sử dụng docker trong docker (dind)  để build docker image trong một docker (nơi CI này đang chạy). Đều này đạt được do shared runner chạy với privileged enable (wao).

Như vậy lúc này CI sẽ tạo một docker có tên biến CONTAINER_TEST_IMAGE , và chạy test trong image này.

Tôi muốn tiến thêm một bước nữa, pipeline bao gồm: build, test, và release. Quá trình release xảy ra khi tôi tag git tag -a version, nó sẽ tạo ra tag latest và upload lên gitlab registry.

Khoa, gitlab registry? Đúng vậy, gitlab cho phép bạn lưu các image lên host của họ. Bạn sẽ có CI, và registry (miễn phí).

image: docker:1.12

services:
- docker:dind

stages:
- build
- test
- release
- deploy

variables:
 CONTAINER_TEST_IMAGE: registry.gitlab.com/company/project:$CI_BUILD_REF_NAME
 CONTAINER_RELEASE_IMAGE: registry.gitlab.com/company/project:latest

before_script:
 - docker login -u gitlab-ci-token -p $CI_BUILD_TOKEN registry.gitlab.com

build:
 stage: build
 script:
 - docker build --pull -t $CONTAINER_TEST_IMAGE .
 - docker push $CONTAINER_TEST_IMAGE

unit_test:
 stage: test
 script:
 - docker pull $CONTAINER_TEST_IMAGE
 - docker run $CONTAINER_TEST_IMAGE npm run unit_test

cdc_test:
 stage: test
 script:
 - docker pull $CONTAINER_TEST_IMAGE
 - docker run $CONTAINER_TEST_IMAGE npm run cdc_test

release-image:
 stage: release
 script:
 - docker pull $CONTAINER_TEST_IMAGE
 - docker tag $CONTAINER_TEST_IMAGE $CONTAINER_RELEASE_IMAGE
 - docker push $CONTAINER_RELEASE_IMAGE
 only:
 - tags
 - triggers

Gitlab rất hào phóng khi cung cấp đầy đủ các công cụ và dịch vụ để bạn có thể xây dựng một quá trình CI khá hoàn chính, từ việc chạy các test đến việc lưu trữ các image của bạn.

Hy vọng bạn sẽ tìm thấy sự hữu dụng trong ecosystem của gitlab để xây dựng hệ thống bền vững.

npm install package from private repo

My company hosts most of the private repositories in gitlab, thanks to its generous unlimited-free-plan, and wonderful built-in CI.

npm need to get package from private gitlab, or bitbucket: create tag, and provide direct link when install package.

First: tag package with version (e.g. 0.0.1)

git tag -a v0.0.1 -m "first release"
git push origin v0.0.1

, then tell npm the link with tag. I will love to use git+ssh instead of git+https since my CI runner and collaborators already have the right to get access to this repo; thus don’t need to enter password every time npm try to install.

npm install git+ssh://git@gitlab.com:company/repo.git#v0.0.1 --save