运行 仅当先前任务的输出发生变化时才会执行 Concourse 构建步骤

Run a Concourse build step only when an output of a prior task changes

给定一个输入,我有一个便宜的函数和一个昂贵的函数;这些中的每一个都被建模为一个 Concourse 任务。

如果廉价函数的两次调用具有相同的输出,我知道昂贵函数的两次调用同样具有相同的输出。

如何设置一个管道,当廉价函数的结果发生变化时只运行昂贵的函数?


举个例子,假设 cheap 函数从代码库中去除注释和空格,然后计算校验和;而昂贵的功能实际上运行包含的代码。在这种情况下,我的目标是不费心构建任何仅在注释或空格方面与先前版本不同的修订版。

我考虑过使用 git 资源并(在我们的示例中)将每个编译目标的预处理器输出哈希存储在不同的文件中,因此执行实际编译(和适用的单元测试)的任务可以触发对文件的更改,其中包含构建该文件的输入的哈希值。不过,拥有一个单独的 git 资源来无限期地维护历史哈希值似乎有点过分了。有没有更好的方法?


这类似于 ,但我正在尝试测试 运行 函数针对文件 的结果是否发生变化,以触发仅针对可能修改构建结果的更改,而不是所有可能的更改。 (上面描述的提议,创建一个带有 cheap 函数输出的中间 repo,将有效地使用该问题的答案作为其组成部分之一;但我希望有一个移动部分更少的选项)。

考虑使用 put 嵌套在 try: 修饰符中:

cheap 作业需要两个输入:

  • git 回购代码
  • 最后一次廉价计算的哈希值

在每次提交 code-repo 时,cheap 作业读取 last-hash 输入,从 hash 映射并将其与计算结果进行比较(在愚蠢的例子中下面,hash.txt 的内容签入了 code-repo).

的根目录

如果它确定来自传入提交的哈希值与先前记录的哈希值不同,它会使用新的哈希值填充 put 参数 hash/hash.txt,这会导致新的 put 到反过来将触发 expensive 作业的资源。

如果未检测到更改,放置尝试将失败,因为 put 参数将不存在,但整个 cheap 作业将成功。

resources:
  - name: code-repo
    type: git
    source:
      branch: master
      private_key: ((key))
      uri: git@github.com:myorg/code-repo.git

  - name: hash
    type: s3
    source:
      access_key_id: ((aws_access))
      secret_access_key: ((aws_secret))
      region_name: ((aws_region))
      bucket: my-versioned-aws-bucket
      versioned_file: hash/hash.txt

jobs:
  - name: cheap
    plan:
    - get: code-repo
      trigger: true
    - get: hash
    - task: check
      input_mapping:
        last-hash: hash
      config:
        platform: linux
        image_resource:
          type: docker-image
          source: { repository: alpine }
        inputs:
          - name: code-repo
          - name: last-hash
        outputs:
          - name: hash
        run:
          path: /bin/sh
          args:
          - -c
          - |
            LAST="$(cat last-hash/hash.txt)"
            NEW=$(cat code-repo/hash.txt)
            if [ "$LAST" != "$NEW" ]; then
              cp code-repo/hash.txt hash/hash.txt
            fi
      on_success:
        try:
          put: hash
          params:
            file: hash/hash.txt

  - name: expensive
    plan:
    - get: hash
      trigger: true
      passed: [ cheap ]

注意:您必须用一些值填充 s3 中的初始状态文件,否​​则 cheap 作业将不会启动。