在这一系列文章中,我想向大家介绍并探讨使用 InterSystems 技术和 GitLab 进行软件开发可以采用的几种方式。 我将介绍以下主题:
- Git 101
- Git 流程(开发流程)
- GitLab 安装
- GitLab 工作流
- 持续交付
- GitLab 安装和配置
- GitLab CI/CD
在上一篇文章中,我们介绍了 Git 基础知识、深度理解 Git 概念对现代软件开发至关重要的原因,以及如何使用 Git 开发软件。 我们的侧重点仍是软件开发的实现部分,但本部分会介绍:
- GitLab 工作流 - 从想法到用户反馈的完整软件生命周期流程
- 持续交付 – 软件工程方式,团队通过这种方式在短周期内制作软件,从而确保软件可以随时实现可靠发布。 它的目的是更快速、更频繁地构建、测试和发布软件。
GitLab 工作流
GitLab 工作流是软件开发流程整个生命周期中可能采取的操作的逻辑序列。
GitLab 工作流会考虑我们在上一篇文章中探讨的 GitLab 流程。 具体如下:
- 想法:每个新提议都始于一个想法。
- 问题:探讨想法最有效的方法是为它创建问题。 您的团队和协作者可以在问题跟踪器中帮助您完善和改进问题。
- 计划:在讨论达成一致意见后,就可以开始编码了。 但首先,我们需要将问题指定至里程碑和问题看板,以此确定工作流的优先级并进行组织。
- 编码:现在,一切安排就绪后,我们就可以编写代码了。
- 提交:对草稿满意后,我们便可将代码提交到具有版本控制的功能分支。 上一篇文章详细介绍了 GitLab 流程。
- 测试:使用 GitLab CI 运行我们的脚本,以构建并测试应用程序。
- 审查:在脚本能够正常运行且测试和构建成功后,我们便可以让代码接受审查并获得批准。
- 暂存:现在应该将代码部署到暂存环境,以检查一切是否按预期进行,或者我们是否仍需要进行调整。
- 生产:如果一切顺利,便可将代码部署到生产环境!
- 反馈:现在可以回顾之前的流程,并检查有哪些阶段的工作需要改进。
再次说明,流程本身不是新的(或者 GitLab 独有的),并且可以通过其他工具来实现。
我们来讨论一下其中的几个阶段以及这些阶段涉及的内容。 还提供文档。
问题和计划
GitLab 工作流的开始阶段以问题为中心,问题是指一个功能、一个错误或其他在语义上独立的工作。
问题有多个目的,例如:
- 管理:问题具有截止日期、指定人员、用时和估计等, 可以帮助跟踪问题解决情况。
- 行政管理:问题是里程碑的一部分,我们可以通过看板跟踪软件从一个版本过渡到另一个版本的进展。
- 开发:问题具有与之相关的讨论和提交。
在计划阶段,我们可以按问题的优先级、里程碑、看板将问题分组,并获得问题的概览。
开发在前一部分进行了讨论,只需按照您希望使用的任何 git 流程执行操作即可。 我们开发了新功能并将其合并到 master 分支后,接下来应怎样操作?
持续交付
持续交付是一种软件工程方式,团队通过这种方式在短周期内制作软件,从而确保软件可以随时实现可靠发布。 它的目的是更快速、更频繁地构建、测试和发布软件。 这种方式允许对生产中的应用程序进行更多增量更新,从而帮助缩减交付更改的成本、缩短时间,以及降低风险。 简单且可重复的部署过程对于持续交付非常重要。
GitLab 中的持续交付
在 GitLab 中,持续交付配置按仓库以 YAML 配置文件形式定义。
- 持续交付配置是一系列连续的阶段。
- 每个阶段都有一个或多个并行执行的脚本。
脚本定义了一个操作以及执行该操作需要满足的条件:
- 要执行的操作(运行 OS 命令、运行容器)?
- 何时运行脚本:
- 触发脚本的条件(特定分支)?
- 之前的阶段失败时是否运行?
- 手动运行还是自动运行?
- 脚本在什么环境中运行?
- 执行脚本后保存哪些工件(这些工件会从环境上传到 GitLab,以便轻松访问)?
环境是配置好的服务器或容器,可用于运行脚本。
运行程序用于在特定环境中执行脚本。 运行程序连接到 GitLab,并根据需要执行脚本。
运行程序可以部署在服务器上、容器上,甚至部署在本地机器上。
持续交付是如何实现的?
- 新提交推送到仓库中。
- GitLab 检查持续交付配置。
- 持续交付配置包含适用于所有情况的全部脚本,因此要过滤出应针对这一特定提交运行的一组脚本(例如提交到 master 分支仅会触发与 master 分支相关的操作)。 这组脚本称为管道。
- 管道是在目标环境中执行的,执行结果会保存并显示在 GitLab 中。
例如,下面是提交到 master 分支后执行的一个管道:
管道包含四个阶段,各阶段连续执行
- 加载阶段会将代码加载到服务器中
- 测试阶段会运行单元测试
- 封装阶段包含两个并行运行的脚本:
- 构建客户端
- 导出服务器代码(主要用于提供信息)
- 部署阶段会将构建的客户端移动到 Web 服务器目录中。
我们可以看到,每个脚本都成功运行,如果其中一个脚本运行失败,则默认不会运行后面的脚本(但我们可以更改此行为):
如果我们打开脚本,可以查看日志并确定脚本运行失败的原因:
Running with gitlab-runner 10.4.0 (857480b6)
on test runner (ab34a8c5)
Using Shell executor...
Running on gitlab-test...
Fetching changes...
Removing diff.xml
Removing full.xml
Removing index.html
Removing tests.html
HEAD is now at a5bf3e8 Merge branch '4-versiya-1-0' into 'master'
From http://gitlab.eduard.win/test/testProject
* [new branch] 5-versiya-1-1 -> origin/5-versiya-1-1
a5bf3e8..442a4db master -> origin/master
d28295a..42a10aa preprod -> origin/preprod
3ac4b21..7edf7f4 prod -> origin/prod
Checking out 442a4db1 as master...
Skipping Git submodules setup
$ csession ensemble "##class(isc.git.GitLab).loadDiff()"
[2018-03-06 13:58:19.188] Importing dir /home/gitlab-runner/builds/ab34a8c5/0/test/testProject/
[2018-03-06 13:58:19.188] Loading diff between a5bf3e8596d842c5cc3da7819409ed81e62c31e3 and 442a4db170aa58f2129e5889a4bb79261aa0cad0
[2018-03-06 13:58:19.192] Variable modified
var=$lb("MyApp/Info.cls")
Load started on 03/06/2018 13:58:19
Loading file /home/gitlab-runner/builds/ab34a8c5/0/test/testProject/MyApp/Info.cls as udl
Load finished successfully.
[2018-03-06 13:58:19.241] Variable items
var="MyApp.Info.cls"
var("MyApp.Info.cls")=""
Compilation started on 03/06/2018 13:58:19 with qualifiers 'cuk /checkuptodate=expandedonly'
Compiling class MyApp.Info
Compiling routine MyApp.Info.1
ERROR: MyApp.Info.cls(version+2) #1003: Expected space : '}' : Offset:14 [zversion+1^MyApp.Info.1]
TEXT: quit, "1.0" }
Detected 1 errors during compilation in 0.010s.
[2018-03-06 13:58:19.252] ERROR #5475: Error compiling routine: MyApp.Info.1. Errors: ERROR: MyApp.Info.cls(version+2) #1003: Expected space : '}' : Offset:14 [zversion+1^MyApp.Info.1]
> ERROR #5030: An error occurred while compiling class 'MyApp.Info'
ERROR: Job failed: exit status 1
编译错误导致脚本失败。
结论
- GitLab 支持软件开发的所有主要阶段。
- 持续交付可以帮助您自动执行软件构建、测试和部署任务。
链接
后续内容
在下一篇文章中,我们将:
- 安装 GitLab。
- 将它连接到多个安装了 InterSystems 产品的环境。
- 编写持续交付配置。
我们来探讨一下持续交付的运作方式。
首先,我们需要多个环境以及与之对应的分支。 代码进入此分支,并交付到目标环境:
环境 | 分支 | 交付 | 有权提交的角色 | 有权合并的角色 |
---|---|---|---|---|
测试 | master | 自动 | 开发者、所有者 | 开发者、所有者 |
preprod | 预生产 | 自动 | 无 | 所有者 |
prod | 生产 | 半自动(按下按钮进行交付) | 无 |
所有者 |
作为示例,我们将使用 GitLab 流程开发一个新功能,并使用 GitLab CD 进行交付。
- 在功能分支中开发功能。
- 对功能分支进行审查并将其合并到 master 分支中。
- 一段时间(合并了多个功能)后,将 master 分支合并到 preprod 分支中
- 一段时间(用户测试等)后,将 preprod 分支合并到 prod 分支中
具体如下图所示:
- 开发和测试
- 开发者将新功能的代码提交到单独的功能分支中
- 功能稳定后,开发者将功能分支合并到 master 分支中
- 来自 master 分支的代码被交付到测试环境,在其中进行加载和测试
- 交付到预生产环境
- 开发者创建从 master 分支到 preprod 分支的合并请求
- 仓库所有者在一段时间后批准合并请求
- 来自 preprod 分支的代码被交付到预生产环境
- 交付到生产环境
- 开发者创建从 preprod 分支到 prod 分支的合并请求
- 仓库所有者在一段时间后批准合并请求
- 仓库所有者按下“部署”按钮
- 来自 prod 分支的代码被交付到生产环境
也可以用示意图形式表示此流程: