前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。
简介
GitLab Community Edition 是一个自托管的 Git 仓库提供商,具有额外的功能来帮助项目管理和软件开发。GitLab 提供的最有价值的功能之一是内置的持续集成和交付工具,称为 GitLab CI。
在本指南中,我们将演示如何设置 GitLab CI 来监视您的存储库的更改并运行自动化测试来验证新代码。我们将从一个正在运行的 GitLab 安装开始,在那里我们将复制一个基本的 Node.js 应用程序的示例存储库。配置我们的 CI 过程后,当向存储库推送新提交时,GitLab 将使用 CI 运行程序在隔离的 Docker 容器中执行代码的测试套件。
先决条件
在开始之前,您需要设置一个初始环境。我们需要一个安全的 GitLab 服务器,用于存储我们的代码并管理我们的 CI/CD 过程。此外,我们需要一个地方来运行自动化测试。这可以是安装了 GitLab 的同一服务器,也可以是一个单独的主机。以下部分详细介绍了要求。
使用 SSL 安全保护的 GitLab 服务器
为了存储源代码并配置我们的 CI/CD 任务,我们需要在 Ubuntu 16.04 服务器上安装 GitLab 实例。GitLab 目前建议使用至少 2 个 CPU 核心 和 4GB 的 RAM 的服务器。为了保护您的代码免受暴露或篡改,GitLab 实例将使用 Let's Encrypt 进行 SSL 保护。您的服务器需要有一个域名或与之关联的子域名,以完成此步骤。
您可以使用以下教程完成这些要求:
- 使用 Ubuntu 16.04 进行初始服务器设置:创建一个
sudo
用户并配置基本防火墙 - 如何在 Ubuntu 16.04 上安装和配置 GitLab:在服务器上安装 GitLab 并使用 Let's Encrypt TLS/SSL 证书进行保护
我们将演示如何在项目之间共享 CI/CD 运行程序(运行自动化测试的组件)以及如何将它们锁定到单个项目。如果您希望在项目之间共享 CI 运行程序,我们强烈建议您限制或禁用公共注册。如果您在安装过程中没有修改设置,请返回并按照 GitLab 安装文章中限制或禁用注册的可选步骤)以防止外部方的滥用。
一个或多个用作 GitLab CI 运行程序的服务器
GitLab CI 运行程序是检出代码并运行自动化测试以验证新更改的服务器。为了隔离测试环境,我们将在 Docker 容器中运行所有自动化测试。为此,我们需要在将运行测试的服务器上安装 Docker。
这一步可以在 GitLab 服务器上完成,也可以在不同的 Ubuntu 16.04 服务器上完成,以提供额外的隔离并避免资源争用。以下教程将在您希望用于运行测试的主机上安装 Docker:
- 使用 Ubuntu 16.04 进行初始服务器设置:创建一个
sudo
用户并配置基本防火墙(如果您正在为 GitLab 服务器设置 CI 运行程序,则无需再次完成此步骤) - 如何在 Ubuntu 16.04 上安装和使用 Docker:按照 步骤 1 和 2 在服务器上安装 Docker
当您准备好开始时,请继续阅读本指南。
从 GitHub 复制示例存储库
首先,我们将在 GitLab 中创建一个包含示例 Node.js 应用程序的新项目。我们将直接从 GitHub 导入原始存储库,以便我们不必手动上传它。
登录到 GitLab,单击右上角的 加号图标 ,然后选择 新项目 添加一个新项目:
!GitLab 添加新项目图标
在新项目页面上,单击 导入项目 选项卡:
!GitLab 新项目名称
接下来,单击 通过 URL 导入 按钮。虽然有一个 GitHub 导入选项,但它需要个人访问令牌,并用于导入存储库和其他信息。我们只对代码和 Git 历史感兴趣,因此通过 URL 导入更容易。
在 Git 存储库 URL 字段中,输入以下 GitHub 存储库 URL:
https://github.com/do-community/hello_hapi.git
它应该看起来像这样:
!GitLab 新项目 GitHub URL
由于这是一个演示,最好将存储库标记为 私有 。完成后,单击 创建项目。
新项目将基于从 GitHub 导入的存储库创建。
理解 .gitlab-ci.yml 文件
GitLab CI 在每个存储库中查找名为 .gitlab-ci.yml
的文件,以确定应该如何测试代码。我们导入的存储库已经为项目配置了 gitlab-ci.yml
文件。您可以通过阅读 .gitlab-ci.yml 参考文档 了解更多有关格式的信息。
单击 GitLab 界面中刚创建的项目的 .gitlab-ci.yml
文件。CI 配置应该如下所示:
yaml
image: node:latest
stages:
- build
- test
cache:
paths:
- node_modules/
install_dependencies:
stage: build
script:
- npm install
artifacts:
paths:
- node_modules/
test_with_lab:
stage: test
script: npm test
该文件使用 GitLab CI YAML 配置语法来定义应采取的操作、它们应该执行的顺序、应在何种条件下运行以及完成每个任务所需的资源。在编写自己的 GitLab CI 文件时,您可以访问 /ci/lint
在您的 GitLab 实例中进行语法检查,以验证您的文件格式是否正确。
配置文件首先声明应该用于运行测试套件的 Docker image
。由于 Hapi 是一个 Node.js 框架,我们使用最新的 Node.js 图像:
yaml
image: node:latest
接下来,我们明确定义了不同的持续集成阶段:
yaml
stages:
- build
- test
您在这里选择的名称是任意的,但顺序决定了接下来将执行的步骤的顺序。阶段是可以应用于单个作业的标签。GitLab 将并行运行相同阶段的作业,并将等待执行下一个阶段,直到当前阶段的所有作业完成。如果没有定义阶段,GitLab 将使用三个名为 build
、test
和 deploy
的阶段,并默认将所有作业分配给 test
阶段。
在定义阶段之后,配置包括一个 cache
定义:
yaml
cache:
paths:
- node_modules/
这指定可以在运行或阶段之间缓存(保存以供以后使用)的文件或目录。这可以帮助减少依赖于在运行之间可能不会更改的资源的作业运行时间。在这里,我们正在缓存 node_modules
目录,这是 npm
将下载的依赖项的位置。
我们的第一个作业称为 install_dependencies
:
yaml
install_dependencies:
stage: build
script:
- npm install
artifacts:
paths:
- node_modules/
作业可以命名为任何内容,但因为名称将在 GitLab UI 中使用,因此有助于使用描述性名称。通常,npm install
可以与下一个测试阶段合并,但为了更好地演示阶段之间的交互,我们正在提取此步骤以在其自己的阶段中运行。
我们使用 stage
指令明确标记阶段为 "build"。接下来,我们使用 script
指令指定要运行的实际命令。您可以通过在 script
部分内添加额外的行来包含多个命令。
artifacts
子部分用于指定要在阶段之间保存和传递的文件或目录路径。因为 npm install
命令会安装项目的依赖项,我们的下一步将需要访问下载的文件。声明 node_modules
路径确保下一个阶段将可以访问这些文件。这些文件也将在测试后可以在 GitLab UI 中查看或下载,因此这对于构建二进制文件等构建工件非常有用。如果要保存阶段期间产生的所有内容,请将整个 paths
部分替换为 untracked: true
。
最后,第二个作业称为 test_with_lab
,声明了实际运行测试套件的命令:
yaml
test_with_lab:
stage: test
script: npm test
我们将其放在 test
阶段。由于这是一个较晚的阶段,它可以访问由 build
阶段产生的构建工件,这在我们的情况下是项目依赖项。在这里,script
部分演示了当只有一个项目时可以使用的单行 YAML 语法。我们也可以在前一个作业中使用相同的语法,因为只指定了一个命令。
现在您对 .gitlab-ci.yml
文件如何定义 CI/CD 任务有了基本的了解,我们可以定义一个或多个能够执行测试计划的运行程序。
触发持续集成运行
由于我们的仓库包含一个 .gitlab-ci.yml
文件,任何新的提交都将触发新的 CI 运行。如果没有可用的运行程序,CI 运行将被设置为 "pending"。在我们定义运行程序之前,让我们触发一个 CI 运行,以查看处于挂起状态的作业是什么样子的。一旦有运行程序可用,它将立即接管挂起的运行。
回到 hello_hapi
GitLab 项目仓库视图,在分支和项目名称旁边点击加号 ,然后从菜单中选择新建文件:
!GitLab 新建文件按钮
在下一个页面,输入 dummy_file
在文件名字段中,并在主编辑窗口中输入一些文本:
!GitLab 虚拟文件
完成后点击底部的提交更改。
现在,返回到主项目页面。最新提交将附有一个小的暂停图标。如果你将鼠标悬停在图标上,它将显示 "提交:pending":
!GitLab 挂起标记
这意味着尚未运行验证代码更改的测试。
要获取更多信息,转到页面顶部并点击流水线。您将进入流水线概览页面,在这里您可以看到 CI 运行被标记为 pending,并标记为 "stuck":
!GitLab 流水线索引 stuck
从这里,您可以点击pending状态以获取有关运行的更多详细信息。此视图显示了我们运行的不同阶段,以及与每个阶段相关联的单独作业:
!GitLab 流水线详细视图
最后,点击install_dependencies作业。这将为您提供有关延迟运行的具体细节:
!GitLab 作业详细视图
在这里,消息表明作业因缺乏运行程序而被卡住。这是预期的,因为我们尚未配置任何运行程序。一旦有运行程序可用,同样的界面可以用来查看输出。这也是您可以在构建过程中下载生成的工件的位置。
现在我们知道了挂起作业的样子,我们可以为我们的项目分配一个 CI 运行程序来接管挂起的作业。
安装 GitLab CI 运行程序服务
现在我们准备设置一个 GitLab CI 运行程序。为此,我们需要在系统上安装 GitLab CI 运行程序包并启动 GitLab 运行程序服务。该服务可以为不同项目运行多个运行程序实例。
如先决条件中所述,您可以在托管 GitLab 实例的同一服务器上完成这些步骤,或者如果您想确保避免资源争用,也可以在不同的服务器上完成。请记住,无论您选择哪个主机,您都需要安装 Docker 以便使用我们将要使用的配置。
安装 GitLab CI 运行程序服务的过程类似于安装 GitLab 本身的过程。我们将下载一个脚本以将 GitLab 仓库添加到我们的 apt
源列表中。运行脚本后,我们将下载运行程序包。然后我们可以配置它来为我们的 GitLab 实例提供服务。
首先,将最新版本的 GitLab CI 运行程序仓库配置脚本下载到 /tmp
目录(这是一个与 GitLab 服务器使用的不同的仓库):
command
curl -L https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh -o /tmp/gl-runner.deb.sh
随时随地检查下载的脚本,以确保您对它将要执行的操作感到满意。您也可以在这里找到托管版本的脚本:
command
less /tmp/gl-runner.deb.sh
一旦您对脚本的安全性感到满意,运行安装程序:
command
sudo bash /tmp/gl-runner.deb.sh
该脚本将设置您的服务器以使用由 GitLab 维护的仓库。这使您可以使用与其他系统软件包相同的软件包管理工具来管理 GitLab 运行程序包。完成后,您可以继续使用 apt-get
进行安装:
command
sudo apt-get install gitlab-runner
这将在系统上安装 GitLab CI 运行程序包并启动 GitLab 运行程序服务。
设置 GitLab 运行程序
接下来,我们需要设置一个 GitLab CI 运行程序,以便它可以开始接受工作。
为此,我们需要一个 GitLab 运行程序令牌,以便运行程序可以与 GitLab 服务器进行身份验证。我们需要的令牌类型取决于我们希望如何使用此运行程序。
项目特定运行程序 在运行程序有特定要求时非常有用。例如,如果您的 gitlab-ci.yml
文件定义了需要凭据的部署任务,则可能需要特定的运行程序才能正确地进行部署环境的身份验证。如果您的项目在 CI 过程中有资源密集型步骤,这也可能是一个好主意。项目特定运行程序将不接受来自其他项目的作业。
另一方面,共享运行程序是一个通用的运行程序,可以被多个项目使用。运行程序将根据一个算法从项目中接受作业,该算法考虑了每个项目当前正在运行的作业数量。这种类型的运行程序更加灵活。您需要使用管理员帐户登录 GitLab 来设置共享运行程序。
我们将在下面演示如何获取这两种运行程序类型的运行程序令牌。选择最适合您的方法。
收集信息以注册特定项目的 Runner
如果您希望将 Runner 与特定项目关联,首先导航到 GitLab 界面中项目的页面。
在此处,点击左侧菜单中的 设置 项。然后,点击子菜单中的 CI/CD 项:
!GitLab 项目设置项
在此页面上,您将看到一个 Runners 设置 部分。点击 展开 按钮以查看更多细节。在详细视图中,左侧将解释如何注册特定项目的 Runner。复制在说明的第 4 步中显示的注册令牌:
!GitLab 特定 Runner 配置设置
如果您希望为此项目禁用任何活动的共享 Runner,可以通过点击右侧的 禁用共享 Runner 按钮来执行。这是可选的。
当您准备好时,可以跳转到下一步,了解如何使用从此页面收集的信息注册您的 Runner。
收集信息以注册共享 Runner
要找到注册共享 Runner 所需的信息,您需要使用管理员帐户登录。
首先,点击顶部导航栏中的 扳手图标 以访问管理区域。在左侧菜单的 概览 部分,点击 Runners 以访问共享 Runner 配置页面:
!GitLab 管理区域图标
复制显示在页面顶部的注册令牌:
!GitLab 共享 Runner 令牌
我们将使用此令牌为项目注册 GitLab CI Runner。
在 GitLab 服务器上注册 GitLab CI Runner
现在您已经有了一个令牌,返回到安装了您的 GitLab CI Runner 服务的服务器。
要注册一个新的 Runner,请输入以下命令:
command
sudo gitlab-runner register
您将被要求回答一系列问题以配置 Runner:
请输入 gitlab-ci 协调员 URL(例如 https://gitlab.com/)
输入您的 GitLab 服务器的域名,使用 https://
指定 SSL。您可以选择在您的域名末尾附加 /ci
,但是最近的版本将自动重定向。
请输入此 Runner 的 gitlab-ci 令牌
您在上一节中复制的令牌。
请输入此 Runner 的 gitlab-ci 描述
此特定 Runner 的名称。这将显示在命令行和 GitLab 界面的 Runner 服务列表中。
请输入此 Runner 的 gitlab-ci 标签(逗号分隔)
这些是您可以分配给 Runner 的标签。GitLab 作业可以根据这些标签的要求来确保它们在具有正确依赖项的主机上运行。
在这种情况下,您可以将其留空。
是否将 Runner 锁定到当前项目 [true/false]
将 Runner 分配给特定项目。它不能被其他项目使用。
在这里选择 "false"。
请输入执行者
Runner 用于完成作业的方法。
在这里选择 "docker"。
请输入默认的 Docker 镜像(例如 ruby:2.1)
在 .gitlab-ci.yml
文件中不包括镜像规范时用于运行作业的默认镜像。最好在这里指定一个通用镜像,并在您的 .gitlab-ci.yml
文件中定义更具体的镜像,就像我们所做的那样。
在这里输入 "alpine:latest" 作为一个小型、安全的默认值。
回答完提示后,将创建一个新的 Runner,能够运行您项目的 CI/CD 任务。
您可以通过输入以下命令来查看 GitLab CI Runner 服务当前可用的 Runner:
command
sudo gitlab-runner list
列出配置的 Runner ConfigFile=/etc/gitlab-runner/config.toml
example-runner Executor=docker Token=e746250e282d197baa83c67eda2c0b URL=https://example.com
现在我们有一个可用的 Runner,可以返回到 GitLab 中的项目。
在 GitLab 中查看 CI/CD 运行
回到您的网络浏览器,返回到 GitLab 中的项目。根据您注册 Runner 的时间长短,Runner 可能正在运行:
!GitLab CI 运行图标
或者它可能已经完成:
!GitLab CI 运行通过图标
无论状态如何,点击 运行中 或 通过 图标(如果遇到问题则点击 失败 )以查看当前 CI 运行的状态。您也可以通过点击顶部的 流水线 菜单来获得类似的视图。
您将被带到流水线概览页面,在那里您可以看到 GitLab CI 运行的状态:
!GitLab CI 流水线运行概览
在 阶段 标头下,将有一个圆圈指示运行中的每个阶段的状态。如果点击阶段,您可以看到与该阶段相关的各个作业:
!GitLab CI 流水线运行阶段视图
点击 build 阶段中的 install_dependencies 作业。这将带您到作业概览页面:
!GitLab CI 流水线作业概览
现在,不再显示关于没有可用 Runner 的消息,而是显示作业的输出。在我们的情况下,这意味着您可以看到 npm
安装每个软件包的结果。
在右侧,您还可以看到一些其他项目。您可以通过更改 阶段 并点击下面的运行来查看其他作业。您还可以查看或下载运行产生的任何构件。
结论
在本指南中,我们向 GitLab 实例添加了一个演示项目,以展示 GitLab CI 的持续集成和部署能力。我们讨论了如何在 gitlab-ci.yml
文件中定义流水线,以构建和测试您的应用程序,以及如何将作业分配给阶段,以定义它们之间的关系。然后,我们设置了一个 GitLab CI runner 来接收我们项目的 CI 作业,并演示了如何查找有关单个 GitLab CI 运行的信息。