Compare commits
2 Commits
beb865ae68
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| d43c1d31ac | |||
| d4eaf5fed2 |
@@ -46,8 +46,12 @@ RUN echo "gate lint-image-pin, epoch ${CHECK_EPOCH}" && \
|
||||
# unpinned HTTPS call; measured on the pinned image, it does not. The
|
||||
# binary carries the schema for its own version, so under
|
||||
# `--network none` this both passes on a valid config and still rejects
|
||||
# an invalid one with the jsonschema error. Linting therefore needs no
|
||||
# network beyond pulling the pinned image.
|
||||
# an invalid one with the jsonschema error. That holds for the gate
|
||||
# steps generally — none of them makes a network call — but not for
|
||||
# this build as a whole: `go mod download` above needs the network on a
|
||||
# cold cache, and under `--network none` a first build fails there
|
||||
# before reaching any gate. That layer stays cached, so only a warm
|
||||
# cache lints offline, until go.mod or go.sum changes.
|
||||
RUN echo "gate config verify, epoch ${CHECK_EPOCH}" && \
|
||||
golangci-lint config verify --config .golangci.yml
|
||||
|
||||
|
||||
22
README.md
22
README.md
@@ -475,13 +475,21 @@ and may be invoked directly. The provided entrypoints are:
|
||||
steps, so a successful build is a clean lint. The linter is never
|
||||
run on the host, which makes a working `docker` the one
|
||||
prerequisite for linting — and therefore for `make check` and the
|
||||
pre-commit hook. Once the pinned image is local, nothing here
|
||||
needs the network: the config-schema validation used by
|
||||
`config verify` comes from a schema the pinned binary embeds, and
|
||||
was measured under `--network none` to both pass a valid config
|
||||
and reject an invalid one. Because the daemon only ever sees a
|
||||
build context, this works when the docker daemon is remote and
|
||||
bind mounts are impossible.
|
||||
pre-commit hook. Offline machines: the gate steps themselves make
|
||||
no network calls. `golangci-lint run` does not, and neither does
|
||||
`golangci-lint config verify` — it validates against a schema the
|
||||
pinned binary embeds, measured under `--network none` to both
|
||||
pass a valid config and reject an invalid one. The build around
|
||||
them does. `Dockerfile.lint` runs `go mod download` before the
|
||||
gates and this module has external dependencies, so a first lint
|
||||
on a machine with a cold BuildKit cache reaches the network there
|
||||
(as well as pulling the pinned image); under `--network none` it
|
||||
fails at that step, before any gate. That layer sits above the
|
||||
gates and stays cached, so once it is warm `script/lint` — and
|
||||
with it `make check` — runs entirely offline, until `go.mod` or
|
||||
`go.sum` changes and the download layer goes cold again. Because
|
||||
the daemon only ever sees a build context, this works when the
|
||||
docker daemon is remote and bind mounts are impossible.
|
||||
- `script/fmt` — format the Go sources in place (`gofmt -s -w`).
|
||||
Markdown is not formatted.
|
||||
- `script/fmt-check` — the read-only counterpart of `script/fmt`:
|
||||
|
||||
8
TODO.md
8
TODO.md
@@ -82,9 +82,11 @@
|
||||
concern about its unpinned live HTTPS schema fetch was measured
|
||||
rather than assumed — under `--network none` the pinned binary both
|
||||
passes a valid config and rejects an invalid one with the jsonschema
|
||||
error, so it validates from an embedded schema and linting needs no
|
||||
network; the README says so instead of claiming a requirement that
|
||||
does not exist. Verified: `make lint` green with every `PATH`
|
||||
error, so it validates from an embedded schema and makes no network
|
||||
call of its own. The README scopes that to the gate steps rather
|
||||
than to linting as a whole: `Dockerfile.lint` runs `go mod download`
|
||||
above them, so a cold cache still needs the network and only a warm
|
||||
one lints offline. Verified: `make lint` green with every `PATH`
|
||||
directory containing a `golangci-lint` removed
|
||||
(`/home/user/go/bin`, `/home/user/.local/bin`, `/usr/local/bin`;
|
||||
`command -v golangci-lint` empty); two consecutive `script/lint` runs
|
||||
|
||||
@@ -1,8 +1,19 @@
|
||||
#!/bin/sh
|
||||
# script/cibuild: run the CI build. The Dockerfile runs make fmt-check,
|
||||
# make lint and make check (via the script/ entrypoints) as build steps,
|
||||
# so a successful build implies all checks pass. The Gitea workflow runs
|
||||
# this on push.
|
||||
# script/cibuild: run the CI build. The Gitea workflow runs this on
|
||||
# push.
|
||||
#
|
||||
# The Dockerfile runs the gates individually as build steps, not the
|
||||
# make check aggregate: the lint stage runs make fmt-check,
|
||||
# script/verify-lint-image-pin, golangci-lint config verify and
|
||||
# golangci-lint run; the build stage, dropped to an unprivileged user,
|
||||
# runs make test and make fmt-check. Neither make lint nor make check
|
||||
# appears, because both reach script/lint, which is itself a docker
|
||||
# build, and a docker build cannot run inside one. Lint is not skipped
|
||||
# by that — the linter is invoked directly in the lint stage, and the
|
||||
# build stage's COPY --from=lint makes that stage a prerequisite, so
|
||||
# BuildKit must finish it first. Between the two stages everything
|
||||
# make check would run has run, which is why a successful build here
|
||||
# implies the repo is green.
|
||||
#
|
||||
# That implication holds only because of CHECK_EPOCH. A COPY layer is
|
||||
# invalidated by changed content, and a merge commit's tree is
|
||||
|
||||
@@ -4,11 +4,11 @@
|
||||
#
|
||||
# CHECK_EPOCH is passed for the same reason script/cibuild passes it:
|
||||
# without it Docker serves the Dockerfile's gate layers from cache on an
|
||||
# unchanged tree and this exits 0 having run neither the lint stage nor
|
||||
# the builder stage's make check. This is the gate a developer or
|
||||
# reviewer runs by hand, so a cached pass here is the most misleading
|
||||
# result the repo can produce. Dependency layers sit above the ARG and
|
||||
# stay cached.
|
||||
# unchanged tree and this exits 0 having run neither the lint stage's
|
||||
# gates nor the builder stage's test and fmt-check gates. This is the
|
||||
# set of gates a developer or reviewer runs by hand, so a cached pass
|
||||
# here is the most misleading result the repo can produce. Dependency
|
||||
# layers sit above the ARG and stay cached.
|
||||
set -eu
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd -P)"
|
||||
|
||||
@@ -3,8 +3,11 @@
|
||||
# host: it runs via docker only, one way, everywhere — this builds
|
||||
# Dockerfile.lint, which COPYs the repo into the digest-pinned
|
||||
# golangci-lint image and lints as a build step, so a successful build
|
||||
# is a clean lint. The only prerequisite is a working docker; once the
|
||||
# pinned image is present nothing here reaches the network.
|
||||
# is a clean lint. The only prerequisite is a working docker. The gate
|
||||
# steps make no network calls of their own, but Dockerfile.lint runs
|
||||
# `go mod download` above them, so a cold cache does reach the network
|
||||
# (as does pulling the pinned image); that layer stays cached, and once
|
||||
# it is warm this runs offline until go.mod or go.sum changes.
|
||||
#
|
||||
# CHECK_EPOCH is what makes the result mean anything. Without it docker
|
||||
# serves the gate layers from cache on an unchanged tree and this exits
|
||||
|
||||
Reference in New Issue
Block a user