List the steps above ARG CACHEBUST and split the long Python install sentences (closes #133)
check / check (push) Canceled after 0s
check / check (push) Canceled after 0s
The ARG CACHEBUST rule and the CACHED expectation now list their steps as bullets, the same way in the policy, the README and both checklists. The checklists' Python item and the policy's Python point use shorter sentences with the verb early. The TODO entry no longer counts "no Python" as an install or says "except" where only a difference is meant. Model: opus-5-5
This commit is contained in:
+36
-32
@@ -174,28 +174,32 @@ style conventions are in separate documents:
|
||||
`script/cibuild`. `script/lint`, `script/test`, `script/cibuild` and
|
||||
`script/docker` are the four, and there is no fifth — `script/check` runs the
|
||||
two gate phases and `script/fmt-check`, and builds no image of its own. In
|
||||
every stage of the `Dockerfile`, `ARG CACHEBUST` comes right after the steps
|
||||
that install system packages, download Go's modules or run `script/bootstrap`
|
||||
to install a Python `test` phase's packages from `Pipfile.lock`, or right
|
||||
after `FROM` in a stage with none of these, and every step that lints, tests
|
||||
or compiles comes after it. A step that installs anything else as well, such
|
||||
as a `script/bootstrap` that also installs node packages, comes after it too.
|
||||
A new value reruns every `RUN` step after that line; `COPY` steps are compared
|
||||
by content and need nothing. Docker keeps the layers above the line until the
|
||||
base image, their own lines or the files they copy change. A stage without the
|
||||
`ARG` line is served from cache on an unchanged tree, so a repository
|
||||
re-vendors the scripts and adds the `ARG` lines in one commit. The scripts do
|
||||
not pass `--no-cache`: it reruns every step too, but it also builds the layers
|
||||
above the line again and empties every cache mount, so Go's build cache and
|
||||
golangci-lint's, which the canonical Go `Dockerfile` below mounts so that they
|
||||
survive between check builds, would start empty every time. A bare
|
||||
`docker build .` is not evidence that anything ran: a sub-second build
|
||||
reporting success is a cache hit, not a result. Never invalidate by pruning —
|
||||
`docker builder prune` and friends destroy a build cache shared with every
|
||||
other build on the host. When a check is added or changed, prove it works by
|
||||
planting a defect it must catch and watching the run fail on it, then revert
|
||||
the defect. A green run alone shows neither that the check ran nor that it
|
||||
covers what it should.
|
||||
every stage of the `Dockerfile`, every step that lints, tests or compiles
|
||||
comes after `ARG CACHEBUST`. `ARG CACHEBUST` comes right after these steps:
|
||||
- the steps that install system packages
|
||||
- the steps that download Go's modules
|
||||
- the step that runs `script/bootstrap` to install a Python `test` phase's
|
||||
packages from `Pipfile.lock`
|
||||
|
||||
A stage with none of these steps declares `ARG CACHEBUST` right after
|
||||
`FROM`. A step that installs anything else as well, such as a
|
||||
`script/bootstrap` that also installs node packages, comes after it too. A
|
||||
new value reruns every `RUN` step after that line; `COPY` steps are compared
|
||||
by content and need nothing. Docker keeps the layers above the line until
|
||||
the base image, their own lines or the files they copy change. A stage
|
||||
without the `ARG` line is served from cache on an unchanged tree, so a
|
||||
repository re-vendors the scripts and adds the `ARG` lines in one commit.
|
||||
The scripts do not pass `--no-cache`: it reruns every step too, but it also
|
||||
builds the layers above the line again and empties every cache mount, so
|
||||
Go's build cache and golangci-lint's, which the canonical Go `Dockerfile`
|
||||
below mounts so that they survive between check builds, would start empty
|
||||
every time. A bare `docker build .` is not evidence that anything ran: a
|
||||
sub-second build reporting success is a cache hit, not a result. Never
|
||||
invalidate by pruning — `docker builder prune` and friends destroy a build
|
||||
cache shared with every other build on the host. When a check is added or
|
||||
changed, prove it works by planting a defect it must catch and watching the
|
||||
run fail on it, then revert the defect. A green run alone shows neither that
|
||||
the check ran nor that it covers what it should.
|
||||
|
||||
- **The gate phases are separate stages, and the build stage depends on both.**
|
||||
The lint phase is based on the `golangci/golangci-lint` image (pinned by
|
||||
@@ -380,8 +384,8 @@ style conventions are in separate documents:
|
||||
`Pipfile.lock`. It installs no Python there: the tests use the base
|
||||
image's Python, which the image's hash pins. If it installs anything else
|
||||
there, the step goes after `ARG CACHEBUST`.
|
||||
- It installs pipenv and its dependencies by hash, as the rule that every
|
||||
external reference is pinned by hash requires. It does so with
|
||||
- Every external reference must be pinned by hash, so `script/bootstrap`
|
||||
installs pipenv and its dependencies by hash. It does so with
|
||||
`pip install --require-hashes -r` and a requirements file in `script/`
|
||||
that lists each of them with `==` and its `--hash`. pip refuses to install
|
||||
a dependency the file does not list.
|
||||
@@ -394,14 +398,14 @@ style conventions are in separate documents:
|
||||
their hashes. The packages `virtualenv` puts into the virtualenv that
|
||||
pipenv creates come from wheels the `virtualenv` package ships, which its
|
||||
hash covers. Two things in the layer are not fixed by a hash. A package
|
||||
with no ready-built wheel for the image is built from source, with build
|
||||
tools pip downloads without a hash check, so a kept layer's build of it
|
||||
may differ from a new one. And system packages keep the versions the
|
||||
package manager gave when the layer was built; a new install may get newer
|
||||
ones.
|
||||
- The packages are kept in a layer rather than a cache mount for the reason
|
||||
Go's modules are: a cache mount is shared by every build on the host, and
|
||||
nothing checks its files again.
|
||||
with no ready-built wheel for the image is built from source. pip
|
||||
downloads the build tools without a hash check, so a kept layer's build of
|
||||
such a package may differ from a new one. And system packages keep the
|
||||
versions the package manager gave when the layer was built; a new install
|
||||
may get newer ones.
|
||||
- As with Go's modules, the packages are kept in a layer, not a cache mount.
|
||||
A cache mount is shared by every build on the host, and nothing checks its
|
||||
files again.
|
||||
|
||||
In this example, `script/bootstrap` finds `make` and `git` already
|
||||
installed, installs pipenv and its dependencies by hash, and runs
|
||||
|
||||
Reference in New Issue
Block a user