Git

使用GitLab CI 持续集成

Posted by FridayLi on January 21, 2018

当你的项目有一定的规模并且还要持续开发时,持续集成就显得很重要。gitlab 一般用Gitlab CI, 而github一般用jenkins, 主要功能是在你提交或merge代码到仓库后, 自动执行一些你定义好的命令, 比如安装依赖、单元测试、pep8检查、 甚至还可以自动部署到生成环境。前段时间自己给当前做的项目加上了gitlab ci, 实现的主要功能是提交代码后自动检测安装依赖有没有问题, 单元测试能不能通过, pep 8 规范检查是否合格, 有一项不合格就会在提交的分支或merge后面有个显目的红叉, 全通过的话则是一个赏心悦目的绿色对勾。 描述

安装和配置Runner

首先, gitlab ci 需要单独部署在一台服务器上来运行, 对应的程序是GitLab Runner, 在ubuntu和centos上安装都是先根据一个shell脚本安装各种依赖, 然后再执行安装程序。

1
2
3
4
5
6
# For Debian/Ubuntu
$ curl -L https://packages.gitlab.com/install/repositories/runner/gitlab-ci-multi-runner/script.deb.sh | sudo bash
$ sudo apt-get install gitlab-ci-multi-runner
# For CentOS
$ curl -L https://packages.gitlab.com/install/repositories/runner/gitlab-ci-multi-runner/script.rpm.sh | sudo bash
$ sudo yum install gitlab-ci-multi-runner

如果服务器上curl命令没装的话或者运行有问题的话可以直接打开curl命令对应的网址, 复制粘贴上边的shell脚本,写到服务器的一个文件(gitlab-runner.sh)中, 然后手动执行 sh gitlab-runner.sh

为了能够让GitLab Runner 能够连接到我们的项目上需要注册操作: sudo gitlab-runner register 然后根据提示输入配置信息(这些信息可以在项目的gitlab网站的CI/CD 配置里找到, 需要master权限)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com )
https://gitlab.com  //项目gitlab的根域名, 一般公司都会部署自己内部使用的gitlab

Please enter the gitlab-ci token for this runner
xxx   // gitlab token, 每个项目都不一样

Please enter the gitlab-ci description for this runner
[hostame] my-runner  // 项目描述, 起个名称

Please enter the gitlab-ci tags for this runner (comma separated):
my-tag,another-tag   // 给该 Runner 指派 tags, 稍后也可以在 GitLab's UI 修改, 这里也可以直接回车, 使用默认值

Whether to run untagged jobs [true/false]:
[false]: true   // 选择 Runner 是否接收未指定 tags 的任务(默认值:false), 稍后可以在 GitLab's UI 修改

Whether to lock Runner to current project [true/false]:
[true]: false // 该runner是否只能运行当前指定项目(根据token来判断的),默认值:true:

Please enter the executor: ssh, docker+machine, docker-ssh+machine, kubernetes, docker, parallels, virtualbox, docker-ssh, shell:
shell  // 选择runner的类型, 这里用shell就好

配置完成, sudo gitlab-ci-multi-runner list 可以查看当前runner的状态。

ps: 如果配置完遇到以下问题:

1
2
ERROR: Registering runner... failed runner=38BUk9-k status=404 Not Found
PANIC: Failed to register this runner. Perhaps you are having network problems 

原因很可能是你公司部署的gitlab 版本太旧(低于v9), 和你新安装的gitlab Runner 版本不兼容, 把gitlab Runner的版本降到1.11.1 版本应该能解决这个问题

pipeline 配置

GitLab Runner 启动成功后接下来就是在你的项目里配置gitlab ci要干哪些事情了, 在项目的根目录新建一个.gitlab-ci.yml 文件,在里边配置代码commit后gitlab ci要干的事情。一个简单的示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 定义 stages
stages:
  - build
  - test
# 定义 job
job1:
  stage: test
  script:
    - echo "I am job1"
    - echo "I am in test stage"
# 定义 job
job2:
  stage: build
  script:
    - echo "I am job2"
    - echo "I am in build stage"

执行顺序如下:

  1. stages里的stage按顺序执行, 如果有一个stage执行失败, 结束, 不再往下执行。
  2. 执行每个stage时,stage里的job并行执行, 所有job都执行成功该stage才算成功, 有一个失败的话该stage执行失败, 结束。

此外,还有连个非常有用的选项——before_script 和 after_script, 分别对应着每个job执行前后要运行的额外代码。 更多的配置选项可以看gitlab ci的官方文档

unit test coverage

让gitlab ci 执行django单元测试, 运行一条简单的django 的测试命令即可: python manage.py test 但相信你和我一样都想看看单元测试覆盖了多少代码,使用一个第三方Python 库Coverage可以很方便的得到结果

  1. 首先, 安装Coverage pip install coverage
  2. 然后运行单元测试
    1
    
    python -m coverage run --source='unit test覆盖率统计的目录' gold/manage.py test your_app --settings=your_settings
    

    其中, –source可以指定unit test测试的是哪个文件夹下面的代码, 这样统计覆盖率时可以更加准确, –settings可以指定运行单元测试时django 的配置文件

  3. 最后, 输出测试报告: python -m coverage report 报告内容可以在console里直接查看, 不仅可以看到总的覆盖率, 还可以观察到每个文件的单元测试覆盖率,有助于完善你的单元测试。 描述

pep 8

当多人参与一个项目时, 统一代码规范就很重要。 python一般用的是pep 8, 用flake 8 可以很方便做到。

  1. 安装 pip install flake8 pep8-naming
  2. 在项目根目录下新建一个.flake8配置文件
  3. 配置文件内容大概如下(不要出现中文, 后面的注释是为了便于读者理解额外添加的): ``` [flake8] ignore = W292 W391 E126 W291 N805 // 忽略的格式类型 exclude = // 忽略的文件、文件夹 migrations, # python related .pyc, .git, pycache, *.conf, *.md, config settings manage.py gold/vulpo/*

max-line-length=125 // 单行最大字数 max-complexity=16 // 复杂度上限 format=pylint
show_source = True statistics = True count = True

1
当然, 记得在`.gitlab-ci.yml` 中添加一个执行pep 8 检查的job:

pep8_test: stage: pep8 script: - flake8 gold

allow_failure: true // 有追求的程序员当然不会允许pep 8 检查不通过

1
2
3
## 点亮badge
看到别人开源的代码首页read me 左上方的badge有没有觉得高大上呢? 其实自己的项目里也可以很方便的添加。
gitlab 自带两个默认的badge, 分别是build和test, 对于单元测试, 在gitlabsetting页面的Pipelines配置页,找到 Test coverage parsing项,填写 \d+%\s*$, 然后在项目文件的read me 的首行添加:

coverage report build status

1
2
3
4
效果如下:
![描述](/img/old-post/21982db37401f4bef72ae2f165e396f16723.PNG)
##一个完整的.gitlab-ci.yml 配置
最后, 展示下我的.gitlab-ci.yml 的最终配置:

before_script: - source /opt/gold/gold_env/bin/activate # 启动Python env

stages: - install_deps #安装依赖 - unit_test # 单元测试 - pep8 # pep 8 测试

install_deps: stage: install_deps script: - pip install -i http://xxx:18080/simple –trusted-host xxx -e . # 用自己的pypi安装项目的各种依赖 - python3.6 gold/manage.py migrate –settings=gold.settings.testcase # 把数据库变更同步到单元测试数据库 - gunicorn gold.wsgi:application –workers 1 –max-requests 10000 -k gthread –timeout 30 –bind 0.0.0.0:8000 –env GOLD_PROFILE=testcase –check-config # 检查gunicorn 能否启动成功

unit_test: stage: unit_test script: - python3.6 -m coverage run –source=’xxx’ gold/manage.py test wallet –settings=gold.settings.testcase # 单元测试 - python3.6 -m coverage report # 输出报告

pep8_test: stage: pep8 script: - flake8 gold # pep 8 检测

allow_failure: true

``` ###参考文章

  1. gitlab-ci.yaml 配置
  2. 单元测试和pep8 检测
  3. gitlab ci 快速配置
  4. gitlab runner 注册
  5. gitlab runner 和gitlab版本冲突问题