当 Rocker 遇到 GitLab CI
楚新元 / 2021-09-05
Rocker 可以理解为一个提供 R 环境的 Docker,GitLab CI 则可以用来定义整个项目运行机制和流程。把这两个利器结合起来就可以做一些自动化的工作。比如我们可以设置每天按照 GitLab CI 设定的流程让 R 生成报表或者报告,甚至还可以顺便把生成的结果部署到网页上。最近笔者写了一个定时给好友发生日祝福邮件的项目1。
本例重点向读者展示 Rocker 和 Gitlab CI 是如何工作的,因此,这里笔者把任务简化处理:定义 GitLab CI 机制和流程,让 Rocker 给我们画一幅图,并把生成的图推送到项目所在仓库。
编写画图的 R 代码
cairo_pdf("graph.pdf")
MSG::msg("3.14")
dev.off()
这里为了代码简洁以及一般化考量,刻意增加了 MSG 包依赖。运行上述代码后,生成的图会自动导出到 graph.pdf
文件中。
定义 GitLab CI 机制和流程
定义GitLab CI 机制和流程主要是通过 .gitlab-ci.yml
文件实现2,如果是定时任务,还需要设置 Schedules。这里不涉及 Schedules,因为当本地向 GitLab 仓库推送更新后,会自动触发 GitLab CI 运行一次。因此,本次任务只涉及 .gitlab-ci.yml
文件。 .gitlab-ci.yml
文件中的代码如下:
image: rocker/verse:4.1.1
get_pdf_file:
stage: build
before_script:
- R -e "install.packages('MSG', dependencies = 'Imports')"
script:
- git remote set-url origin https://${CI_USERNAME}:${CI_TOKEN}@gitlab.com/${CI_PROJECT_PATH}.git
- git config --global user.name "${GITLAB_USER_NAME}"
- git config --global user.email "${GITLAB_USER_EMAIL}"
# 在 rocker 里生成 graph.pdf
- Rscript plot.R
after_script:
# push to origin branch
- git add --all *
- git commit -m '[skip ci] commit from CI runner'
- git push origin HEAD:$CI_COMMIT_REF_NAME
-
代码
image: rocker/verse:4.1.1
意思是执行本次任务需要调用 Rocker/verse 镜像,R 版本为 4.1.1,在这个环境里没有任何第三方 R 扩展包。 -
before_script 阶段是
plot.R
运行前的准备阶段,在 R 环境中安装依赖包 MSG。 -
script 阶段通过 Git 将整个项目克隆到 Rocker 里,然后运行行
plot.R
代码。 -
after_script 阶段将 Rocker 里新生成的文件推送回最初的 GitLab 仓库。
这里有几个参数需要在 Setting > CI/CD > Variables 下面设置,本例涉及到下面 3 个参数:
- CI_USERNAME
- CI_TOKEN
- CI_PROJECT_PATH
注意:CI_USERNAME 和 CI_TOKEN 的 value 值分别填用户名和登录密码;CI_PROJECT_PATH 的 value 值填用户名/镜像名。
现在一切准备就绪,我们只需要将本地文件推送到 GitLab 仓库里,GitLab 仓库有变化后会自动触发 GtiLab CI 执行画图任务,并将 graph.pdf
从 Rocker 推送回 GitLab 仓库,所有任务完成后,我们只需要把 GitLab 仓库的文件 Pull 回本地即可。
为了方便读者体验,我把本文涉及的所有代码和文件全部放在了 updown 仓库,欢迎体验。