GitLab CI with SBT/Maven build tools In Docker

Gitlab的CI工具比较好用,通常我们会把代码的push或者Tag标签的生成作为触发事件,启动代码的编译、测试和部署,这些都离不开Build tool的参与,而Gitlab-runner可以使用多种类型的Runner,或者将Build tools安装在本机,直接在Shell里边执行,或者采用Docker/Kubernetes类似的容器技术,配合Build tools的镜像执行编译操作,前者的问题在于每台机器都要进行编译工具的安装配置,扩容相对繁琐,每增加一个Runner都要自己在新的机器上进行一批操作,后者的好处显而易见只要是启动了Docker daemon的机器,都可以自动的pull对应的Build tool image来进行编译,减少了很多重复操作。

在Docker镜像里边使用Sbt等编译工具需要考虑到每次编译所下载的依赖缓存到哪里,默认情况会放到对应的镜像运行时所对应的Container里边的目录,一旦镜像升级或者运行时的container被删除,所有的缓存的依赖在下次编译的时候都要重新下载,虽然可以通过Volumn挂载的方式将缓存产生在宿主机的某些目录,不过用这种方案依然避免不了在每个宿主机器上进行额外的缓存目录的配置,本文主要以SBT/Maven为例,说明如何在Gitlab CI工具中使用Docker类型的Runner来进行代码的编译,并且依赖GItlab CI的Cache功能来缓存编译时下载的各种依赖,加速重复编译的速度。

关于如何构建SBT/Maven的镜像就不多说了,Docker hub上边有很多成熟的例子,基于Alpine Linux构造出来尽可能小的镜像即可。如何让每次Sbt镜像进行编译的时候能够重复的使用缓存,不需要重新下载依赖才是关键。

  1. SBT目录结构
ls ~/.sbt
0.13  1.0  boot  gpg  launchers  preloaded  repositories .credentials
ls .sbt/1.0 
build.sbt  plugins  server  staging  target  templates  zinc

其中0.13和1.0对应不同大版本号的sbt.global.base目录,因为二者差别较大,boot对应sbt.boot.directory,repositories和.credentials是我们自己定义的仓库列表和所授权的用户名密码。
sbt.global.base目录里边的内容不是那么纯粹,build.sbt以及plugins目录里边的*.sbt文件是我们预先配置好的插件和授权验证等信息,也包含了一些插件在update过程中所下载的依赖,因此这个目录的缓存是比较麻烦的,只能缓存其中一部分

  1. SBT缓存哪些数据
  • sbt 启动自身需要的依赖和插件等数据,比如我们每次修改buid.properties换一个更新的sbt版本号时可能就会触发的get sbt xxx version的提示
  • ivy cache and local,这部分是我们所编译的工程的依赖,默认路径是$HOME/.ivy2/{cache, local}
  • coursier cache, 如果我们使用了coursier来并行的解决依赖,也需要缓存这个插件的数据,默认位置是$HOME/.coursier/cache
  1. SBT项目.gitlab-ci.yml
image: "xxxxx/sbt:1.1.0-alpine"

variables:
  SBT_OPTS: "-Dsbt.global.base=/{absolute path}/sbt-cache/base -Dsbt.boot.directory=sbt-cache/boot -Dsbt.ivy.home=sbt-cache/ivy -Xmx3096m  -Dsbt.override.build.repos=true -Dsbt.repository.config=/root/.sbt/repositories" # 修改默认的路径,统一将sbt需要的东西都保存到某个sbt-cache目录,这个目录在下边的gitlab cache部分会定义
  # 注意sbt.global.base的路径只能是绝对路径,我们只能写具体的gitlab runner里边的build路径
  # 注意sbt.repository.config后边的路径也必须是绝对路径,如果用环境变量$HOME或者~替代,则会出现无法使用正确的仓库的问题
  COURSIER_CACHE: sbt-cache/coursier # 当使用Coursier时需要这一行,定义Coursier Cache
  SBT_CREDENTIALS: "/root/.sbt/.credentials" # 此处也是必须使用绝对路径,用$HOME环境变量无法找到正确的文件路径,这个环境变量主要在upgrade sbt的时候使用,如果不指定是无法使用私服去更新sbt的,此时没有开始加载basedir/credentials.sbt 这个文件,因此会报授权错误

cache:
  #key: "$CI_BUILD_REF_NAME" # 每个分支一个缓存,还有其他的常量定义Tag等缓存的区分,默认是整个工程所有的Job都使用同一个缓存
  # 对于编译工具来说,不需要每个分支额外缓存一份,注释掉这行即可
  untracked: true
  paths:  #以下出现的路径都会在编译的时候由gitlab ci的runner负责创建和管理,只要相对路径即可,对应上边环境变量里边所设置的路径
    - "sbt-cache/ivy/cache"
    - "sbt-cache/ivy/local"
    - "sbt-cache/boot"
    - "sbt-cache/base"
    - "sbt-cache/coursier" #only needed if you use coursier

before_script:
  - which sbt
  - mkdir -p sbt-cache/base/plugins 
  # 接下来比较奇怪,因为sbt的这两个路径里边不只有缓存的东西,还有一些我们预先配置好的脚本,比如plugin.sbt, build.sbt等,
  # 一般这些内容我们会直接打包到镜像里边,而缓存只有在第一次运行之后才会创建,如果不拷贝过去,因为上边的SBT_OPTS里边定义的路径都是缓存里边的路径,
  # 会导致我们配置的repositories和credentials不生效,如果不用上边的环境变量来修改,会导致有些内容不会被缓存,每次都会get sbt到临时的docker container中,重复下载
  - cp ~/.sbt/0.13/build.sbt sbt-cache/base/ # 根据情况0.13要改成1.0
  - cp ~/.sbt/0.13/plugins/*.sbt sbt-cache/base/plugins/ # 同上

stages:
  - build
  - deploy

compile:
  stage: build
  script:
    - sbt compile
  allow_failure: true
  tags:
    - sbt

最终在执行完成后我们可以看到如下日志:

......
HEAD is now at ddb6c5c  modified:   .gitlab-ci.yml
Checking out ddb6c5c4 as docker_env...
Skipping Git submodules setup
Checking cache for default...
Successfully extracted cache
......
Creating cache default...
sbt-cache/ivy/cache: found 528 matching files      
WARNING: sbt-cache/ivy/local: no matching files    
sbt-cache/boot: found 66 matching files            
sbt-cache/base: found 174 matching files           
sbt-cache/coursier: found 9544 matching files      
untracked: found 17215 files                       
Created cache
Job succeeded

能够看到缓存在各个目录的文件的情况

  1. Maven目录结构
    Maven相对来说要简单很多,我们只要缓存.m2/repository就可以了
  2. Maven工程的.gitlab-ci.yml
image: "xxxxx/tools/maven:3.3.9-alpine"

variables:
  MAVEN_OPTS: "-Dmaven.repo.local=.m2/repository"

cache:
  untracked: true
  paths:
    - .m2/repository

......

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容