Compare commits
1 Commits
6b9827a618
...
51c394552e
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
51c394552e |
@@ -92,14 +92,18 @@ style conventions are in separate documents:
|
|||||||
reading the Makefile.
|
reading the Makefile.
|
||||||
|
|
||||||
- Every repo should have a `Dockerfile`. All Dockerfiles must run `make check`
|
- Every repo should have a `Dockerfile`. All Dockerfiles must run `make check`
|
||||||
as a build step so the build fails if the branch is not green. For non-server
|
as a build step so the build fails if the branch is not green — which requires
|
||||||
repos, the Dockerfile should bring up a development environment and run
|
`ARG CHECK_EPOCH` and its guard in every stage containing a check-running
|
||||||
`make check`. For server repos, `make check` should run as an early build
|
`RUN`, per the `CHECK_EPOCH` rule below. Without them a Dockerfile satisfies
|
||||||
stage before the final image is assembled. Dockerfiles install development
|
this criterion while its check layers are served from cache, so the build
|
||||||
prerequisites by running `script/bootstrap` rather than duplicating installs
|
cannot fail on a branch that is not green. For non-server repos, the
|
||||||
inline; COPY `script/` and the dependency manifests (`package.json` +
|
Dockerfile should bring up a development environment and run `make check`. For
|
||||||
`yarn.lock`, `go.mod` + `go.sum`, etc.) before running it so the bootstrap
|
server repos, `make check` should run as an early build stage before the final
|
||||||
layer stays cached until dependencies change.
|
image is assembled. Dockerfiles install development prerequisites by running
|
||||||
|
`script/bootstrap` rather than duplicating installs inline; COPY `script/` and
|
||||||
|
the dependency manifests (`package.json` + `yarn.lock`, `go.mod` + `go.sum`,
|
||||||
|
etc.) before running it so the bootstrap layer stays cached until dependencies
|
||||||
|
change.
|
||||||
|
|
||||||
- **Every check-running `RUN` must be cache-busted with `CHECK_EPOCH`.** Docker
|
- **Every check-running `RUN` must be cache-busted with `CHECK_EPOCH`.** Docker
|
||||||
invalidates a `COPY` layer only when the copied content changes, so on an
|
invalidates a `COPY` layer only when the copied content changes, so on an
|
||||||
@@ -130,8 +134,8 @@ style conventions are in separate documents:
|
|||||||
rather than dependent on BuildKit's handling of an unreferenced `ARG`, and
|
rather than dependent on BuildKit's handling of an unreferenced `ARG`, and
|
||||||
it puts the epoch in the build log. The guard is itself value-keyed, for
|
it puts the epoch in the build log. The guard is itself value-keyed, for
|
||||||
the same reason: it references `$CHECK_EPOCH`, so BuildKit renders the
|
the same reason: it references `$CHECK_EPOCH`, so BuildKit renders the
|
||||||
epoch into that layer's description (observed as
|
epoch into that layer's description (rendered as
|
||||||
`RUN [ -n "1786287053..." ] || exit 1`) and re-runs it whenever the value
|
`RUN [ -n "<epoch>" ] || exit 1`) and re-runs it whenever the value
|
||||||
changes. Each stage therefore has two independent invalidation points, and
|
changes. Each stage therefore has two independent invalidation points, and
|
||||||
the guard always precedes the check `RUN`. Keep both: the expansion is
|
the guard always precedes the check `RUN`. Keep both: the expansion is
|
||||||
defence in depth, and it is what makes the epoch visible in the build
|
defence in depth, and it is what makes the epoch visible in the build
|
||||||
@@ -212,6 +216,16 @@ style conventions are in separate documents:
|
|||||||
a stage dependency. BuildKit runs stages in parallel by default; without
|
a stage dependency. BuildKit runs stages in parallel by default; without
|
||||||
this line, the build stage would not wait for lint to finish and a lint
|
this line, the build stage would not wait for lint to finish and a lint
|
||||||
failure might not fail the overall build.
|
failure might not fail the overall build.
|
||||||
|
- **Re-prove that ordering on a warm cache after adopting `CHECK_EPOCH`.**
|
||||||
|
The cache-bust turns this no-op `COPY` into a content-cache hit, so an
|
||||||
|
ordering guarantee established on a cold cache does not automatically
|
||||||
|
carry over; it has to be re-checked warm. This was re-proved in another
|
||||||
|
repo in the org that uses the same file-dependency trick (there with a
|
||||||
|
marker file in place of `go.sum`), and the ordering held. It has **not**
|
||||||
|
been verified in this repo, which is single-stage and has no lint stage to
|
||||||
|
order against. Any repo relying on a file-dependency trick for stage
|
||||||
|
ordering should re-check it warm after adopting the bust rather than
|
||||||
|
assuming this result transfers.
|
||||||
- If the project uses `//go:embed` directives that reference build artifacts
|
- If the project uses `//go:embed` directives that reference build artifacts
|
||||||
(e.g. a web frontend compiled in a separate stage), the lint stage must
|
(e.g. a web frontend compiled in a separate stage), the lint stage must
|
||||||
create placeholder files so the embed directives resolve. Example:
|
create placeholder files so the embed directives resolve. Example:
|
||||||
|
|||||||
Reference in New Issue
Block a user