Skip to content

Action outputs with fixed timestamps cause problems #14723

@miscott2

Description

@miscott2

Description of the problem / feature request:

If an output file from a Bazel action has a fixed timestamp then if the content of the file change but the size of the file doesn't it won't trigger the re-running of any actions that depends on this file.

Feature requests: what underlying problem are you trying to solve with this feature?

Some of the inputs to our build are archives containing template files that are expanded during the build. The archives are produced by another build system and to ensure that build system is reproducible the timestamps of the template files are set to 1970 in the archive. During the build we extract the templates files from the archive (retaining their timestamp as this is the default behavior of tar), expand the template and then use the expanded template in a further action. When we checkout a different refpoint of our code sometimes the archive has changed but the templates are still the same size and this results in actions not being re-run when they should be.

I understand that Bazel can't rehash all input files but I was a bit surprised that when an action is run that all output files are not rehashed. Perhaps this is too much of an edge case to worry about but I thought it was worth raising.

We've worked around the issue by not retaining timestamps when we extract files from the archives but wanted to check if Bazel should handle this.

Bugs: what's the simplest, easiest way to reproduce this bug? Please provide a minimal example if possible.

Create a workspace with the following BUILD and .bzl files

$cat BUILD
load("rules.bzl", "my_expand")

genrule(
    name = "my_templates",
    srcs = ["template_archive.tar"],
    outs = ["template1"],
    cmd = "tar -C $(@D) -xf template_archive.tar",
)

my_expand(
    name = "expand1",
    input = "template1",
    output = "expanded1",
    to_sub = {"test":"foo"}
)
$cat rules.bzl
def _my_expand_impl(ctx):
    ctx.actions.expand_template(
        template = ctx.file.input,
        output = ctx.outputs.output,
        substitutions = ctx.attr.to_sub
    )

my_expand = rule(
    implementation = _my_expand_impl,
    attrs = {
        "input": attr.label(allow_single_file=True),
        "output": attr.output(),
        "to_sub" : attr.string_dict(),
    }
)

Now create a set of archives with different template files

echo "test : alpha" > template1
tar -cf template_archive_alpha.tar --mtime='1970-01-01' template1
echo "test : delta" > template1
tar -cf template_archive_delta.tar --mtime='1970-01-01' template1
echo "test : beta" > template1
tar -cf template_archive_beta.tar --mtime='1970-01-01' template1

Put the alpha archive in place as the input, build and verify that the expanded template is as expected.

$cp template_archive_alpha.tar template_archive.tar 
$bazel ...
INFO: Analyzed 2 targets (0 packages loaded, 0 targets configured).
INFO: Found 2 targets...
INFO: Elapsed time: 0.106s, Critical Path: 0.03s
INFO: 2 processes: 1 internal, 1 linux-sandbox.
INFO: Build completed successfully, 2 total actions
$cat bazel-bin/expanded1 
foo : alpha

Switch to the delta archive as the input, build and verify that the expanded template has not been updated.

$cp template_archive_delta.tar template_archive.tar 
$bazel ...
INFO: Analyzed 2 targets (0 packages loaded, 0 targets configured).
INFO: Found 2 targets...
INFO: Elapsed time: 0.095s, Critical Path: 0.03s
INFO: 2 processes: 1 internal, 1 linux-sandbox.
INFO: Build completed successfully, 2 total actions
$cat bazel-bin/expanded1 
foo : alpha

Even though the extracted template has been updated

$cat bazel-bin/template1 
test : delta

Verify that performing a Bazel clean and building results in the correct output.

$bazel clean
INFO: Starting clean (this may take a while). Consider using --async if the clean takes more than several minutes.
$bazel build ...
INFO: Analyzed 2 targets (5 packages loaded, 10 targets configured).
INFO: Found 2 targets...
INFO: Elapsed time: 0.186s, Critical Path: 0.03s
INFO: 3 processes: 2 internal, 1 linux-sandbox.
INFO: Build completed successfully, 3 total actions
$cat bazel-bin/expanded1 
foo : delta

Switching to/from the alpha/delta archives and the beta archive works fine presumably because the size of the template files change (beta being 4 characters and alpha/delta being 5 characters).

What operating system are you running Bazel on?

Linux

What's the output of bazel info release?

release 4.1.0- (@Non-Git)

If bazel info release returns "development version" or "(@Non-Git)", tell us how you built Bazel.

I don't have full details to hand about how we built Bazel but I'm confident that any changes have not impacted the behavior described above.

What's the output of git remote get-url origin ; git rev-parse master ; git rev-parse HEAD ?

N/A

Have you found anything relevant by searching the web?

No. I'm not even confident if Bazel should handle this scenario but I think it's worth asking.

Any other information, logs, or outputs that you want to share?

No

Metadata

Metadata

Assignees

Labels

P1I'll work on this now. (Assignee required)more data neededteam-CoreSkyframe, bazel query, BEP, options parsing, bazelrctype: bug

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions