一、什么是CI/CD/CD?
现代软件公司通常都使用工具将部署代码的流程自动化:
持续集成注重将各个开发者的工作集合到一个代码仓库中,通常每天会进行几次,主要目的是尽早发现集成错误,使团队更加紧密结合,更好地协作,它的实现通常能够将构建部署的每个步骤自动化,以便任何时刻能够安全地完成代码发布。
持续部署是一种更高程度的自动化,无论何时代码有较大改动,都会自动进行构建/部署,其每一个阶段都称之为pipeline,引用一张版本帝的图片:
- 持续集成(CI)
持续集成重要思想就是让开发人员更快、更频繁地做到能够频繁地将其代码集成到代码仓库的分支中,开发人员只需要关注开发这个模块,从而降低集成的开销。
要想有效地使用 CI 必须转变开发团队的习惯,要鼓励频繁迭代构建,强调的是分支代码的提交、构建与单元测试,这样有助于降低总体的构建成本并在开发周期的早期发现缺陷。
- 持续交付(CD)
持续交付目的为存在一个永远可用的代码仓库。使用 CD 后每小时甚至每分钟都有可能发生版本发布,所谓小步快跑。
CD 集中依赖于部署流水线(pipeline),团队通过流水线自动化测试和部署过程(去过工厂的都知道流水线吧),在流水线的每个阶段,如果构建无法通过关键测试会向团队发出警报。
这是一整套研发流程,因为构建、部署和环境都是一起执行和测试的,它能让构建在实际的生产环境可部署和可验证。
- 持续部署(CD)
持续部署为整个CI/CD 系统的最后阶段,它将在构建组件编译、打包,并在退出流水线时自动部署发布,此类自动部署可以配置为快速向客户分发组件、功能模块或修复补丁,并准确说明当前提供的内容。
得到用户对于新版本的快速反馈,并且可以迅速处理任何明显的缺陷,在这样的流程中,不需要人为决定何时及如何投入生产环境。
二、举个栗子
范例为最为常见的JAVA Maven 的项目,具体 Gitlab-CI 的配置如下:
image: registry-vpc.cn-hangzhou.aliyuncs.com/kubernetes_hub/java_active:0.1
variables:
# CONTAINER_TEST_IMAGE: $HARBOR_CI_REGISTRY/$CI_PROJECT_NAME
before_script:
- docker login -u $GITLAB_CI_USER -p $GITLAB_CI_JOB_TOKEN $HARBOR_CI_REGISTRY
- IMAGE_TAG=$HARBOR_CI_REGISTRY/$CI_PROJECT_NAME-common-backend:$CI_COMMIT_SHORT_SHA
stages:
- maven_build
- build_image
- cleanup
maven_build:
stage: maven_build
script:
- mvn clean package
artifacts:
paths:
- target/*.jar
only:
- master
tags:
- java
Build_Image:
stage: build_image
script:
- sed -i "s/PROJECT_NAME/$CI_PROJECT_NAME/g" Dockerfile
- docker build -t $IMAGE_TAG .
- docker push $IMAGE_TAG
only:
- master
tags:
- java
when: manual
cleanup_dist_file:
stage: cleanup
script:
- rm -f target/*.jar
only:
- master
tags:
- java
when: always
具体效果如下:
三、Gitlab-CI 常用参数:
在上面的例子中,用到了不少常用的参数,下面我们来解释下各自的含义:
script:
设置Linux脚本命令,执行构建的操作
cache:
设置cache缓存文件,针对不同语言的特性,缓存各种当前目录的包文件,比如缓存前端的node_module依赖包,以此可提高构建效率,像composer、maven的缓存目录不在当前项目目录的,可以不设置;
stage:
设置项目若干个构建阶段,编译、打包、变量替换、发布,等等
artifacts:
驻留文件。在每一次构建的阶段都会清除当前生成的文件,比如:jar包、dist目录、vendor目录,这些都是我们需要的文件,所以如果需要上下两个构建需要关联到上层构建结果的,需要添加此变量:支持单/多个文件或者路径;
only:
设置触发构建的条件,可以指定分支名、tags;
tags(重要):
设置该构建所匹配的Runner环境,如:JAVA、IOS、.NET,不同的环境所用的Runner也不同!
# 值得注意的是:在tag不被指定的情况下,runner会自动匹配更全局的主机,故,如果设置了比较多的runner需要额外小心。底部有runner的优先级链接
when:
设置触发构建的时机,值可以为:on_success、always、manual(手动触发)等;
dependencies:
设置触发此构建的上一个构建;
environment:
设置当前构建所属的环境,对回滚操作非常有用;
- 查看 Gitlab-Runner 优先级请点击这里
3.1 使用 manual 这个参数后的自动构建的差别
使用后:
未启用:
大家可以看到使用 manual 这个参数后,build_image 的操作需用手动执行,这个对日后的发布有重大的作用。
四、Gitlab-CI 内置变量:
在之前的实例中细心的同学一定能发现有几个奇怪的变量,这些变量有些为自定义变量,有些为Gitlab-CI的内置变量方便用户调用,版本帝真良心!
下面是我这边常用的几个内置变量,其中的含义如下:
CI_COMMIT_SHORT_SHA="1ecfd275"
CI_COMMIT_REF_NAME="master"
CI_REPOSITORY_URL="https://gitlab-ci-token:abcde-1234ABCD5678ef@example.com/gitlab-org/gitlab-ce.git"
CI_COMMIT_TAG="1.0.0"
CI_JOB_NAME="spec:other"
CI_JOB_STAGE="test"
CI_JOB_MANUAL="true"
CI_JOB_TRIGGERED="true"
CI_JOB_TOKEN="abcde-1234ABCD5678ef"
CI_PROJECT_ID="34"
CI_PROJECT_DIR="/builds/gitlab-org/gitlab-ce"
CI_PROJECT_NAME="gitlab-ce"
CI_PROJECT_NAMESPACE="gitlab-org"
CI_PROJECT_URL="https://example.com/gitlab-org/gitlab-ce"
CI_RUNNER_ID="10"
CI_RUNNER_TAGS="docker, linux"
CI_SERVER="yes"
CI_SERVER_HOST="example.com"
GITLAB_USER_EMAIL="user@example.com"
上面的解释,按照字面意思已经很明白了,就不赘述了。
- 想要看所有 Gitlab-CI 内置变量统统都在这,请点击这里
五、Gitlab-CI 自定义变量:
Gitlab-CI的变量与Gitlab-Runner息息相关,变量会有作用域的问题,分为群组变量、项目变量,其性质与Gitlab-Runner的作用域原理相同,不清楚的参考我上一篇文章。
5.1 群组变量
群组变量的作用域覆盖在群组之内,简单点来说,同一群组内的所有项目,在这里定义的变量在整个群组中都是共享的,比如,docker registry的地址、账号,密码,组内的数据库连接串,等等。
- 在群组中设置:
5.2 项目变量
项目变量顾名思义就是作用域只限定与本项目,设置的变量无法作用在其他任何项目上。
- 在具体项目中设置:
5.3 项目临时变量
项目临时变量,即,项目调试、试运行或需要临时覆盖原有变量的特殊参数,优先级最高,会直接覆盖原有的参数,此参数谨慎操作。
- 在具体项目中设置:
六、结束语
Gitlab(版本帝)是一家很拉轰的公司,目前笔者也只是小试牛刀,用了一小部分功能而已,还有一些比如:自定义项目模版,gitlab-registry仓库,codereview等功能还没有真正的使用起来,大家一起加油努力吧,有啥好玩的功能欢迎大家一起交流!