【问题标题】:GitLab CI : merge or replace cache?GitLab CI:合并或替换缓存?
【发布时间】:2019-07-18 23:55:40
【问题描述】:

我正在使用 GitLab CI。

我在构建阶段有 2 个作业,它们以不同的方式构建我的应用程序。 2 个作业为分支上传缓存。我使用编译好的源代码在测试阶段启动了一些测试。

build:
  stage: build
  script:
    - ./gradlew build --build-cache --quiet
  cache:
    key: ${CI_COMMIT_REF_SLUG}
    paths:
     - "*/build"

build_with_different_conf:
  stage: build
  script:
    - ./gradlew buildDiff --build-cache --quiet
  cache:
    key: ${CI_COMMIT_REF_SLUG}
    paths:
     - "*/build"

Test:
  stage: test
  script:
    - ./gradlew test --build-cache

在我的示例中,作业 build_with_different_conf 需要更多时间才能完成。

我的问题是:最后完成的构建作业是从第一个构建作业上传缓存并替换缓存,还是将文件与先前的作业合并?

谢谢。

【问题讨论】:

  • 您能否再解释一下,为什么将cache 用于分支,您的意思是什么。给出一些代码 .yml 示例。
  • 我编辑添加更多上下文
  • 首先我认为你必须使用缓存,在这种情况下你想使用人工制品来传输你的构建结果。缓存主要用于传输一些依赖项或其他不经常移动的东西,例如 npm node_modules
  • 我建议花一些时间在 artifact 文档上。据我了解,您想在一项工作中使用build,而不是使用构建结果来加速testBuild1build2 只是不同的入口点。那是对的吗 ?或者您更愿意拥有build1 而不是使用结果来加速build2test
  • 不过,您的 build 工作结果可能是 .classes 的工件,而此工件的寿命可能只有几分钟/小时。在接下来的工作中使用这个编译的.classes,你可以构建你的war。您的后续工作只需要依赖于先例,这样他们就可以转移工件。我仍然会在我的第一条评论中说明,缓存可能会被误用,但它不是它的主要角色。

标签: caching continuous-integration gitlab gitlab-ci


【解决方案1】:

据我了解,您正在为 gradle 依赖项使用全局缓存。 比你想拥有某种工作,去工作缓存。

我会这样做,或多或少。

stages:
  - build
  - test

cache:
  paths:
    - <your_gradle_cache>

build_classes:
  stage: build
  script:
    - ./gradlew build --build-cache --quiet
  artifacts:
    expire_in: 1d
    paths:
      - <your_build_dir>

build_war:
  stage: build
  dependencies:
    - build_classes
  script:
    - ./gradlew buildDiff --build-cache --quiet
  artifacts:
    expire_in: 1w
    paths:
      - <path_to_your_war>

test_classes:
  stage: test
  dependencies:
    - build_war
  script:
    - ./gradlew test --build-cache

test_war:
  stage: test
  dependencies:
    - build_war
  script:
    - test # some kind of test to assure your war is in good condition

在此配置中:

build_classes --[.classes]--> build_war -> [.war]
 |                 |
[.classes]       [.war]
 |                 |
 V                 V
test_classes    test_war

PS。不要忘记你可以使用shell(或任何你的运行器的操作系统)来调试,了解更多关于这一点。您可以将ls -la 放在任何地方。

【讨论】:

  • 是的,一开始我确实在到处使用lspwd 来了解容器结构。仔细检查缓存内容可能会很好;)对于工件的使用,我不确定。我肯定会将战争用作工件并在部署阶段使用它,但构建目录可以改进同一分支中下一个管道的构建。如果我错了,请纠正我,但工件更适合在同一管道中使用。有了缓存,我可以在下一个分支管道中重新使用它来加速构建。感谢所有提示;)
  • 在这种情况下${CI_COMMIT_REF_SLUG} 应该可以工作。对于缓存键,女巫应该与分支相关。好吧,要么你在全局范围内定义它,整个 ci 都会这样使用它。或者你把它留给每个工作,这样只有一个工作序列使用它。这可能与gradle 更相关,关于我无话可说的地方。
【解决方案2】:
build:
  stage: build

同一阶段的作业并行运行。

cache:
    key: ${CI_COMMIT_REF_SLUG}
    paths:
     - "*/build"

缓存文件由cache:key 管理。这意味着如果您对不同的作业使用相同的cache:key,即使您定义不同的cache:paths,它们也会在作业之间共享相同的cache.zip 文件。如果您使用相同的密钥,但路径不同,那么您的缓存将无效,因为每个作业都会用不同的路径内容覆盖 cache.zip 文件。

在您的情况下,您在不同的工作中使用相同的 cache:key

cache:
    key: ${CI_COMMIT_REF_SLUG}
    paths:
     - "*/build"

这意味着最后完成的作业将覆盖cache.zip 文件而不是合并,并将用于下一个作业和定义相同键的后续管道作业。

奖金:

Test:
  stage: test
  script:
    - ./gradlew test --build-cache

还要注意,如果此作业需要 */build 目录内容存在,则必须小心并更好地使用工件。缓存并不总是存在,它是作为尽力而为的交付方式提供的。

例如我这样使用gitlab ci的缓存。

nodejs_test:
  stage: test
  image: node:12.13-alpine
  before_script:
    - npm install
  script:
    - yarn test
  cache:
    key:
      files:
        # New cache key will be computed on each package.json change.
        - package.json
    paths:
      - node_modules/

nodejs_build:
  stage: build
  image: node:12.13-alpine
  before_script:
    # In case if we miss cache, we can simply install packages again.
    # If cache is there npm install won't download them again.
    - npm install
  script:
    - yarn build
  cache:
    policy: pull        # totally optional
    key:
      files:
        - package.json
      prefix: ${CI_COMMIT_REF_SLUG}
    paths:
      - node_modules/

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-03-13
    • 1970-01-01
    • 2018-10-01
    • 2019-03-03
    • 1970-01-01
    • 1970-01-01
    • 2018-07-06
    • 2016-08-27
    相关资源
    最近更新 更多