Gitlab CI 持續集成的完整實踐

Gitlab CI 持續集成的完整實踐python

    本着公司團隊初創,又在空檔期想搞點事情,搭建了私有Gitlab的契機,順便把持續集成搭建起,實現了對Python服務端代碼的單元測試、靜態代碼分析和接口測試的持續集成。整體架構以下:git

執行過程:github

  1. 開發提交代碼後,自動觸發gitlab-runner拉取executor鏡像執行單元測試,單元測試代碼中包含上傳測試結果到x-utest測試平臺;redis

  2. 單元測試經過後,gitlab-runner拉取sonar-scanner鏡像執行靜態代碼分析,分析結果評論在commit中或保存於sonarqube;docker

  3. 靜態代碼分析結束,執行分發操做,將代碼分發至灰度測試服務器,並運行;數據庫

  4. 執行接口測試,執行完成後上傳測試結果到x-utest測試平臺。後端

四個任務相互依賴,只在前一個任務狀態爲成功狀況下才會執行。api

Gitlab CI 基本配置

針對某個須要作CI/CD的項目,須要將代碼庫的該設置打開,併爲其配置 gitlab-runner。服務器

gitlab runner

gitlab-runner不只能夠運行在物理機,還能夠運行在容器中。考慮到gitlab-runner消耗的資源少,使用容器更合適。架構

拉取gitlab-runner Docker 鏡像:

 

sudo docker pull gitlab/gitlab-runner

 

啓動容器:

sudo docker run -d --name gitlab-runner --restart always \

-v /srv/gitlab-runner/config:/etc/gitlab-runner \

   -v /var/run/docker.sock:/var/run/docker.sock \

   gitlab/gitlab-runner:latest

在容器中執行register操做,將gitlab上的項目註冊到gitlab-runner中:

 

sudo docker exec -it gitlab-runner gitlab-ci-multi-runner  register

 

輸入上述命令後會有一系列的配置須要輸入,固然也能夠設置完後進行更改 按照提示輸入便可,前兩項能夠在指定項目設置中CI/CD選項裏的Runners settings選項中的Specific Runners裏看到,tags是gitlab-ci.yml文件中所要用到的,executor選擇docker 配置成功後,咱們能夠在設置中CI/CD選項裏的Runners settings選項中的Specific Runners裏看到runner信息

本地executor鏡像

爲了部署與測試,須要一個鏡像用於執行。當選用本地鏡像時,可能會出現拉取鏡像失敗。

拉取鏡像失敗

報錯的緣由在於,gitlab-runner嘗試去官方的docker hub倉庫拉取鏡像。經過修改gitlab-runner中的配置,設置只拉取本地鏡像:

修改 /etc/gitlab-runner/config.toml ,在 [runners.docker] 下,添加:

 

pull_policy = never  # 該配置默認always,即只在線上拉取鏡像

 

若是有須要添加一些hosts映射,仍然在 [runners.docker] 下,添加:

 

extra_hosts = ["hostname:ip"]

 

另外爲了加快單元測試執行速度,將服務端代碼的依賴提早安裝至executor鏡像中:

 

COPY requirement.txt .

 

 

RUN pip install -r requirement.txt

 

編寫 .gitlab-ci.yaml

單元測試部分

用nose執行測試

對於Python,nosetest工具能夠嗅探與執行你寫的全部測試用例,並輸出結果。在執行測試前,使用nose須要使用pip安裝

 

pip install nose

 

安裝完成後,使用 nosetests 執行。

 

nosetests

 

自寫測試入口

另外一個執行測試的選擇,是自寫測試入口,不依賴nose。好處是可以將測試結果上傳至x-utest。 對測試結果作判斷,若是所有用例經過(即wasSuccessful爲True),則sys.exit(0),不然sys.exit(1)

redis與mongo服務化

對於redis與mongo這種外部服務,有兩種解決方式,一是mock對數據庫的讀寫,二是使用服務化的redis與mongo,保證外部環境的一致性。(更推薦第一種方式,此處介紹第二種。)

因爲設置了不從docker hub拉取鏡像,所以須要先拉取redis與mongo服務鏡像到本地

 

docker pull redis:2.8 

 

 

docker pull mongo:3.2

 

在gitlab-ci.yaml中添加services:

 

services:

 

 

 - redis:2.8

 

 

 - mongo:3.2

 

修改代碼的local_config配置文件中的mongo與redis鏈接URL,指向「mongo」與「redis」

靜態代碼分析

sonarqube搭建

製作了一個docker-compose項目能夠一鍵部署SonarQube平臺,使用postgres做爲後端數據庫,並將數據持久化在宿主機本地。

 

git clone https://github.com/ityoung/sonarqube-docker.git

 

 

pip install docker-compose

 

 

cd sonarqube-docker

 

 

docker-compose up

 

sonar scanner配置

同時針對Python開源了sonar-scanner鏡像的Dockerfile ,該鏡像已經安裝pylint,方便作Python的靜態代碼分析。

 

git clone https://github.com/ityoung/sonar-scanner-docker.git

 

 

cd sonar-scanner-docker

 

 

docker build -t sonar-scanner .

 

YAML添加執行命令

啓動SonarQube後,進入IP:9000到SonarQube管理頁面,登陸admin/admin,新建一個項目,按步驟執行完成

建立一個project

建立完成後,獲取到執行代碼,複製這段代碼,添加到yaml中,可以實現分析結果上傳到SonarQube。

獲取sonar-scanner執行腳本

注意:若是yaml中用到了兩個鏡像,儘可能不要有before_script,不然可能兩個鏡像,觸發錯誤。

Sonar分析後評論

對於develop分支,能夠不保存分析結果,而改成將分析結果評論在當次commit下。

在yaml腳本中添加以下參數:

 

     - sonar-scanner

 

 

     -Dsonar.analysis.mode=preview

 

 

     -Dsonar.gitlab.commit_sha=$CI_BUILD_REF

 

 

     -Dsonar.gitlab.ref_name=$CI_BUILD_REF_NAME

 

 

     -Dsonar.gitlab.project_id=$CI_PROJECT_ID

 

注意:無新issue時默認不會評論,須要在SonarQube修改gitlab配置纔會每次都評論。

持續交付

這部分交由對服務端部署更熟悉的運維操做。

接口測試

接口測試代碼在另外一個倉庫,這就涉及到從另外一個倉庫clone測試代碼時的權限問題。

給倉庫URL添加token可以實現跨倉庫clone代碼:

git clone https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.xxx.com/yx/apitest.git

附一:完整的.gitlab-ci.yml

image: pro1_executor stages: - unittest - analyze - deploy - apitest variables: SONAR_HOST: "http://192.168.0.29:9000" SONAR_PROJ: "pro_1" SONAR_LOGIN: "b3135dd602b61ce7ff5f4202a3ec2ec0865fa7f5" services: - redis:3
  - mongo:3.2 UnitTest: stage: unittest script: - pip install nose - python -m runtest xtest Sonar_Preview: image: sonar-scanner stage: analyze script: - sonar-scanner -Dsonar.analysis.mode=preview -Dsonar.gitlab.commit_sha=$CI_BUILD_REF -Dsonar.gitlab.ref_name=$CI_BUILD_REF_NAME -Dsonar.gitlab.project_id=$CI_PROJECT_ID -Dsonar.projectKey=$SONAR_PROJ -Dsonar.sources=. -Dsonar.host.url=$SONAR_HOST -Dsonar.login=$SONAR_LOGIN except: - master Sonar_Analyze: image: sonar-scanner stage: analyze script: - sonar-scanner -Dsonar.projectKey=$SONAR_PROJ -Dsonar.sources=. -Dsonar.host.url=$SONAR_HOST -Dsonar.login=$SONAR_LOGIN only: - master Deploy_TestServer: stage: deploy script: echo "deploy" API_Test: stage: apitest script: - cd /
    - git clone https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.xxx.com/yx/apitest.git
    - cd apitest - pip install -r requirements.txt - python runtest.py

 

參考:  

[1] https://mp.weixin.qq.com/s/fJPNg8jPkLAd0y8-D7xBYw

相關文章
相關標籤/搜索