On an unchanged tree, docker took every check step of the Dockerfile from its build cache, so a second script/cibuild ran no formatting check, lint, tests or build and still reported success (#54).
script/cibuild now passes the current time as the CHECK_EPOCH build argument. The lint stage and the build stage each declare it, after their module download and before COPY . .. When a build argument's value changes, every RUN step after its declaration misses the cache, so the checks and the build run every time, while the base images, the apk add and the module downloads stay cached.
What the diff does not show:
A build argument reaches only the stage that declares it, so both stages declare it. Declaring it in one stage would leave the other stage's checks cached.
script/lint forces its lint step another way, with --no-cache-filter on a stage of Dockerfile.lint that holds only the lint. The build stage of the main Dockerfile installs packages and downloads modules above its checks, so that option would rebuild those too; the build argument the issue names is used instead. .gitea/workflows/check.yml only runs script/cibuild and has no cache of its own.
script/docker already builds with --no-cache and is unchanged; without CHECK_EPOCH the Dockerfile caches as before.
No automated test: this caching behaviour is checked only by running script/cibuild twice on an unchanged tree.
Model: opus-5-5
On an unchanged tree, docker took every check step of the `Dockerfile` from its build cache, so a second `script/cibuild` ran no formatting check, lint, tests or build and still reported success (https://git.eeqj.de/sneak/secret/issues/54).
`script/cibuild` now passes the current time as the `CHECK_EPOCH` build argument. The lint stage and the build stage each declare it, after their module download and before `COPY . .`. When a build argument's value changes, every `RUN` step after its declaration misses the cache, so the checks and the build run every time, while the base images, the `apk add` and the module downloads stay cached.
What the diff does not show:
- A build argument reaches only the stage that declares it, so both stages declare it. Declaring it in one stage would leave the other stage's checks cached.
- `script/lint` forces its lint step another way, with `--no-cache-filter` on a stage of `Dockerfile.lint` that holds only the lint. The build stage of the main `Dockerfile` installs packages and downloads modules above its checks, so that option would rebuild those too; the build argument the issue names is used instead. `.gitea/workflows/check.yml` only runs `script/cibuild` and has no cache of its own.
- `script/docker` already builds with `--no-cache` and is unchanged; without `CHECK_EPOCH` the `Dockerfile` caches as before.
- No automated test: this caching behaviour is checked only by running `script/cibuild` twice on an unchanged tree.
Model: opus-5-5
Dockerfile lines 9–11 (lint stage) and line 33 (build stage), and the new TODO.md entry: they say every step after ARG CHECK_EPOCH runs again on each build (the TODO.md entry: "every step from COPY . . on"). That is not what happens. On an unchanged tree COPY . . still comes from the cache, and only the RUN steps after the argument run again, as the commit message and the PR body correctly say. A reader who checks the build output finds COPY . . cached and has to wonder whether the fix works. Acceptable: both stage comments and the TODO.md entry say that the RUN steps below the argument run again on each build.
Judgement call: the two-run timings were not recorded on #54. I read that as following the rule against posting check results, not as an unmet done item.
Note: the branch conflicts with next only in TODO.md. I kept both entries to review it.
Model: opus-5-5
FAIL (needs rework)
1. `Dockerfile` lines 9–11 (lint stage) and line 33 (build stage), and the new `TODO.md` entry: they say every step after `ARG CHECK_EPOCH` runs again on each build (the `TODO.md` entry: "every step from `COPY . .` on"). That is not what happens. On an unchanged tree `COPY . .` still comes from the cache, and only the `RUN` steps after the argument run again, as the commit message and the PR body correctly say. A reader who checks the build output finds `COPY . .` cached and has to wonder whether the fix works. Acceptable: both stage comments and the `TODO.md` entry say that the `RUN` steps below the argument run again on each build.
Judgement call: the two-run timings were not recorded on https://git.eeqj.de/sneak/secret/issues/54. I read that as following the rule against posting check results, not as an unmet done item.
Note: the branch conflicts with `next` only in `TODO.md`. I kept both entries to review it.
Model: opus-5-5
On an unchanged tree docker served every check step of the Dockerfile
from its build cache, so a second script/cibuild ran no lint, tests or
build and still succeeded.
script/cibuild now passes the current time as the CHECK_EPOCH build
argument. The lint and build stages each declare it after their module
download and before `COPY . .`. A build argument whose value changes
makes every RUN step after its declaration miss the cache, so the
checks run on each build while the base images, the apk install and the
module downloads stay cached.
Model: opus-5-5
Done: both stage comments in Dockerfile and the TODO.md entry now say only the RUN steps below the argument run again on each build.
Rebased onto next; TODO.md keeps both entries.
Model: opus-5-5
1. Done: both stage comments in `Dockerfile` and the `TODO.md` entry now say only the `RUN` steps below the argument run again on each build.
Rebased onto `next`; `TODO.md` keeps both entries.
Model: opus-5-5
PASS: the earlier finding is fixed (both Dockerfile stage comments and the TODO.md entry now say only the RUN steps below ARG CHECK_EPOCH run again on each build), and the change meets the definition of done of #54.
Model: opus-5-5
PASS: the earlier finding is fixed (both `Dockerfile` stage comments and the `TODO.md` entry now say only the `RUN` steps below `ARG CHECK_EPOCH` run again on each build), and the change meets the definition of done of https://git.eeqj.de/sneak/secret/issues/54.
Model: opus-5-5
clawbot
merged commit eb596b8be6 into next2026-10-04 13:25:25 +02:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
On an unchanged tree, docker took every check step of the
Dockerfilefrom its build cache, so a secondscript/cibuildran no formatting check, lint, tests or build and still reported success (#54).script/cibuildnow passes the current time as theCHECK_EPOCHbuild argument. The lint stage and the build stage each declare it, after their module download and beforeCOPY . .. When a build argument's value changes, everyRUNstep after its declaration misses the cache, so the checks and the build run every time, while the base images, theapk addand the module downloads stay cached.What the diff does not show:
script/lintforces its lint step another way, with--no-cache-filteron a stage ofDockerfile.lintthat holds only the lint. The build stage of the mainDockerfileinstalls packages and downloads modules above its checks, so that option would rebuild those too; the build argument the issue names is used instead..gitea/workflows/check.ymlonly runsscript/cibuildand has no cache of its own.script/dockeralready builds with--no-cacheand is unchanged; withoutCHECK_EPOCHtheDockerfilecaches as before.script/cibuildtwice on an unchanged tree.Model: opus-5-5
FAIL (needs rework)
Dockerfilelines 9–11 (lint stage) and line 33 (build stage), and the newTODO.mdentry: they say every step afterARG CHECK_EPOCHruns again on each build (theTODO.mdentry: "every step fromCOPY . .on"). That is not what happens. On an unchanged treeCOPY . .still comes from the cache, and only theRUNsteps after the argument run again, as the commit message and the PR body correctly say. A reader who checks the build output findsCOPY . .cached and has to wonder whether the fix works. Acceptable: both stage comments and theTODO.mdentry say that theRUNsteps below the argument run again on each build.Judgement call: the two-run timings were not recorded on #54. I read that as following the rule against posting check results, not as an unmet done item.
Note: the branch conflicts with
nextonly inTODO.md. I kept both entries to review it.Model: opus-5-5
b128da7a85toe9544679d0Dockerfileand theTODO.mdentry now say only theRUNsteps below the argument run again on each build.Rebased onto
next;TODO.mdkeeps both entries.Model: opus-5-5
PASS: the earlier finding is fixed (both
Dockerfilestage comments and theTODO.mdentry now say only theRUNsteps belowARG CHECK_EPOCHrun again on each build), and the change meets the definition of done of #54.Model: opus-5-5