我想使用Gitlab编译一篇Latex文章,正如在这个答案在tex.stackexchange上中解释的那样(类似的pdf生成示例显示在工件的gitlab文档中)。我使用了杂志编辑给我的一个特殊的胶乳模板。我的Latex文章包含了用R统计软件制作的数字。R和Latex是两个具有大量依赖项的大型软件安装,因此我决定使用两个单独的容器进行构建,一个用于使用R进行统计分析和可视化,另一个用于将Latex文档编译成pdf。
以下是.gitlab-ci.yml的内容
knit_rnw_to_tex:
image: rocker/verse:4.0.0
script:
- Rscript -e "knitr::knit('article.Rnw')"
artifacts:
paths:
- figure/
compile_pdf:
image: aergus/latex
script:
- ls figure
- latexmk -pdf -bibtex -use-make article.tex
artifacts:
paths:
- article.pdf在R "rocker“容器中执行的knit_rnw_to_tex作业是成功的,我可以从gitlab”作业“页面下载图形工件。第二个作业compile_pdf的问题是,ls figure向我显示一个空文件夹,而Latex文章编译由于缺少数字而失败。
apt install latexmk的安装由于未知的原因而失败。也许是因为它有上百个依赖项,这对gitlab来说是很重要的吗?发布于 2021-04-19 10:36:22
谢谢你的评论,因为我想确定,你是如何做到的。示例也会有帮助,但我现在是通用的(使用docker)。
要运行多个容器,需要一个The Docker executor)
引用其上的文档:
当与GitLab CI一起使用时,Docker执行器连接到Docker引擎,并使用在
.gitlab-ci.yml中和config.toml中设置的预定义映像在单独的孤立容器中运行每个构建。
工作流程
Docker执行者将作业划分为多个步骤:
您的config.toml可能如下所示:
[runners.docker]
image = "rocker/verse:4.0.0"
builds_dir = /home/builds/rocker
[[runners.docker.services]]
name = "aergus/latex"
alias = "latex"从上述链接文件中:
image关键字
image关键字是存在于本地Docker引擎中的Docker图像的名称(列出所有带有码头图像的图像)或在docker中可以找到的任何图像的名称。有关图像和码头集线器的更多信息,请阅读码头基础文档。
简而言之,对于映像,我们指的是Docker映像,它将用于创建运行构建的容器。
如果您不指定namespace,那么Docker就意味着包含所有官方图像的库。这就是为什么您将多次看到.gitlab-ci.yml和config.toml中省略的库部分。例如,您可以定义像image: ruby:2.6这样的图像,这是图像的快捷方式:library/ruby:2.6。
然后,对于每个Docker映像都有标记,表示图像的版本。它们是在图像名称之后用冒号(:)定义的。例如,对于Ruby,您可以在码头枢纽上看到受支持的标记。如果不指定标记(如image: ruby),则暗示有最新的标记。
您选择通过image指令运行构建的image必须在其操作系统PATH中有一个工作外壳。支持的shell是sh、bash和pwsh (自13.9以来)用于Linux,PowerShell用于Windows。GitLab运行程序不能使用底层OS系统调用(如exec)执行命令。
services关键字
services关键字仅定义在生成期间运行的另一个Docker映像,该映像链接到图像关键字定义的Docker映像。这允许您在构建时访问服务映像。
service映像可以运行任何应用程序,但是最常见的用例是运行数据库容器,例如mysql。每次构建项目时,使用现有映像并将其作为附加容器运行比安装mysql更容易和更快。
您可以在CI服务示例的相关文档中看到一些广泛使用的服务示例。
如果需要,您可以为每个服务分配一个alias。
至于你的问题:
应该可以使用工件在作业之间传递数据,根据这个答案和这个解释很好的论坛帖子,但是它们只使用一个容器来处理不同的作业。在我的案子里不管用。可能是因为我用了两个不同的容器?
构建和缓存存储(来自文档)
默认情况下,Docker将所有构建都存储在/builds/<namespace>/<project-name>中,所有缓存都存储在/cache (容器中)中。您可以通过在/builds中的[[runners]]部分下定义builds_dir和cache_dir选项来覆盖[[runners]]和cache_dir目录。这将修改存储在容器中的数据的位置。
如果修改/cache存储路径,还需要通过在volumes = ["/my/cache/"]中config.toml中的[runners.docker]部分下定义该目录来确保将其标记为持久目录。
builds_dir ->绝对路径。例如,本地、Docker或SSH。正如您可能已经注意到的,我已经将您的toml文件中的toml定制为/home/builds/rocker,请将其调整为您自己的路径。
如何将工件从一个作业传递到另一个作业?
您可以使用build_dir指令。第二个选项是使用作业工件API。
我应该使用docs.gitlab.com /缓存中解释的缓存吗?
是的,您应该使用cache存储项目依赖项。其优点是,您只从internet获取一次依赖项,随后的运行速度要快得多,因为它们可以跳过这一步。Artifacts用于在构建阶段之间共享结果。
我希望现在更清楚了,我已经把你们引向了正确的方向。
发布于 2021-04-25 22:23:31
这两种不同的图像并不是造成问题的原因。工件保存在一个映像中(这似乎有效),然后在另一个映像中恢复。因此,我建议不要建造(和维持)一个单一的形象,因为这在这里不应该是必要的。
您出现问题的原因是您缺少构建阶段,这会让gitlab了解作业之间的依赖关系。因此,我建议您在您的.gitlab-ci.yml中指定阶段以及它们各自的工作。
stages:
- do_stats
- do_compile_pdf
knit_rnw_to_tex:
stage: do_stats
image: rocker/verse:4.0.0
script:
- Rscript -e "knitr::knit('article.Rnw')"
artifacts:
paths:
- figure/
compile_pdf:
stage: do_compile_pdf
image: aergus/latex
script:
- ls figure
- latexmk -pdf -bibtex -use-make article.tex
artifacts:
paths:
- article.pdf上下文:
默认情况下,如果添加相应的规范,则以前构建阶段的所有工件都可以在以后的阶段中使用。
如果没有指定任何阶段,gitlab将把所有作业放入默认的test阶段,并并行执行它们,假设它们是独立的,并且不需要彼此的工件。它仍然会存储工件,但不会在作业之间提供它们。这大概就是导致你的问题的原因。
至于cache:工件是在构建阶段之间传递文件的方式。缓存是很好的,缓存。实际上,它们被用于诸如外部包这样的东西,以避免不得不多次下载它们,请看这里。在有多个不同跑步者的情况下,缓存有些不可预测。它们仅用于性能原因,并且使用cache而不是使用工件系统在作业之间传递文件是一种巨大的反模式。
编辑:我不知道您的knitr设置是什么,但是如果您从article.Rnw生成一个article.tex,那么您可能也需要将它添加到您的artifacts中。
此外,services还用于测试数据库的MySQL服务器,或者用于构建坞映像的dind (坞中对接)守护进程。在你的情况下这不应该是必要的。类似地,您不应该需要从默认值中更改任何运行程序配置(在它们各自的config.toml中)。
Edit2:我添加了一个MWE 这里,它适用于我的gitlab设置。
https://stackoverflow.com/questions/67111613
复制相似问题