如何为 GitLab CI 运行器启用 Maven 工件缓存?

问题描述 投票:0回答:8

我们使用 GitLab CI 和共享运行器来进行持续集成。对于每个构建,运行程序都会下载大量 Maven 工件。

有没有办法配置 GitLab CI 来缓存这些工件,以便我们可以通过防止一遍又一遍地下载相同的工件来加快构建过程?

maven gitlab-ci gitlab-ci-runner
8个回答
126
投票

Gitlab CI 允许您定义某些路径,其中包含应在每个作业或构建的基础上在构建之间缓存的数据(有关更多详细信息,请参阅此处)。结合 khmarbaise 的建议,这可以用于缓存多个构建之间的依赖关系。

缓存构建中所有作业依赖项的示例:

cache:
  paths:
    - .m2/repository

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

maven_job:
  script:
    - mvn clean install

18
投票

根据 GitLab 问题跟踪器上的对话,我设法更改 Maven 本地存储库路径并将其放入

./.m2/repository/
目录中,然后我们将通过将此全局块添加到 CI 配置来在运行之间保持不变:

cache:
  paths:
    - ./.m2/repository
  # keep cache across branch
  key: "$CI_BUILD_REF_NAME"

不幸的是,根据this StackOverflow回答,maven本地存储库路径只能在每次运行时使用

-Dmaven.repo.local
或通过编辑
settings.xml
来设置,这是在gitlab-ci配置脚本中完成的一项繁琐的任务。一个选项是使用默认 Maven 选项设置一个变量并将其传递给每次运行。

此外,至关重要的是本地 Maven 存储库是当前目录的子目录。由于某种原因,将其放入

/cache
/builds
对我来说不起作用,尽管 GitLab 的某人声称它应该起作用。

Maven + Java 的工作

gitlab-ci.yml
配置文件示例:

image: maven:3-jdk-8

variables:
  MAVEN_OPTS: "-Djava.awt.headless=true -Dmaven.repo.local=./.m2/repository"
  MAVEN_CLI_OPTS: "--batch-mode --errors --fail-at-end --show-version"

cache:
  paths:
    - ./.m2/repository
  # keep cache across branch
  key: "$CI_BUILD_REF_NAME"

stages:
  - build
  - test
  - deploy

build-job:
  stage: build
  script:
    - "mvn clean compile $MAVEN_CLI_OPTS"
  artifacts:
    paths:
      - target/

unittest-job:
  stage: test
  dependencies:
    - build-job
  script:
    - "mvn package $MAVEN_CLI_OPTS"
  artifacts:
    paths:
      - target/

integrationtest-job:
  stage: test
  dependencies:
    - build-job
  script:
    - "mvn verify $MAVEN_CLI_OPTS"
  artifacts:
    paths:
      - target/

deploy-job:
  stage: deploy
  artifacts:
    paths:
      - "target/*.jar"

11
投票

接受的答案并不适合我。

正如 zlobster 提到的,GitLab 的人员有这个令人惊叹的 存储库,您可以在其中找到用于 Maven 项目的

.gitlab-ci.yml
文件的正确示例。

基本上,您需要的是这些行:

cache:
  paths:
    - .m2/repository

请记住,如果您决定为某个作业添加本地缓存,则上面添加的全局缓存将被替换。更多相关内容这里


7
投票

您可以将缓存文件夹添加到 gitlab-ci 运行程序配置中并将其传递给 maven。

/etc/gitlab-runner/config.toml

[[runners]]
...
  [runners.docker]
  ...
   volumes = ["/cache", "/.m2"]
  ...

.gitlab-ci.yml

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

build:
  script:
    - mvn package

6
投票

如果您使用kubernetes作为gitlab-runner的执行器,您还可以使用maven缓存。我选择使用 k8s PV 在 NFS 上建立持久缓存(但 gitlab-runner 支持其他卷类型)。由于 NFS 提供持久性,以下配置不使用 cache gitlab 功能。

1)在您的集群上创建一个 PersistentVolume,例如此处使用 NFS(适应您的持久层和您的选项):

apiVersion: v1
kind: PersistentVolume
metadata:
  name: gitlabrunner-nfs-volume
spec:
  capacity:
    storage: 10Gi
  mountOptions:
    - nolock
  accessModes:
    - ReadWriteMany
  persistentVolumeReclaimPolicy: Recycle
  nfs:
    path: /gitlabrunner
    server: 1.2.3.4

2) 引用 PV 以获取作为 runner pod 中卷的声明:

[[runners.kubernetes.volumes.pvc]]
  name = "pvc-1"
  mount_path = "/path/to/mount/point1"

注意 (03/09/18):这些参数的命令行选项尚不存在。有一个未解决的问题

3)为gitlab-runner缓存指定相同的路径:

[[runners]]
  executor = "kubernetes"
  # ...
  cache_dir = "/path/to/mount/point1"

--cache-dir "/path/to/mount/point1"
交互模式

4)使用

-Dmaven.repo.local
选项中的“/path/to/mount/point1”目录


4
投票

我能够使用主机卷来共享我的

.m2
存储库目录。这还有一个优点是可以共享我的
settings.xml
文件(不是每个人都想要)。我发现这比使用提到的
cache
解决方案更快。

[[runners]]
  [runners.docker]
    volumes = ["/home/<user>/.m2:/root/.m2"]

2
投票

还有另一种方法。不要使用 gitlab 缓存并使用自定义(每个项目)docker 镜像。

一些细节:

首先,您需要创建一个 Maven docker 映像,其中提供了项目依赖项所需的所有(或大部分)。将其发布到您的注册表(gitlab 有一个)并将其用于任何运行 Maven 的作业。

为了创建这样的图像,我通常在 CI 中创建一个手动触发的附加作业。您需要在初始阶段以及项目依赖项发生大量修改时触发它。

工作示例可以在这里找到:

https://gitlab.com/alexej.vlasov/syncer/blob/master/.gitlab-ci.yml - 该项目正在使用准备好的图像,并且它还有准备该图像的工作。

https://gitlab.com/alexej.vlasov/maven/blob/master/Dockerfile - dockerfile 运行 Maven 并下载一次依赖项。

优点:

  • 不需要每次都下载依赖项 - 它们位于 docker 镜像(并且 docker 层缓存在运行器上)
  • 工作完成后无需上传工件
  • 作业中不下载缓存,不要使用maven

1
投票

使用 CI_PROJECT_DIR 变量时,不必在变量部分声明 MAVEN_OPTS(克隆存储库和运行作业的完整路径)

cache:
    key: maven-cache
    paths:
    - $CI_PROJECT_DIR/.m2/
最新问题
© www.soinside.com 2019 - 2024. All rights reserved.