Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
75c4011a2e |
@@ -56,14 +56,14 @@ with your task.
|
||||
- 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.
|
||||
The `script/` builds pass a new `CACHEBUST` value on every build, which
|
||||
reruns every `RUN` step after that line and leaves the layers above it and
|
||||
the cache mounts in place; `--no-cache` would build those layers again and
|
||||
empty the mounts. A stage without the `ARG` line is served from cache on
|
||||
an unchanged tree, so the scripts and the `ARG` lines are re-vendored in
|
||||
one commit.
|
||||
`FROM`. A step that also installs anything else comes after
|
||||
`ARG CACHEBUST` too. A `script/bootstrap` that also installs node packages
|
||||
is one. The `script/` builds pass a new `CACHEBUST` value on every build,
|
||||
which reruns every `RUN` step after that line and leaves the layers above
|
||||
it and the cache mounts in place; `--no-cache` would build those layers
|
||||
again and empty the mounts. A stage without the `ARG` line is served from
|
||||
cache on an unchanged tree, so the scripts and the `ARG` lines are
|
||||
re-vendored in one commit.
|
||||
- [ ] Go: each Go stage downloads the modules (`COPY go.mod go.sum ./`,
|
||||
`RUN go mod download`) above `ARG CACHEBUST`; the steps that compile
|
||||
(`golangci-lint run`, `go test`, `go build`) mount Go's build cache
|
||||
@@ -76,15 +76,19 @@ with your task.
|
||||
- [ ] Python: a `test` phase that installs its packages from `Pipfile.lock` does
|
||||
it above `ARG CACHEBUST`, with `COPY script/ script/`,
|
||||
`COPY Pipfile Pipfile.lock ./` and `RUN script/bootstrap`. When
|
||||
`script/bootstrap` runs in that step, it installs nothing beyond system
|
||||
packages, pipenv and its dependencies, and the packages from
|
||||
`Pipfile.lock`. It installs pipenv and its dependencies by hash, with
|
||||
`pip install --require-hashes`. It installs the packages from
|
||||
`Pipfile.lock` with `pipenv install --deploy`, plus `--dev` when the tests
|
||||
need the development packages. It installs no Python there, because the
|
||||
tests use the base image's. The tests run after `ARG CACHEBUST`, and every
|
||||
other stage installs its Python packages after it, as in the Python `test`
|
||||
phase example in `REPO_POLICIES.md`
|
||||
`script/bootstrap` runs in that step, it installs nothing beyond these:
|
||||
- system packages
|
||||
- pipenv and its dependencies
|
||||
- the packages from `Pipfile.lock`
|
||||
|
||||
It installs pipenv and its dependencies by hash, with
|
||||
`pip install --require-hashes`. It installs the packages from `Pipfile.lock`
|
||||
with `pipenv install --deploy`, plus `--dev` when the tests need the
|
||||
development packages. It installs no Python there, because the tests use the
|
||||
base image's. The tests run after `ARG CACHEBUST`, and every other stage
|
||||
installs its Python packages after it, as in the Python `test` phase example
|
||||
in `REPO_POLICIES.md`
|
||||
|
||||
- [ ] The gate phases invoke their tools directly, never through `make lint` or
|
||||
`script/test` — those are themselves a `docker build` and would recurse
|
||||
inside a build step
|
||||
@@ -111,15 +115,15 @@ with your task.
|
||||
- that of a submodule keeping its own `.git` directory
|
||||
|
||||
`git describe` does not need them, and each can hold a credential: a
|
||||
password in a remote URL, or the token the CI checkout step stores there. A
|
||||
submodule name may have a `config` segment, as in `config`, `deploy/config`
|
||||
or `config/lib`. Such a submodule loses its whole git directory to
|
||||
`**/.git/modules/**/config`, and Go's version stamping then fails the build.
|
||||
Give it a name without that segment (`git submodule add --name`). The stage
|
||||
that compiles has `git`: the Debian Go image has it, and an alpine one needs
|
||||
`apk add --no-cache git`. That stage takes the version from the `VERSION`
|
||||
build argument when one is given, otherwise from
|
||||
`git describe --tags --always`. That gives:
|
||||
password in a remote URL, or the token the CI checkout step stores there.
|
||||
Some submodule names have a `config` segment, as in `config`,
|
||||
`deploy/config` or `config/lib`. Such a submodule loses its whole git
|
||||
directory to `**/.git/modules/**/config`, and Go's version stamping then
|
||||
fails the build. Give it a name without that segment
|
||||
(`git submodule add --name`). The stage that compiles has `git`: the Debian
|
||||
Go image has it, and an alpine one needs `apk add --no-cache git`. That
|
||||
stage takes the version from the `VERSION` build argument when one is given,
|
||||
otherwise from `git describe --tags --always`. That gives:
|
||||
- the tag, on a tagged commit
|
||||
- the tag, the number of commits since it and the short commit
|
||||
(`v1.2.3-4-gabc1234`), on a later commit
|
||||
|
||||
@@ -82,7 +82,7 @@ Template files can be fetched from:
|
||||
|
||||
`git describe` does not need them, and each can hold a credential: a
|
||||
password in a remote URL, or the token the CI checkout step stores
|
||||
there. A submodule name may have a `config` segment, as in `config`,
|
||||
there. Some submodule names have a `config` segment, as in `config`,
|
||||
`deploy/config` or `config/lib`. Such a submodule loses its whole git
|
||||
directory to `**/.git/modules/**/config`, and Go's version stamping then
|
||||
fails the build. Give it a name without that segment
|
||||
@@ -123,14 +123,14 @@ Template files can be fetched from:
|
||||
- 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.
|
||||
The `script/` builds pass a new `CACHEBUST` value on every build, which
|
||||
reruns every `RUN` step after that line and leaves the layers above it and
|
||||
the cache mounts in place; `--no-cache` would build those layers again and
|
||||
empty the mounts. A stage without the `ARG` line is served from cache on
|
||||
an unchanged tree, so the scripts and every stage's `ARG CACHEBUST` line
|
||||
are added in the same commit.
|
||||
`FROM`. A step that also installs anything else comes after
|
||||
`ARG CACHEBUST` too. A `script/bootstrap` that also installs node packages
|
||||
is one. The `script/` builds pass a new `CACHEBUST` value on every build,
|
||||
which reruns every `RUN` step after that line and leaves the layers above
|
||||
it and the cache mounts in place; `--no-cache` would build those layers
|
||||
again and empty the mounts. A stage without the `ARG` line is served from
|
||||
cache on an unchanged tree, so the scripts and every stage's
|
||||
`ARG CACHEBUST` line are added in the same commit.
|
||||
- Go: each Go stage downloads the modules (`COPY go.mod go.sum ./`,
|
||||
`RUN go mod download`) above `ARG CACHEBUST`; the steps that compile
|
||||
(`golangci-lint run`, `go test`, `go build`) mount Go's build cache
|
||||
@@ -143,15 +143,19 @@ Template files can be fetched from:
|
||||
- Python: a `test` phase that installs its packages from `Pipfile.lock` does
|
||||
it above `ARG CACHEBUST`, with `COPY script/ script/`,
|
||||
`COPY Pipfile Pipfile.lock ./` and `RUN script/bootstrap`. When
|
||||
`script/bootstrap` runs in that step, it installs nothing beyond system
|
||||
packages, pipenv and its dependencies, and the packages from
|
||||
`Pipfile.lock`. It installs pipenv and its dependencies by hash, with
|
||||
`pip install --require-hashes`. It installs the packages from
|
||||
`Pipfile.lock` with `pipenv install --deploy`, plus `--dev` when the tests
|
||||
need the development packages. It installs no Python there, because the
|
||||
tests use the base image's. The tests run after `ARG CACHEBUST`, and every
|
||||
other stage installs its Python packages after it, as in the Python `test`
|
||||
phase example in `REPO_POLICIES.md`
|
||||
`script/bootstrap` runs in that step, it installs nothing beyond these:
|
||||
- system packages
|
||||
- pipenv and its dependencies
|
||||
- the packages from `Pipfile.lock`
|
||||
|
||||
It installs pipenv and its dependencies by hash, with
|
||||
`pip install --require-hashes`. It installs the packages from
|
||||
`Pipfile.lock` with `pipenv install --deploy`, plus `--dev` when the
|
||||
tests need the development packages. It installs no Python there,
|
||||
because the tests use the base image's. The tests run after
|
||||
`ARG CACHEBUST`, and every other stage installs its Python packages
|
||||
after it, as in the Python `test` phase example in `REPO_POLICIES.md`
|
||||
|
||||
- Server: the final stage builds and runs the application
|
||||
- Non-server: the final stage brings up the dev environment
|
||||
- Image pinned by sha256 hash with version/date comment
|
||||
|
||||
@@ -235,7 +235,7 @@ style conventions are in separate documents:
|
||||
executes, and the build still exits 0. Every `docker build` in `script/`
|
||||
therefore passes `--build-arg CACHEBUST="$(date +%s)-$$"`, the time and the
|
||||
script's process id. So no two builds share a value, not even the three in one
|
||||
`script/cibuild`. These are the four, and there is no fifth:
|
||||
`script/cibuild`. Four scripts do this, and there is no fifth:
|
||||
- `script/lint`
|
||||
- `script/test`
|
||||
- `script/cibuild`
|
||||
@@ -440,7 +440,7 @@ style conventions are in separate documents:
|
||||
|
||||
`git describe` does not need them, and each can hold a credential: a
|
||||
password in a remote URL, or the token the CI checkout step stores
|
||||
there. A submodule name may have a `config` segment, as in `config`,
|
||||
there. Some submodule names have a `config` segment, as in `config`,
|
||||
`deploy/config` or `config/lib`. Such a submodule loses its whole git
|
||||
directory to `**/.git/modules/**/config`, and Go's version stamping then
|
||||
fails the build. Give it a name without that segment
|
||||
@@ -499,8 +499,8 @@ style conventions are in separate documents:
|
||||
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.
|
||||
- It then runs `pipenv install --deploy`, with `--dev` when the tests need
|
||||
the development packages. `--deploy` does all of these:
|
||||
- `script/bootstrap` then runs `pipenv install --deploy`, with `--dev` when
|
||||
the tests need the development packages. `--deploy` does all of these:
|
||||
- installs only what `Pipfile.lock` names
|
||||
- checks every package against the lockfile's hashes
|
||||
- fails when the lockfile is out of date with `Pipfile`
|
||||
@@ -850,14 +850,15 @@ style conventions are in separate documents:
|
||||
|
||||
- after installing, re-resolves the binary the way callers do, with
|
||||
`hash -r` and then through `PATH`, not through the directory the installer
|
||||
wrote to. It fails and names the resolved path. A shadowing binary can
|
||||
hide an install, which then succeeds while no caller sees any change.
|
||||
wrote to. A shadowing binary can hide an install, which then succeeds
|
||||
while no caller sees any change. In that case it fails and names the
|
||||
resolved path.
|
||||
- is actually called, and prints the version on both success paths. A
|
||||
function defined and never invoked has the same exit status and the same
|
||||
empty output as one that worked.
|
||||
|
||||
Node is the exception to the whole-token comparison. The canonical
|
||||
`script/bootstrap` compares only node's major version, because the
|
||||
`script/bootstrap` compares only node's major version. That is because the
|
||||
`Dockerfile` stages start from a node 22 alpine image, which is not the
|
||||
exact pin, and nvm cannot install a prebuilt node on alpine.
|
||||
|
||||
@@ -927,8 +928,8 @@ style conventions are in separate documents:
|
||||
an explicit allowlist of known origins. Wildcard (`*`) is acceptable
|
||||
only for public, unauthenticated read-only APIs.
|
||||
- **Error handling:**
|
||||
- Internal errors must never leak implementation details to the client,
|
||||
such as:
|
||||
- Internal errors must never leak implementation details to the client.
|
||||
Those details include:
|
||||
- stack traces
|
||||
- SQL queries
|
||||
- file paths
|
||||
|
||||
Reference in New Issue
Block a user