GitLab本身功能非常豐富,加上它又是open source可以自行架設,從8.0開始支援CI功能,只要在project root裡面新增一個.gitlab-ci.yml,就可以啟用GitLab CI功能。GitLab也提供預設Shared Runners執行CI jobs,除此之外也可以自定義註冊Specific Runners給特定專案使用。
Pre-required
- Remote linux server : Ubuntu 16.04 (use AWS EC2)
- Create a repository on gitlab, example name :
laravel-ci
- Use composer to create a laravel project and push to
laravel-ci
.
Create GitLab CI
Gitlab CI有提供laravel範例yaml腳本,選用後修改調整
調整後的.gitlab-ci.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
|
stages:
- test
- build
- deploy
cache:
paths:
- vendor/
test_php7.1_mysql5.7:
stage: test
image: mmx112945/docker-laravel-php:7.1
services:
- mysql:5.7
variables:
MYSQL_ROOT_PASSWORD: secret
MYSQL_DATABASE: homestead
MYSQL_USER: homestead
MYSQL_PASSWORD: secret
before_script:
# Install & enable Xdebug for code coverage reports
- pecl install xdebug
- docker-php-ext-enable xdebug
# Install Composer and project dependencies.
- composer install
# Install Node dependencies.
# - npm install (pass)
# Copy over testing configuration.
- cp .env.testing .env
# Generate an application key. Re-cache.s
- php artisan key:generate
- php artisan config:cache
# Run database migrations.
- php artisan migrate:refresh
# Run database seed
- php artisan db:seed
script:
# run laravel tests
- php vendor/bin/phpunit --coverage-text --colors=never --coverage-html=coverage
# run frontend tests
# - npm test (pass)
artifacts:
paths:
- coverage/
expire_in: 1 day
build_production:
stage: build
image: docker:stable
services:
- docker:dind
script:
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- echo -e "$ENV_PRODUCTION" > .env
- docker build --pull -t $CI_REGISTRY_IMAGE .
- docker push $CI_REGISTRY_IMAGE
deploy_production:
stage: deploy
script:
- mkdir -p ~/.ssh
- echo -e "$SSH_PRIVATE_KEY" > ~/.ssh/id_rsa
- chmod 600 ~/.ssh/id_rsa
- '[[ -f /.dockerenv ]] && echo -e "Host *\nStrictHostKeyChecking no\n" > ~/.ssh/config'
- scp docker-compose.yml deploy.sh $SERVER_USER@$SERVER_URL:/home/ubuntu
- ssh ubuntu@$SERVER_URL "chmod +x ./deploy.sh"
- ssh ubuntu@$SERVER_URL "./deploy.sh $CI_DEPLOY_USER $CI_DEPLOY_PASSWORD"
environment:
name: production
url: http://$SERVER_URL
only:
- master
when: manual
|
catch
- composer install後會產生 vendor/,做catch後,除非composer.json有變動更新,否則之後的jobs都會使用已經build好存在gitlab catch的vendor/。此外也可以因為不用再重build vendor/,而節省下其他jobs的執行時間。
test_php7.1_mysql5.7
- image使用我已包好的docker laravel環境,加快job處理的時間
- 需使用mysql services服務使用,因為phpunit時會使用DB相關操作,參考: What is a service
- 安裝php debug tools,設定.env測試檔,特別注意
MYSQL_HOST=mysql
,參考: Using MySQL
- phpunit執行後會產生
coverage/
程式覆蓋率報表
- 如何設定與gitlab coverage連動
到Settings > CI/CD > General pipelines
頁面後,phpunit coverage parsing = ^\s*Lines:\s*\d+.\d+\%
(依照自己程式語言設定)
之後在CI/CD > Jobs
就可以看到coverage結果
另外可以在readme.md加上coverage or pipeline的icon → 看起來專業
build_production
- 使用
dind
方式建置環境
Settings > CI/CD > Variables
add ENV_PRODUCTION
,將正式環境的.env內容存成變數然後拿來使用
- $CI_REGISTRY_USER, $CI_REGISTRY_PASSWORD…等相關gitlab預設環境變數可以參考: GitLab CI/CD Variables
deploy_production
- 在本機設定遠端SERVER的private ssh key
- 將要執行deploy相關的檔案scp到遠端SERVER
- 使用ssh方法,遠端下指令給SEVER執行deploy動作
- 使用
Settings > Repository > Deploy Tokens
create read-only access to your repository and registry images → 將create後得到的username, token設定到enviroment variables : $CI_DEPLOY_USER
, $CI_DEPLOY_PASSWORD
- deploy.sh
1
2
3
4
5
6
7
8
9
10
11
|
#!/bin/bash
CI_DEPLOY_USER=$1
CI_DEPLOY_PASSWORD=$2
[[ \"$(docker info | grep Swarm | sed 's/Swarm: //g')\" == \"inactive\" ]] && docker swarm init
docker login registry.gitlab.com -u $CI_DEPLOY_USER -p $CI_DEPLOY_PASSWORD
docker-compose pull
docker stack deploy -c docker-compose.yml --with-registry-auth stack_laravel-ci
# 使用swarm, docker-compose的方式更新系統環境
|
- 若有設定environment,則可以在
Operations > Environments
看到完成結果
Conclusion
使用GitLab CI服務,讓開發者在每次提交新版Code後自動測試+部屬,可以大幅提升系統測試品質,以及環境部屬上的缺失。像正式環境所用的config跟測試環境的config就會不一樣,傳統手動部屬的話,要是哪個天兵一閃失丟錯config到正式環境,那就要爆了。
GitLab自帶CI/CD服務,不需要再透過其他第三方CI/CD (Jenkins, Travis…),這點真的很方便,也很好上手。