gitlab CI/CD :创建一个复杂的pipeline流水线

教程内容原文地址:Tutorial: Create a complex pipeline ,当前教程版本:16.1


本教程通过小的迭代步骤引导您配置一个日益复杂的 CI/CD 流水线。流水线始终具有完整的功能,但是每一步都会获得更多的功能。

当你完成这个教程,你就可以在gitlab.com中拥有自己的新项目,并且可以在Docusarus中让你的文档网站运行起来。

Docusaurus 是 Facebook 专门为开源项目开发者提供的一款易于维护的静态网站创建工具,使用 Markdown 即可更新网站。构建一个带有主页、文档、API、帮助以及博客页面的静态网站,只需5分钟。

拓展知识:Docusaurus 快速建站 - 作者:eqera

为了完成这个教程,你将要做到:

  1. 创建一个项目来保存 Docusaurus 文件
  2. 创建一个初始化pipeline流水线配置文件
  3. 添加一个 job 来构建这个站点
  4. 添加一个 job 来部署这个站点
  5. 添加多个测试用的 job
  6. 开始使用合并请求pipelines流水线
  7. 减少重复的配置

先决条件

  • 你需要在gitlab.com有用一个帐号
  • 你应该熟悉 Git
  • 在你的本地机器中必须安装node.js。举个例子,在macOs中你可以通过brew install node 来安装node。

创建一个项目来保存 Docusaurus 文件

在添加pipeline 配置前,你必须先在 gitlab.com 中创建一个 Docusaurus 项目:

  1. 在你的用户名下(非分组名)创建一个新项目:
    a. 在顶部栏,选择Main menu > Projects > View all projects(主菜单>项目>查看所有项目)
    b. 在页面的右侧,选择New project(新项目)
    c. 选择Create blank project(创建空白项目)
    d. 输入项目的详细信息:
    Project name(项目名)字段中,输入你项目的名字,例如你的项目的名字是my-pipeline-tutorial-project
    选择Initialize repository with a README(使用README初始化仓库)
    e. 选择Create project(创建项目)
  2. 在项目的Project Overview(项目概述)页的右侧,选择Clone(克隆)以查找项目的克隆路径。复制 SSH 或 HTTP 路径并使用该路径在本地克隆项目。
    例如,通过SSH克隆仓库到你电脑中的pipeline-tutorial目录中:

在这里假设,你在gitlab.com的用户名是my-username,你的项目名称是my-pipeline-tutorial-project,你要克隆my-pipeline-tutorial-project项目,到本地(你的电脑)的文件目录名称是pipeline-tutorial

git clone git@gitlab.com:my-username/my-pipeline-tutorial-project.git pipeline-tutorial

  1. 进入到项目的目录,然后生成一个新的 Docusaurus 站点
cd pipeline-tutorial
npm init docusaurus

Docusaurus 的初始化向导会提示你一些关于站点的问题,在这里你可以使用所有的默认选项来创建Docusaurus。
(或者你可以阅读一些扩展文章:Docusaurus 快速建站 - 作者:eqera 来实现个性化配置。)

  1. Docusaurus 的初始化向导在 website/中设置站点,但这个站点应该要位于项目的根目录中。所以我们要将文件上移到根目录并删除旧目录:
mv website/* .
rm -r website
  1. 用 GitLab 项目的详细信息更新 Docusaurus 配置文件。在docusaurus.config.js中:
  • url:, 将 url: 设置为这种https://<my-username>.gitlab.io/格式的路径,如果你的用户名是wataru,那么路径就是:https://wataru.gitlab.io/
  • baseUrl:,将 baseUrl: 设置为你的项目名称,如/my-pipeline-tutorial-project/
  1. 提交以上这些修改,然后把这些修改推送到 gitlab 上
git add .
git commit -m "添加简单生成的Docusaurus站点"
git push origin

创建初始CI/CD的配置文件

从最简单的pipeline配置文件开始,以确保在项目中启用CI/CD,并且runner(运行程序)可以运行job(作业)。

步骤介绍:

  • Jobs: 这些是pipeline自包含的部分,用于运行你的命令。Jobs(作业)在runner(运行程序)上运行,独立于gitlab实例。
  • script:job配置的这个部分,是为jobs定义命令的地方。如果(在数组中)有多个命令,它们会按顺序运行。每条命令执行的方式就像它作为CLI命令运行一样。默认情况下,如果一条命令失败了或者返回一个错误,这个job就会被标记为失败,并且不再运行剩下的命令。

在这一步,在项目的根目录创建一个.gitlab-ci.yml 文件(缺了第一个.将不会识别为gitlab ci 的配置文件,这是容易疏漏的地方),用来测试一下这个job在gitlab上能不能正常运行。

test-job: # 测试作业(test-job名字可修改,是某个阶段的job名称)
	script: # 定义命令的关键词script
		- echo "This is my first job!" # 输出 "This is my first job!"
		- date # 打印日期

提交并推送这些修改到gitlab上,然后:

  1. 前往gitlab的 Build > Pipelines(构建>流水线),确保gitlab的流水线上有运行这个job。
  2. 选择这条pipeline,然后选择这个job来查看job的日志,你会看到echo命令输出的This is my first job!消息,以及消息后跟着的日期。

现在你的项目有了.gitlab-ci.yml文件,你可以在pipeline editor流水线编辑器中,修改所有未来你需要用到的配置。

添加一个job来构建站点

CI/CD 流水线任务通常是用来构建项目的代码并且部署它。从添加构建站点的job开始。
步骤说明:

  • image: 告诉运行程序用哪个Docker 容器来运行这个job。这个运行程序包括:
      1. 下载容器image镜像并且启动镜像。
      1. 克隆你的gitlab项目进入到这个运行中的容器里。
      1. 运行script命令,一次一个。
  • artifacts:jobs是自包含的,job和job之间不会分享任何资源。如果你想要在一个job中生成的文件能在另一个job使用,你必须先将它们保存到 artifacts 中。后续的job就可以检索这些artifacts,并且使用已生成的文件。

在这一步,我们将上一步的test-job测试作业改为build-job构建作业:

  • 使用image 来配置这个job来运行最新的node镜像。Docusaurus 是一个Node.js 项目,这个node镜像内置了我们所需的npm命令。
  • 运行npm install,把Docusaurus安装到运行中的node容器中,然后运行npm run build来构建站点
  • Docusaurus 将我们构建的站点保存到了 build/目录下,所以我们要把构建出的这些文件保存到 artifacts中,以便后续job能够使用。
build-job: # 构建作业
	image: node # 运行的镜像:node
	script: # 作业要运行的命令
		- npm install # 通过npm 安装项目需要的依赖包
		- npm run build # 通过npm 构建代码
	artifacts: 
		paths:
			- "build/"

使用流水线编辑器来提交这个流水线配置文件到默认分支,然后检查这个job的日志。你可以:

  • 看到npm的命令运行并且构建这个站点
  • 验证最后是否保存了artifacts
  • 在作业完成后,通过选择job日志右侧的Browse(浏览)来浏览artifacts的文件内容

添加一个job来部署这个站点

build-job验证完Docusaurus 站点的构建后,你可以添加一个job来部署它。
步骤说明:

  • stagestages:最常见的流水线配置是将job作业分组成多个阶段。相同阶段的job作业可以并行运行,而后面的stage阶段的job作业则需要等待前面的stage阶段的job完成。如果一个job失败了,那么整个stage阶段都将被认为失败了并且后面stage阶段的job不再开始运行。
  • Gitlab Pages:为了托管你的静态站点,你将要使用 Gitlab Pages 。

在这一步骤中:

  • 添加一个job用来构建站点并且部署它。当使用Gitlab Pages时,这个job需要被命名为pagesbuild-job中的artifacts会被自动获取,并且被提取到这个job中。由于页面会在/public目录下查找站点,所以要添加一个script脚本命令,将这个站点移动到/public目录中。
  • 增加一个stages阶段部分,然后为每一个job定义多个阶段stages。最先运行的是在build阶段的build-job作业,然后运行的是deploy部署阶段的pages作业。
stages: # 阶段总览,一共有哪些阶段,并且定义这些阶段的顺序
	- build # 构建阶段,第一个运行
	- deploy # 部署阶段,第二个运行

# 设置一个作业在 build 阶段运行
build-job: # 构建作业的名称:build-job
	stage: build # 属于 build 阶段
	image: node # 这个作业使用的镜像是 node 的镜像
	script: # 脚本命令
		- npm install # 安装项目所需的依赖包
		- npm run build # 构建项目代码
	artifacts: # 工件,用来保存文件
		paths: # 路径
			- "build/" # 保存了“build/”这个目录下的文件

# 设置一个新的作业在 deploy 阶段运行
pages:  # 部署作业的名称:pages
	stage: deploy # 属于 deploy 阶段
	script: # 脚本命令
		- mv build/ public/ # 移动 build/ 目录下的文件到 public/ 目录下
	artifacts: # 工件,用来保存文件
		paths: # 路径
			- "public/" # 保存了“public/”这个目录下的文件

使用流水线编辑器来提交这个流水线配置到默认分支,在 Pipelines(流水线)列表中查看流水线的细节。验证以下几点:

  • 有两个job运行在不同的stages中,stages分别是builddeploy
  • pages job 完成后,会出现一个pages-deploy 的job,pages-deploy 是部署 Pages 站点的 Gitlab 进程。当这个job完成后,你就可以访问你的新 Docusaurus 站点了。Pages 的说明文档解释了 URL的格式,它必须类似于 https://<my-username>.gitlab.io/<my-pipeline-tutorial-project>/,例如: https://wataru.gitlab.io/my-pipeline-tutorial-project/ ,my-pipeline-tutorial-project是该项目的名称,见上文 baseUrl的设置。

添加测试jobs

既然站点按照预期构建和部署了,你可以添加一些测试和linting。例如,一个Ruby 项目可能运行 RSpec 测试作业。Docusaurus 是一个生成于HTML使用Markdown 的静态站点,所以这个教程添加一些作业来测试 Markdown 和 HTML。
这个步骤的介绍:

  • allow_failure: 间歇性发生故障的作业,或者预计会失败的作业,会导致降低生产效率或者增加故障排查的的难度。使用 allow_failure 让这些作业失败的时候,不会停止流水线的执行。
  • dependencies:通过列出从哪些jobs获取artifacts,使用dependencies来控制各个作业的artifacts下载。

在本步骤中:

  • builddeploy阶段之间添加一个test 阶段。当配置文件中stages是undefined未定义时,默认的阶段就是buildtestdeploy这三个阶段。
  • 添加一个lint-markdown作业区运行 markdownlint ,并且检查你项目中的 Markdown 。 markdownlint 是一个静态分析工具,用来检查你的Markdown 文件是否符合格式标准。
    • Docusaurus 生成的 Markdown 文件样本在 blog/docs/目录下。
    • 这个工具只扫描原始的Markdown 文件,不需要在 build-job 的 artifacts 中保存生成的HTML。用dependencies:[]加速这个作业,好让他不去获取返回 artifacts。
    • 一些Markdown 文件样本违反了默认的markdownlint 规则,所以要增加 allow_failure: true 配置,来让流水线在有违反规则的情况下能继续运行。
  • 添加一个test-html作业来运行 HTMLHint,来检查生成的HTML。HTMLHint 是一个静态分析工具,用于扫描生成的HTML中的已知问题。
  • test-htmlpages都需要在 build-job 的 artifacts 中找到生成的HTML。作业默认从前面阶段的所有作业中获取返回 artifacts,但是添加 dependencies: 能确保在未来的一些流水线变化之后,这个作业不会意外下载其他的 artifacts 。
stages: # 阶段总览,一共有哪些阶段,并且定义这些阶段的顺序
	- build # 构建阶段,第一个运行
	- test # 测试阶段,第二个运行
	- deploy # 部署阶段,第三个运行

# 设置一个作业在 build 阶段运行
build-job: # 构建作业的名称:build-job
	stage: build # 属于 build 阶段
	image: node # 这个作业使用的镜像是 node 的镜像
	script: # 脚本命令
		- npm install # 安装项目所需的依赖包
		- npm run build # 构建项目代码
	artifacts: # 工件,用来保存文件
		paths: # 路径
			- "build/" # 保存了“build/”这个目录下的文件

# 设置一个新的作业在 test 阶段运行
lint-markdown:  # 测试作业的名称:lint-markdown
	stage: test # 属于 test 阶段
	image: node # 这个作业使用的镜像是 node 的镜像
	dependencies: [] # 不要获取任何artifacts
	script: # 脚本命令
		- npm install markdownlint-cli2 --global # 通过npm 全局安装markdownlint-cli2
		- markdownlint-cli2 -v # 查询markdownlint-cli2的版本
		- markdownlint-cli2 "blog/**/*.md" "docs/**/*.md" # 使用markdownlint-cli2 对blog/和docs/目录下的.md文件进行格式检测
	allow_failure: true # 允许失败,lint-markdown测试失败后,可以继续运行 test-html 作业
	
# 设置一个新的作业在 test 阶段运行
test-html:  # 测试作业的名称:test-html
	stage: test # 属于 test 阶段
	image: node # 这个作业使用的镜像是 node 的镜像
	dependencies: # 依赖关系
		- build-job # 依赖于 build-job 中的artifacts
	script: # 脚本命令
		- mv build/ public/  # 移动 build/ 目录下的文件到 public/ 目录下
	artifacts: # 工件,用来保存文件
		paths: # 路径
			- "public/" # 保存了“public/”这个目录下的文件

将这个流水线配置提交到默认分支,并查看流水线的详细信息。

  • test-markdown作业失败了,因为Markdown 样本文件违反了默认的markdownlint规则,但是这个作业是允许失败的。你可以:
    • 现在忽视这些违反的情况。在这个教程中,这不是必须解决的部分。
    • 修复这些markdown文件违反规则的地方,然后你可以将 allow_failure改为false,或者完全移除 allow_failure,因为在它为定义的时候,allow_failure: false 是默认行为。
    • 添加一个markdownlint配置文件,来限制对哪些违反规则的行为发出警告。
  • 你也可以在markdown 文件修改一些内容,然后在下一次部署后,看看站点上发生了哪些变化。

开始使用合并请求流水线

通过上面的流水线配置,每次流水线成功完成后,这个站点都会部署一次,但这并不是一个理想的开发工作流。更好的做法是在功能分支上开发功能,然后合并请求,只有当修改的内容合并到默认分支后才会部署站点。
这一步骤的介绍:

  • rules:向每个作业添加rules规则,来配置它们在哪些流水线运行。你可以将作业配置为:在合并请求流水线、计划流水线,或者其他特殊情况下运行。rules规则从上至下来评估,如果一条rule规则匹配上了,就将这个作业添加进流水线中。
  • CI/CD variables:在配置文件中使用这些环境变量来配置作业的行为和脚本命令。Predefined CI/CD variables预置CI/CD变量是你不需要手动定义的变量。它们自动注入到流水线中,所以你可以直接使用这些变量来配置流水线。变量的格式通常和$VARIABLE_NAME一样,预置变量通常以$CI_开头。

在这一步骤中:

  • 创建一个新的功能分支,在这个分支而非默认分支上进行更改。
  • 向每个作业添加rules
    • 这个站点应该只在默认分支有变更的时候才部署
    • 对于合并请求或默认分支中的所有功能更改,应该运行其他作业。
  • 通过这个流水线配置,你可以在功能分支上工作,而不需要运行任何作业,达到节省资源的目的。当你准备校验你的更改时,就创建一个合并请求,运行流水线,其中作业配置为在合并请求时才运行。
  • 当你的合并请求被接受并且更改都合并到默认分支时,一条包含pages部署作业的新流水线便会运行。如果没有作业失败,站点就会部署。
stages:
	- build
	- test
	- deploy

build-job
	stage: build
	image: node
	script:
		- npm install
		- npm run build
	artifacts:
		paths:
			- "build/"
	rules:
		- if: $CI_PIPELINE_SOURCE == 'merge_request_event'
		- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH

lint-markdown:
	stage: test
	image: node
	dependencies: []
	script:
		- npm install markdownlist-cli2 --global
		- markdownlist-cli2 -v
		- markdownlist-cli2 "blog/**/*.md" "docs/**/*.md"
	allow_failure: true
	rules:
		- if: $CI_PIPELINE_SOURCE == 'merge_request_event'
		- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH

test-html:
	stage: test
	image: node
	dependencies:
		- build-job
	script:
		- npm install htmlhint --save-dev
		- npx htmlhint --version
		- npx htmlhint build/
	rules:
		- if: $CI_PIPELINT_SOURCE == 'merge_request_event'
		- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH

pages:
	stage: deploy
	dependencies:
		- build-job
	script:
		- mv build/ public/
	artifacts:
		paths:
			- "public/"
	rules:
		- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
	

在合并请求中合并更改的内容。此操作更新默认分支。验证这条新流水线是否包含了用来部署站点的pages作业。
对流水线配置未来所有的更改,请确保使用功能分支和合并请求。其他项目更改(如创建 Git 标签或添加流水线计划),不会触发流水线,除非你也为这些情况添加规则。

减少重复的配置

现在,流水线包含三个作业,它们都有相同的rulesimage配置。使用extendsdefault创建一条单独的sources of truth真相来源,来代替三条重复的规则。
该步骤介绍:

  • Hidden jobs:以.开头的作业永不添加到流水线中。通过这些隐藏的作业保存你想重复使用的配置。
  • extends:使用extends扩展在多个位置的重复配置,通常来自隐藏作业中。如果你更新隐藏作业中的配置,所有通过隐藏作业扩展的作业就会使用更新后的配置。
  • default:设置默认关键词。在没有定义关键词的时候,默认关键词会被添加到所有作业中。
  • 重写YAML:当使用extends(扩展)和default(默认配置)复用配置时,可以在作业中显示定义一个关键词来重写extendsdefault配置。

在这一步:

  • 添加一个.standard-rules隐藏作业来保存build-joblint-markdowntest-html三个作业中重复的规则。
  • 在这三个作业中,使用 extends 来复用.standard-rules的配置。
  • 添加default(默认配置)部分,定义node作为默认的镜像。
  • pages部署作业不需要node作为默认镜像,所以明确使用busybox,这是一个非常小而快的镜像。
stages:
  - build
  - test
  - deploy

default:
	image: node

.standard-rules:
	rules:
		- if: $CI_PIPELINE_SOURCE == 'merge_request_event'
	    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH

build-job:
	stage: build
	extends:
		- .standard-rules
    script:
    	- npm install
    	- npm run build
  	artifacts:
    	paths:
      		- "build/"

lint-markdown:
  stage: test
  extends:
    - .standard-rules  # Reuse the configuration in `.standard-rules` here
  dependencies: []
  script:
    - npm install markdownlint-cli2 --global
    - markdownlint-cli2 -v
    - markdownlint-cli2 "blog/**/*.md" "docs/**/*.md"
  allow_failure: true

test-html:
  stage: test
  extends:
    - .standard-rules  # Reuse the configuration in `.standard-rules` here
  dependencies:
    - build-job
  script:
    - npm install --save-dev htmlhint
    - npx htmlhint --version
    - npx htmlhint build/

pages:
	stage: deploy
	image: busybox
	dependencies:
    	- build-job
  	script:
    	- mv build/ public/
  	artifacts:
	    paths:
      		- "public/"
  	rules:
    	- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH

使用合并请求将此流水线配置提交到默认分支。这个文件更简单了,但它应该具有与上一步相同的行为。

你刚刚创建了一个完整的流水线,并对其进行了精简以提高效率。现在,你可以学习这些知识,了解其余的.gitlab-ci.yml关键字,并构建自己的流水线。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值