欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

GitLab实现持续集成

程序员文章站 2022-06-21 18:40:20
...

概述

互联网软件的开发和发布,已经形成了一套标准流程,最重要的组成部分就是持续集成(Continuous integration,简称CI)。

持续集成

持续集成指的是,频繁地(一天多次)将代码集成到主干。它的好处主要有两个:

  • 快速发现错误。每完成一点更新,就集成到主干,可以快速发现错误,定位错误也比较容易。
  • 防止分支大幅偏离主干。如果不是经常集成,主干又在不断更新,会导致以后集成的难度变大,甚至难以集成。

Martin Fowler 说过,"持续集成并不能消除 Bug,而是让它们非常容易发现和改正。"

图解GitLab实现持续集成

持续集成强调开发人员提交了新代码之后,立刻进行构建、(单元)测试。根据测试结果,我们可以确定新代码和原有代码能否正确地集成在一起。

与持续集成相关的,还有两个概念,分别是持续交付和持续部署 这篇文章不予详述

持续部署的操作流程

  1. 提交

    流程的第一步,是开发者向代码仓库提交代码。所有后面的步骤都始于本地代码的一次提交(commit)

  2. 测试
    代码仓库对 commit 操作配置了钩子(hook),只要提交代码或者合并进主干,就会跑自动化测试。

    测试的种类:

    • 单元测试:针对函数或模块的测试
    • 集成测试:针对整体产品的某个功能的测试,又称功能测试
    • 端对端测试:从用户界面直达数据库的全链路测试

    第一轮至少要跑单元测试。

  3. 构建

    通过第一轮测试,代码就可以合并进主干,就算可以交付了。

    交付后,就先进行构建(build),再进入第二轮测试。所谓构建,指的是将源码转换为可以运行的实际代码,比如安装依赖,配置各种资源(样式表、JS脚本、图片)等等。

    常用的构建工具如下:

    Jenkins
    Travis
    Codeship
    Strider
    Jenkins 和 Strider 是开源软件,Travis 和 Codeship 对于开源项目可以免费使用。它们都会将构建和测试,在一次运行中执行完成。

  4. 测试(第二轮)
    构建完成,就要进行第二轮测试。如果第一轮已经涵盖了所有测试内容,第二轮可以省略,当然,这时构建步骤也要移到第一轮测试前面。

    第二轮是全面测试,单元测试和集成测试都会跑,有条件的话,也要做端对端测试。所有测试以自动化为主,少数无法自动化的测试用例,就要人工跑。

    需要强调的是,新版本的每一个更新点都必须测试到。如果测试的覆盖率不高,进入后面的部署阶段后,很可能会出现严重的问题。

  5. 部署

    通过了第二轮测试,当前代码就是一个可以直接部署的版本(artifact)。将这个版本的所有文件打包( tar filename.tar * )存档,发到生产服务器。

    生产服务器将打包文件,解包成本地的一个目录,再将运行路径的符号链接(symlink)指向这个目录,然后重新启动应用。这方面的部署工具有Ansible,Chef,Puppet等

  6. 回滚
    一旦当前版本发生问题,就要回滚到上一个版本的构建结果。最简单的做法就是修改一下符号链接,指向上一个版本的目录。

Docker有个tag 只要错误,回滚到上次tag

使用GitLab持续集成

  1. 简介
    从 GitLab 8.0 开始,GitLab CI 就已经集成在 GitLab 中,我们只要在项目中添加一个.gitlab-ci.yml文件,然后添加一个 Runner,即可进行持续集成。 而且随着 GitLab 的升级,GitLab CI 变得越来越强大。

  2. 概念

  • Pipeline
    一次 Pipeline 其实相当于一次构建任务,里面可以包含多个流程,如安装依赖、运行测试、编译、部署测试服务器、部署生产服务器等流程。
    任何提交或者 Merge Request 的合并都可以触发 Pipeline,如下图所示:
    GitLab实现持续集成

  • Stages
    Stages 表示构建阶段,说白了就是上面提到的流程。我们可以在一次 Pipeline 中定义多个 Stages,这些 Stages 会有以下特点:

    1.所有 Stages 会按照顺序运行,即当一个 Stage 完成后,下一个 Stage 才会开始
    2.只有当所有 Stages 完成后,该构建任务 (Pipeline) 才会成功
    3.如果任何一个 Stage 失败,那么后面的 Stages 不会执行,该构建任务 (Pipeline) 失败

    因此,Stages 和 Pipeline 的关系就是:
    GitLab实现持续集成

  • Jobs
    Jobs 表示构建工作,表示某个 Stage 里面执行的工作。我们可以在 Stages 里面定义多个 Jobs,这些 Jobs 会有以下特点:

    1. 相同 Stage 中的 Jobs 会并行执行
    2. 相同 Stage 中的 Jobs 都执行成功时,该 Stage 才会成功
    3. 如果任何一个 Job 失败,那么该 Stage 失败,即该构建任务 (Pipeline) 失败

    所以,Jobs 和 Stage 的关系图就是所以,Jobs 和 Stage 的关系图就是:
    GitLab实现持续集成

使用Docker搭建GitLabRunner

环境准备

  • 创建工作目录 /usr/local/docker/runner
  • 创建构建目录 /usr/local/docker/runner/environment
  • 下载 jdk-8u152-linux-x64.tar.gz 并复制到 /usr/local/docker/runner/environment

在 /usr/local/docker/runner/environment 目录下创建 Dockerfile

FROM gitlab/gitlab-runner:v11.0.2
MAINTAINER haolarn_bravo@163.com

# 修改软件源
RUN echo 'deb http://mirrors.aliyun.com/ubuntu/ xenial main restricted universe multiverse' > /etc/apt/sources.list && \
    echo 'deb http://mirrors.aliyun.com/ubuntu/ xenial-security main restricted universe multiverse' >> /etc/apt/sources.list && \
    echo 'deb http://mirrors.aliyun.com/ubuntu/ xenial-updates main restricted universe multiverse' >> /etc/apt/sources.list && \
    echo 'deb http://mirrors.aliyun.com/ubuntu/ xenial-backports main restricted universe multiverse' >> /etc/apt/sources.list && \
    apt-get update -y && \
    apt-get clean

# 安装 Docker
RUN apt-get -y install apt-transport-https ca-certificates curl software-properties-common && \
    curl -fsSL http://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | apt-key add - && \
    add-apt-repository "deb [arch=amd64] http://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable" && \
    apt-get update -y && \
    apt-get install -y docker-ce
COPY daemon.json /etc/docker/daemon.json

# 安装 Docker Compose
WORKDIR /usr/local/bin
RUN wget https://raw.githubusercontent.com/topsale/resources/master/docker/docker-compose
RUN chmod +x docker-compose

# 安装 Java
RUN mkdir -p /usr/local/java
WORKDIR /usr/local/java
COPY jdk-8u152-linux-x64.tar.gz /usr/local/java
RUN tar -zxvf jdk-8u152-linux-x64.tar.gz && \
    rm -fr jdk-8u152-linux-x64.tar.gz

# 安装 Maven
RUN mkdir -p /usr/local/maven
WORKDIR /usr/local/maven
RUN wget https://raw.githubusercontent.com/topsale/resources/master/maven/apache-maven-3.5.3-bin.tar.gz
# COPY apache-maven-3.5.3-bin.tar.gz /usr/local/maven
RUN tar -zxvf apache-maven-3.5.3-bin.tar.gz && \
    rm -fr apache-maven-3.5.3-bin.tar.gz
# COPY settings.xml /usr/local/maven/apache-maven-3.5.3/conf/settings.xml

# 配置环境变量
ENV JAVA_HOME /usr/local/java/jdk1.8.0_152
ENV MAVEN_HOME /usr/local/maven/apache-maven-3.5.3
ENV PATH $PATH:$JAVA_HOME/bin:$MAVEN_HOME/bin

WORKDIR /

在 /usr/local/docker/runner/environment 目录下创建 daemon.json,用于配置加速器和仓库地址

{
  "registry-mirrors": [
    "https://registry.docker-cn.com"
  ],
  ## 自己镜像私服的地址
  "insecure-registries": [
    "192.168.239.147:5000"
  ]
}

在 /usr/local/docker/runner 目录下创建 docker-compose.yml

version: '3.1'
services:
  gitlab-runner:
    build: environment
    restart: always
    container_name: gitlab-runner
    privileged: true
    volumes:
      - /usr/local/docker/runner/config:/etc/gitlab-runner
      - /var/run/docker.sock:/var/run/docker.sock

注册 Runner

docker exec -it gitlab-runner gitlab-runner register

# 输入 GitLab 地址
Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com/):
http://192.168.239.147:8080/

# 输入 GitLab Token
Please enter the gitlab-ci token for this runner:
1Lxq_f1NRfCfeNbE5WRh

# 输入 Runner 的说明
Please enter the gitlab-ci description for this runner:
可以为空

# 设置 Tag,可以用于指定在构建规定的 tag 时触发 ci
Please enter the gitlab-ci tags for this runner (comma separated):
deploy

# 这里选择 true ,可以用于代码上传后直接执行
Whether to run untagged builds [true/false]:
true

# 这里选择 false,可以直接回车,默认为 false
Whether to lock Runner to current project [true/false]:
false

# 选择 runner 执行器,这里我们选择的是 shell
Please enter the executor: virtualbox, docker+machine, parallels, shell, ssh, docker-ssh+machine, kubernetes, docker, docker-ssh:
shell

地址与Token地址
GitLab实现持续集成
测试
在项目工程下编写 .gitlab-ci.yml 配置文件:

stages:
  - test

test:
  stage: test
  script:
   - echo "Hello GitLab Runner"

在GitLab查看工作流
GitLab实现持续集成
GitLab实现持续集成

总结

我们可以根据GitLab返回结果的成功与失败,来测试我们的代码,做到持续集成。