问题描述
背景
我有一个用于我一直在开发的 C++ 库的 CI 管道。到目前为止,我可以将这个库分发到 Linux 和 Windows 系统。由于我使用 GitLab 来构建、测试和打包我的库,我希望我的 Windows 构建运行得更快,但我不知道如何做到这一点。
目前,我在 Windows 构建中使用以下脚本:
.windows_template:
tags:
- windows
before_script:
- choco install cmake.install -y --installargs '"ADD_CMAKE_TO_PATH=System"'
- choco install python --pre -y
- choco install git -y
- $env:ChocolateyInstall = Convert-Path "$((Get-Command choco).Path)\..\.."; Import-Module "$env:ChocolateyInstall\helpers\chocolateyProfile.psm1"; refreshenv
- python -m pip install --upgrade pip
- pip install conan monotonic
问题
任何使用上述脚本的构建都可能需要 10 分钟;更糟糕的是:我有两个阶段,每个阶段都花费相同的时间。这意味着我的整个 CI 管道将需要 20 分钟才能完成,因为 Windows 构建速度缓慢。
理想的解决方案
我的 before_script
中的所有内容都可以缓存或存储为图像。我只需要一些有关如何正确执行的提示。
其他信息
我使用以下工具进行构建:
- CMake:支持我的构建过程;
- python3:测试和构建包;
- Conan(需要 python3):支持创建具有多种功能的包,以及分发它们;
-
Git:在 CMake 配置步骤中下载 Googletest这已经在说明书中提供了 - 我可能只是在我的before_script
中删除了这个额外的安装步骤; - Googletest(需要 python3):测试库;
-
Visual Studio DEV 工具:编译库这已经在说明书中了。
解决方法
像这样安装包(无论是操作系统包,通过 apt-get install... 还是 pip 或其他任何东西)通常都违反 CI/CD 作业的最佳实践,因为每个运行的作业都必须做同样的事情,正如您已经看到的,随着您运行更多管道而花费大量时间。
一些替代方法是搜索包含您需要的所有内容的现有映像(可能但不太可能具有更多依赖项),将您的工作拆分为可能由仅具有一两个依赖项的映像解决的部分,或创建要在您的工作中使用的自定义 docker 图像。几周前我在这里用一个例子回答了一个类似的问题:"Unable to locate package git" when running GitLab CI/CD pipeline
但这里有一个使用 Windows 的 Dockerfile 示例:
# Dockerfile
FROM mcr.microsoft.com/windows
RUN ./install_chocolatey.sh
RUN choco install cmake.install -y --installargs '"ADD_CMAKE_TO_PATH=System"'
RUN choco install python --pre -y
RUN choco install git -y
...
FROM
行表示我们的新图像扩展了 mcr.microsoft.com/windows
基本图像。您可以扩展您有权访问的任何图像,即使它已经扩展了另一个图像(事实上,这就是大多数图像的工作方式:它们从一些小的东西开始,比如基本的操作系统安装,然后添加该包所需的东西。例如 PHP在 Ubuntu 映像上启动,然后安装必要的 PHP 包)。
第一行 RUN
只是一个例子。我不是 Windows 用户,也没有安装 Chocolatey 的经验,但是您可以在这里执行您通常在本地安装它时所做的任何事情。其余的用于安装您需要的任何其他内容。
然后运行
docker build /path/to/dockerfile-dir -t mygroup/mytag:version
您提供的路径必须是包含 Dockerfile 的目录,而不是 Dockerfile 本身。 -t
标志在映像构建后设置映像的标记(尽管您可以使用单独的命令执行此操作,docker tag
也可以)。
接下来,您必须登录您使用的任何注册表(Docker Hub (https://docs.docker.com/docker-hub/repos/)、Gitlab Container Registry (https://docs.gitlab.com/ee/user/packages/container_registry/)、您的雇主可能支持的私有注册表,或任何其他选择。
docker login my.docker.hub.com
现在您可以将映像推送到注册表:
docker push my.docker.hub.com/mygroup/mytag:version
您必须查看文档中有关告诉您的 Gitlab 运行程序或管道如何使用注册表进行身份验证的信息(除非它在 Docker Hub 上公开或您使用 Gitlab 容器注册表)https://docs.gitlab.com/ee/ci/docker/using_docker_images.html#define-an-image-from-a-private-container-registry
完成所有操作后,您就可以在 CI 作业中使用您的新映像了,我们放入映像中的所有内容都可以使用了:
.windows_template:
image: my.docker.hub.com/mygroup/mytag:version
tags:
- windows
...