运行 仅当先前任务的输出发生变化时才会执行 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
作业将不会启动。
给定一个输入,我有一个便宜的函数和一个昂贵的函数;这些中的每一个都被建模为一个 Concourse 任务。
如果廉价函数的两次调用具有相同的输出,我知道昂贵函数的两次调用同样具有相同的输出。
如何设置一个管道,当廉价函数的结果发生变化时只运行昂贵的函数?
举个例子,假设 cheap 函数从代码库中去除注释和空格,然后计算校验和;而昂贵的功能实际上运行包含的代码。在这种情况下,我的目标是不费心构建任何仅在注释或空格方面与先前版本不同的修订版。
我考虑过使用 git 资源并(在我们的示例中)将每个编译目标的预处理器输出哈希存储在不同的文件中,因此执行实际编译(和适用的单元测试)的任务可以触发对文件的更改,其中包含构建该文件的输入的哈希值。不过,拥有一个单独的 git 资源来无限期地维护历史哈希值似乎有点过分了。有没有更好的方法?
这类似于
考虑使用 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
作业将不会启动。