原创
鲜正权 / 叫叫技能团队
现阶段开发人员的作业流程,编写代码、提交、构建、发布。这个过程往往还需求手动履行,简单犯错且很Low,本文将带领我们手摸手完结GitlabCI 自动构建发布,从此高大上~
一、为什么选择Gitlab CI?
现在市面上的 CI/CD 东西有许多,如 **Jenkins**
,**CircleCI**
,**Bamboo**
等,而本文将讲选取 Gitlab CI/CD 进行叙述。
其间原因有下:
- 大部分开发团队都会选择内部建立 Gitalb 作为代码仓库,而 Gitlab CI/CD 内置在 Gitlab 中,不需求额外安装。
- Gitlab CI/CD 的功用丰厚,足以应对大部分devops场景。
- 其间流水线的功用,概念简单,开发者上手门槛低。
二、概念
在运用 Gitlab CI/CD 之前,咱们需求先了解一些概念,这能够帮咱们更简单了解整个 Gitlab CI/CD 运转流程。
1. 流水线(Pipelines)
Gitlab 把在项目中触发的一系列 CI/CD 使命合称 **流水线**
。 一般开发者会把 CI/CD 中的使命按逻辑划分为比如测试,构建,部署等。而这些使命会按次序一个接着一个履行,如同工业流水线一般。
2. 使命(Jobs)
使命是组成流水线的基本要素,是流水线中具体的某个作业。开发者能够自行描绘这些使命的内容与履行方法。
3. 环境变量(Variables)
环境变量不是 CI/CD 的必要部分,但在某些场景下能够完结一些特别需求。官方自有大局环境变量。
一旦装备之后,在流水线就能够直接运用变量的信息。因此一般被用作需求保密信息的记载,如账号密码等。 除此之外,还能够以文件形式保存,但要注意的是当用文件作为变量时,在流水线运用时变量代表的不再是文字内容,而是文件的途径。
4. Runner
ci 需求装备了 runner 之后,才干运用。
三、运用(.gitlab-ci.yml)
GitlabCI就是经过编写 .gitlab-ci.yml
文件来完结。悉数的关键字参考官网文档,本文仅仅举例平常常用的部分。
# 界说阶段
stages:
- build
- deploy
# 界说作业 job
# 名字随意整,只要不整成关键字
job1:
stage: build
script: echo "hello world"
job2:
stage: deploy
script:
- echo "hello world"
- echo "Q:闪钢斩,第三下能够吹风击飞敌人"
大局关键字
阶段 stages
用于界说包括作业组的阶段。在作业(Job)中运用 stage
以将作业装备为在特定阶段运转。
假如 stages未在 .gitlab-ci.yml 文件中界说,则默认管道(Pipelines)阶段为:
.pre
build
test
deploy
.post
项目的 stages
次序 界说了作业的履行次序:
- 同一阶段的作业并行运转。
- 下一阶段的作业在前一阶段的作业成功完结后运转。
假如管道仅包括 .pre
或 .post
阶段中的作业,则它不会运转。在不同的阶段有必要至少有一份其他作业。.pre
和 .post
阶段可用于所需的管道装备 ,以界说有必要在项目管道作业之前或之后运转的合规性作业。
比如:
stages:
- build
- test
- deploy
在这个比如中:
- 一切
stage
为build
的 作业(Job)都会履行。 - 一切
build
都履行成功,则开端履行stage
为test
的一切作业。 - 一切
test
都履行成功,则开端履行stage
为deploy
的一切作业。 - 一切
deploy
都履行成功,则管道(Pipeline)标记为passed
。
其间,假如有任何一个作业(Job)履行失利,整个管道(Pipeline)都将被标记为 failed
,而且一切后续阶段都不会履行。当前阶段的Job不会停止并继续履行。
其他信息
- 假如作业未指定
stage
则会为该 Job 分配test
阶段。 - 假如界说了一个
stage
但没有Job运用它,则该阶段在管道中不行见。
Jobs 关键字
阶段 stage
stage
用于指定 Job 在哪个阶段运转。同一阶段的Job能够并行履行。
假如 stage
未界说,则Job默认运用test
阶段。
stages:
- build
- test
- deploy
job1:
stage: build
script:
- echo "这是一个履行的job,因为该job的stage是 build"
job2:
stage: test
script:
- echo "该job需求等候上个job履行完结才干履行"
job3:
script:
- echo "我和上面那个job相同的,都是 test 阶段履行".
job4:
stage: deploy
script:
- echo "我是现在最终履行的,需求等 test 阶段履行完了才履行。"
first-job:
stage: .pre # 敲黑板,我不受stages次序约束,我就是第一个跑
script:
- echo "不论咋地,我在一切stages之前履行"
last-job:
stage: .post # 敲黑板,我不受stages次序约束,我就是最终一个跑
script:
- echo "不论咋地,我在一切stages之后履行"
script
指定该Job履行啥。
before_script、after_script
和 script
相同,都是该 Job 需求履行的具体内容。 before_script
是在履行 script
履行履行的,after_script
则是在之后。
stages:
- build
- test
- deploy
job1:
stage: build
before_script:
- echo "我在script之前履行"
script:
- echo "这是一个履行的job,因为该job的stage是 build"
job2:
stage: test
script:
- echo "该job需求等候上个job履行完结才干履行"
after_script:
- echo "我在script之前履行"
job4:
stage: deploy
script:
- echo "我是现在最终履行的,需求等 test 阶段履行完了才履行。"
needs
needs
用于乱序履行Job,运用之后能够忽略 stages
的次序运转其他Job。多个阶段的作业能够同时运转。详细介绍
语法:
- 数组,[] 空数组用于将作业设置为在创建管道后当即发动。
- 一系列的Job
linux:build:
stage: build
script: echo "Building linux..."
mac:build:
stage: build
script: echo "Building mac..."
lint:
stage: test
needs: []
script: echo "Linting..."
linux:rspec:
stage: test
needs: ["linux:build"]
script: echo "linux:build履行完结之后履行,不受mac:build影响"
mac:rspec:
stage: test
needs: ["mac:build"]
script: echo "mac:build履行完结之后履行,不受linux:build影响"
production:
stage: deploy
script: echo "Running production..."
environment: production
rules
运用rules
来完结何时履行Job。rules
可用的规矩有:
-
if
:句子为 真时履行。 -
changes
:用于查看特定文件的更改来指定何时履行。 -
exists
:仓库中存在某些文件时履行。 -
allow_failure
:允许 Job 失利而不停止管道。优先级 > Job的allow_failure。 -
variables
:为当前条件界说变量。 -
when
:同下方 when
能够将多个规矩组合在一起,以进行复杂的规矩匹配。
rules:if
- 假如
if
句子为true
,则将Job增加到管道中。 - 假如
if
句子为true
,但是when: never
,则不会将Job增加到管道中。 - 假如没有任何
if
为true
,则不会增加Job到管道中。 -
=~
和!~
右边的表达式会被认定为 正则表达式。
job1:
script: "echo Hello, Rules 1!"
rules:
## 只要在代码 merge 到 master 分支时才会履行。
- if: '$CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "master"'
when: always
job2:
script: "echo Hello, Rules 2!"
rules:
## 只要在代码 commit 到 dev 分支时才会履行。
- if: '$CI_COMMIT_BRANCH == "dev"'
when: always
variables:
VAR_1: "变量1" # 界说变量
job3:
script: "echo Hello, Rules 3!"
rules:
## 只要在代码 commit tag 时才会履行。
- if: '$CI_COMMIT_TAG != null'
when: always
job4:
script: "echo Hello, Rules 4!"
rules:
## 只要在仓库目录下存在 package.json 文件时才会履行。
- exists:
- package.json
job5:
script: "echo Hello, Rules 5!"
rules:
# tag 为 t.x.x 或 v.x.x 时,才会履行
- if: '$CI_COMMIT_TAG =~ /^[t|v]\d+\.\d+\.\d+$/'
when: manual
when
用于制造Job运转条件,假如没有指定,则默以为 on_success
。
可选值:
-
on_success
(默认):当之前阶段一切Job都成功时履行,或许该Job有allow_failure : true
-
manual
:手动触发。 -
always
:不论其他阶段的Job状态,都能够履行。 -
on_failure
:之前阶段的Job至少有一个失利才履行。 -
delayed
:指定延迟时间。 -
never
:不运转该Job。只能在rules
中或许workflow:rules
运用。
stages:
- build
- cleanup_build
- test
- deploy
- cleanup
build_job:
stage: build
script:
- make build
cleanup_build_job:
stage: cleanup_build
script:
- cleanup build when failed
when: on_failure
test_job:
stage: test
script:
- make test
deploy_job:
stage: deploy
script:
- make deploy
when: manual
environment: production
cleanup_job:
stage: cleanup
script:
- cleanup after jobs
when: always
tags
指定该Job运转在哪个服务器。来源是注册runner
时指定的runner
标签。
job:
tags:
- frontend
job2:
tags:
- alicloud
- nodejs
四、方针
最终方针:完结一个业务流程上面的 .gitlab-ci.yml
# 固定的 stages
stages:
- check
- dev
- fat
- uat
- pro
# 代码lint阶段的Job
check:
stage: check # 指定 stage 为 check
script:
- "xxxx script"
# 履行方法: 默认 on_success
only: # 当兼并代码时
- merge_requests
tags:
- tag
dev:
stage: dev
script:
- "xxxx script"
rules:
- if: '$CI_COMMIT_TAG =~ /^[t|v]\d+\.\d+\.\d+$/'
when: manual
tags:
- tag
fat:
stage: fat
script:
- "xxxx script"
rules:
- if: '$CI_COMMIT_TAG =~ /^[t|v]\d+\.\d+\.\d+$/'
when: manual
tags:
- tag
uat:
stage: uat
script:
- "xxxx script"
rules:
- if: '$CI_COMMIT_TAG =~ /^v\d+\.\d+\.\d+$/'
when: manual
tags:
- tag
pro:
stage: pro
script:
- "xxxx script"
rules:
- if: '$CI_COMMIT_TAG =~ /^v\d+\.\d+\.\d+$/'
when: manual
tags:
- tag
五、结束
到现在,信任我们都应该已经完全会gitlabCI了,这玩意儿其实很简单,但还是有几点需求注意:
- stages 不声明会有默认值,声明之后就只会用生命的stage
- Job 称号没有限制
- Job 需求指定 stage
- rules: if 句子有必要是 ” 单引号包裹,if 需求跟 when
- tags 在Job中有必要,否则不会履行Job
- ci 验证:
输入自己的ci内容,点击验证就能够了
参考文献
.gitlab-ci.yml
keyword reference | GitLab