随着系统变得日益复杂和互联,软件可靠性和完整性的重要性持续升级。尽管遵循了既定的工程最佳实践,高完整性系统的开发仍然是一项对技术要求极高且资金投入巨大的工作。鉴于审查、分析、测试和回归工作涉及的大量精力,工程师们一直在寻找减少浪费并提高整体软件质量的方法。最新的趋势之一是推动持续集成和持续部署 (CI/CD) 解决方案。
CI/CD 实践改变了软件开发,实现了高质量软件的快速和一致交付。但是,该技术的快速发展以及可用工具的数量,可能会使创建稳健的 CI/CD 解决方案变得极具挑战性。本文介绍了一种使用 GitLab® Runner、Docker® 和 CI/CD Automation for Simulink Check™ 实现 CI/CD 管道的综合方法。
1️⃣ CI/CD 对安全关键型软件开发和认证的重要性
CI/CD 是现代软件开发中的重要实践,对于医疗、汽车和航空航天工业等领域的安全关键型系统尤为如此。部署高效的 CI/CD 解决方案有助于提高质量和可靠性,更快速地检测和解决问题,并确保持续符合监管标准。由于需求的单一变更可能会引发一连串的回归工作,因此建立强大的 CI/CD 流程对于以经济高效的方式管理任何安全关键型软件开发项目至关重要。
本文将介绍以下步骤,以配置本机建模环境之外的工具,以便与 MATLAB® 和 Simulink® 工具套件集成:
Simulink Check 过程顾问
GitLab 和 GitLab Runners
- 配置 GitLab CI/CD 管道
Docker
- 创建 Docker 镜像
- 构建参量
- 构建镜像并启动容器
- 运行 GitLab Runner 以监听作业
- 测试 Docker 镜像并排除故障
2️⃣ Simulink Check 过程顾问
作为 CI/CD Automation for Simulink Check 的一部分,过程顾问是一个强大的工具,用于在 MATLAB 环境中开发基于模型的设计管道,然后可以通过提供的模板 .yml 文件在外部环境中使用该管道。对于旨在在 MATLAB 环境中配置流程管道的模型开发人员,请点击“阅读原文”参阅以下文档:
设置过程模型:自定义过程模型 https://ww2.mathworks.cn/help/slcheck/define-custom-process.html
自动化模型验证和确认:使用流程顾问自动执行和运行任务 https://ww2.mathworks.cn/help/slcheck/padv/ug/automate-and-run-tasks-with-process-advisor.html
使用过程顾问的最佳实践:过程模型编写的最佳实践 https://ww2.mathworks.cn/help/slcheck/padv/ug/best-practices-for-process-model-authoring.html
3️⃣ GitLab 和 GitLab Runners
此时,您已准备好将过程模型引入 GitLab 中的 CI/CD 管道。为了确保 Simulink 过程模型的更新自动反映在 GitLab 管道中,我们使用了一种独特的方法:我们不将过程模型重新创建为静态 .yml 文件,而是使用一个 .yml 文件来生成另一个包含过程模型中当前任务的 .yml 文件。请点击“阅读原文”参阅附录 A 中的示例管道配置文件 (gitlab-ci.yml)。请注意,这里有两个阶段:
stages: - SimulinkPipelineGeneration - SimulinkPipelineExecution
第一个阶段为第二个阶段生成管道。
此时,考虑如何许可管道中使用的建模和验证工具非常重要。一种方法是使用批处理令牌。要使用批处理令牌,您必须从 Batch Licensing Pilot 申请一个,并将其包含在您的 .yml 文件的 variables 部分中。
variables: MLM_LICENSE_TOKEN: ""
并非所有产品都支持批处理令牌。在这种情况下,您可能需要使用传统的许可证文件 (.lic)。您可以点击“阅读原文”找到有关批处理令牌的更多信息:MATLAB 批量许可令牌(https://github.com/mathworks-ref-arch/matlab-dockerfile/blob/main/alternates/non-interactive/MATLAB-BATCH.md#matlab-batch-licensing-token)。请注意,最佳实践是避免将令牌(和其他凭据类型信息)硬编码到您的 .yml 或 Dockerfile 中。更安全的方法是考虑使用环境变量构建您的 Docker 镜像。
配置 GitLab CI/CD 管道
配置您的 GitLab 项目以管理作业非常简单。您首先需要确保 GitLab 知道在哪里可以找到您的 .yml 文件。在 Settings > CI/CD > General pipelines > CI/CD configuration file 下,提供项目 .yml 文件的路径,最好命名为 “.gitlab-ic.yml”(图 1)。

图 1. GitLab CI/CD 管道配置设置。
接下来,您需要在 GitLab 中创建一个新的 runner。这样做将提供一个 gitlab-runner-token,您稍后将使用它来将 Docker 容器注册到您的 GitLab runner 实例(图 2)。

图 2. GitLab runners 设置。
在 Settings > CI/CD > Runners > New project runner 下,提供一个标签并点击 Create Runner(图 3)。

图 3. 在 GitLab 中创建新的 runner。
创建 runner 后,复制并保存 runner 身份验证令牌(图 4)。

图 4. Runner 身份验证令牌。千万不要弄丢这个!
4️⃣ Docker
创建 Docker 镜像
这可能是该过程中最困难的部分,因为您需要确保 Docker 镜像不仅安装了所有工具依赖项,而且还获得了使用这些工具的许可。同样重要的是要注意,您的 Docker 镜像可以是众多操作系统发行版中的一种。本示例将使用 Ubuntu 22.04。
首先安装运行 Simulink 过程模型和 GitLab runners 所需的所有工具。在您的 Dockerfile 中,拉取基础 MATLAB 镜像:
FROM mathworks/matlab-deps:${MATLAB_DOCKER_RELEASE}
随后,您将直接开始安装所需的一些基本依赖项。请注意,构建变量将在后面讨论。有关完整的安装细目,请点击“阅读原文”参阅附录 B 中的示例 Dockerfile。Dockerfile 首先安装 MPM 的依赖项,然后将使用 MPM 安装所需的 MATLAB 和 Simulink 产品(Simulink Code Inspector™ 除外)。接下来,安装 matlab-proxy 的依赖项。安装完成后,使用 MPM 安装所需的工具并配置您的许可方法。请注意,您还需要在 Docker 镜像上安装 gitlab-runner 并使用您之前保存的 gitlab-runner-token 对其进行注册。下面的代码片段显示了如何使用理想的配置选项进行安装和注册:
RUN curl -L "https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh" | sudo bash && \ sudo apt-get install --no-install-recommends --yes \ gitlab-runner && \ sudo apt-get clean && sudo apt-get autoremove && \ gitlab-runner start && \ sudo gitlab-runner register --non-interactive \ --url "" \ --token "${GITLAB_TOKEN}" \ --docker-image ${IMAGE_NAME} \ --executor "shell"
如 Dockerfile 所示,MPM 可以安装除 Simulink Code Inspector 之外的所有必需 MATLAB 和 Simulink 工具。对于 Simulink Code Inspector,您需要从 MathWorks 网站下载 .iso 文件并从中安装。有关更多信息,请参阅 mpm install 文档。
现在产品已安装,您需要配置许可方法。目前有三种可用的许可方法:
RUN wget -q https://ssd.mathworks.com/supportfiles/ci/matlab-batch/v1/glnxa64/matlab-batch \ && sudo mv matlab-batch /usr/local/bin \ && sudo chmod +x /usr/local/bin/matlab-batch
--build-arg LICENSE_SERVER=27000@MyServerName
或者,您可以直接在 Dockerfile 中指定许可证服务器:
ENV MLM_LICENSE_FILE=27000@flexlm-server-name
COPY ${PATH_TO_LICENSE} /opt/matlab/licenses/
ADD ${PATH_TO_LICENSE} /opt/matlab/licenses/
关于已安装依赖项的最后一点:某些报告需要显示设备来捕获模型的屏幕截图。Xvfb 为诸如 padv.builtin.task.GenerateSDDReport、padv.builtin.task.GenerateSimulinkWebView 和 padv.builtin.task.GenerateModelComparison 之类的任务提供虚拟显示。这应该作为 MPM 依赖项的一部分进行安装。请确保 MPM 由将运行该管道的用户安装。
构建参量
在这个例子中,Dockerfile 配置为接受多个构建参量。构建参量对于维护一个可用于构建多个镜像的 Dockerfile 非常有价值,或者允许用户传入可能会随时间变化或不希望硬编码到 Dockerfile 本身中的构建信息。
此 Dockerfile 包含以下构建参量 (--build-arg):
在 Dockerfile 的开头,您可以为每个参量指定默认值,以防构建命令未提供值:
ARG MATLAB_DOCKER_RELEASE=r2023b-ubuntu22.04 ARG MATLAB_VERSION=r2023b ARG MATLAB_BATCH_TOKEN="<USER>|TOKEN_ML|<TOKEN>" ARG GITLAB_TOKEN=<TOKEN> ARG IMAGE_NAME=matlab_image ARG PATH_TO_LICENSE=<PATH_TO_LICENSE>
在 Dockerfile 中的 FROM 语句之后,您必须声明将使用的变量:
FROM mathworks/matlab-deps:${MATLAB_DOCKER_RELEASE}
ARG MATLAB_VERSIONARG MATLAB_BATCH_TOKENARG GITLAB_TOKENARG IMAGE_NAMEARG PATH_TO_LICENSE
请注意上面的代码片段中,MATLAB_DOCKER_RELEASE 的值是通过 ${} 语法访问的。
构建镜像并启动容器
现在您的 Dockerfile 已准备就绪,您可以从 Docker 终端构建您的第一个容器:
> docker build -t <image-name> -f <dockerfile-name>
如果您的 Docker 文件使用构建参量,那么您的构建命令可能看起来更像这样:> docker build --build-arg PATH_TO_LICENSE=<path-to-license> --build-arg GITLAB_TOKEN=<gitlab-runner-token> --build-arg MATLAB_BATCH_TOKEN="<USER>|TOKEN_ML|<TOKEN>" -t <image-name> -f <dockerfile-name>
容器构建完成后,您可以使用 UI 或终端从 Docker 运行它:
> docker run --name <container_name> -v <optional_volume> <image_name>:latest
您的 Dockerfile 已经将您的镜像注册为 gitlab-runner。要确认这一点,请查看 Docker 中的文件 /etc/gitlab-runner/config.toml 并验证是否注册了正确的 runner(图 5)。

图 5. 验证 GitLab runner 是否已成功注册到 Docker 镜像。
如果 runner 注册不正确或需要更改或重新启动,请在 Docker 镜像的终端中使用以下命令取消注册 runner,然后恢复正确的 runner:
> sudo gitlab-runner unregister --token "" > sudo gitlab-runner register --non-interactive --url "" --token "" --executor "shell"
运行 GitLab Runner 以监听作业
现在容器正在运行并已注册为 GitLab runner,您可以运行 gitlab-runner 并开始监听作业(图 6)。从容器的终端,使用以下命令启动 runner:

图 6. GitLab 管道执行情况和状态。
有许多方法可以启动您的管道,包括计划构建、手动或按需构建,以及基于对 GitLab 仓库的新提交的构建(图 7)。

图 7.GitLab 管道详细状态页面。
计划构建: 在 GitLab 中,使用 Build > Pipeline schedule 来安排管道何时运行。
提交时构建:默认情况下,每次推送到仓库时,GitLab 都会运行管道。要控制如何触发构建,您需要修改 .yml 文件或向提交消息添加特定标签。有关更多信息,请点击“阅读原文”参阅文档:控制作业如何运行(https://docs.gitlab.com/ci/jobs/job_control/)。
手动构建: 在 GitLab 中,使用 Settings > CI/CD > Run pipeline 来触发手动构建。Settings > CI/CD > Pipeline trigger tokens 包含有关如何使用 curl 从终端触发构建的信息。
一旦管道执行完毕,结果可以从管道中的最后一个作业 —— Collect_Artifacts 中查看和下载(图 8)。

图 8. GitLab 管道输出终端和结果。
测试和排除 Docker 镜像故障
在设置和配置 Docker 镜像时,能够沿途测试非常重要。以下是您可以在 Docker 容器的终端中执行的一些有用步骤,以确保一切按预期工作:
1. 验证从容器终端安装的 MATLAB:
$ matlab-batch "disp('Hello, World.')"
2. 要生成某些报告 (SDD),MATLAB 需要显示设备。为此,您可以使用 Xvfb。要测试 Xvfb:
$ sudo xvfb-run -e /dev/stdout -a matlab-batch "disp('Hello, World.')"
3. 手动运行 MATLAB 管道:
a. 克隆仓库(您可能会被提示输入凭据 — 2FA 需要访问令牌,可以在 GitLab 左侧边栏选择您的头像找到:选择 Edit profile >Access Tokens > Add new token)
$ sudo
git clone $ sudo git clone https://:@
b. 更改目录至 MATLAB 项目目录:
c. 运行管道的第一阶段:
$ sudo -E matlab-batch -logfile "MATLAB_LOG_FILE" -nodesktop "cp = openProject(pwd); padv.pipeline.generatePipeline( padv.pipeline.GitLabOptions(PipelineArchitecture = padv.pipeline.Architecture.SerialStagesGroupPerTask, Tags = 'docker-matlab', GeneratedYMLFileName = 'simulink_pipeline.yml', GeneratedPipelineDirectory = fullfile('derived','pipeline'), MatlabLaunchCmd = 'xvfb -a matlab-batch', AddBatchStartupOption = false, EnableArtifactCollection = 'always'));"
d. 验证 simulink_pipeline.yml 文件的生成:
结束语
CI/CD 的集成对于维持高质量、可靠性和合规性标准至关重要。CI/CD 实践简化了开发过程,实现了更新的快速和一致交付,同时确保所有更改符合严格的认证要求。这种方法不仅提高了生产力,还显著降低了错误和违规的风险,这在认证环境中至关重要。
通过应用本文讨论的工具和实践,组织应该能够使用 Docker 和 GitLab Runner 建立一个稳健的环境,以创建一个高效且节省成本的 CI/CD 管道。该管道应促进简化、可靠且合规的开发生命周期,并最终有助于以更大的信心和效率交付高质量的可认证系统。
*本文采用了机器翻译
| 关于作者
Dalton L'Heureux 是 MathWorks 的高级顾问,负责支持从事安全关键型和高完整性系统工作的工程师。他的重点包括帮助团队在 DO-178C 认证等应用中应用系统工程、验证与确认以及代码生成工具。
在加入 MathWorks 之前,Dalton 是 Rockwell Collins 的系统工程师,在那里他成为了规范建模和测试用例生成方面的主题专家。他的工作为包括波音 777X 和庞巴迪 C 系列在内的飞机的飞行软件的经济高效测试做出了贡献。
Dalton 拥有安柏瑞德航空航天大学的航空航天工程学士学位和无人与自主系统工程硕士学位。在他的各个职位中,基于模型的设计和 MATLAB 一直是他开发和验证复杂系统方法中的贯穿主题。
关注 MATLAB 公众号 ↓↓↓