Offline Validation
Networked setup hydrates the workspace once; validation then runs with OFFLINE=1 and never quietly re-downloads anything.
- Kind
- Orchestration
- Domain
- Environment & Tooling
- Applies at
scripts/build/- Status
- Stable
01 Defines
A split between a networked prepare phase that installs, restores, and downloads, and a validation phase that only reads what is already present, switched by a single OFFLINE make variable.
02 Applies when
- A validation step would otherwise fetch something — Terraform providers, TFLint plugins, package dependencies.
- CI hydrates the workspace in one phase and validates in a later one.
- A developer needs
make validateto work without network access.
03 Boundaries
OFFLINE=1skips network steps; it does not provide what they would have fetched.- Dependency installation itself belongs to the dev container and the prepare phase, not to validation targets or ad hoc scripts.
- Offline mode never turns a real validation failure into a pass.
Expected behaviour
- 01
OFFLINEdefaults to0in00-config.mk, so a plainmake validatebehaves normally on a connected machine. - 02Every step that needs the network checks
OFFLINEand, when it is1, prints askip:line instead of downloading. - 03Steps that need no network still run under
OFFLINE=1against whatever the prepare phase left behind. - 04Validation initialises Terraform with
-backend=false, so it needs no credentials either way.
Behaviour#
Validation is most useful when it is reproducible: the same inputs give the
same result, and nothing changes underneath it mid-run. A target that re-runs
terraform init or tflint --init as a side effect quietly depends on the
network and on whatever the registry serves that minute.
The repository separates the two concerns. Getting dependencies onto the
machine is setup — the dev container’s lifecycle hooks locally, a prepare phase
in CI. Validation then runs against the hydrated workspace, and OFFLINE=1
tells every module that the network is off-limits.
- 01 Prepare Lockfile restores, provider and plugin downloads; network allowed Update-Content Phase
- 02
Hydrated
.terraform/,.cache/tflint, andnode_modules/are on disk - 03
Validate
make validate OFFLINE=1— network steps printskip:and the checks run Explicit Skips
The default is OFFLINE=0. In that mode the Terraform module clears each
root’s .terraform/ and re-initialises it before validating, which is what a
fresh checkout wants. The 00-config.mk comment describes the CI intent:
OFFLINE is set once the prepare phase has hydrated the workspace, “so
validation never silently re-downloads dependencies”.
What the switch changes#
| Step | OFFLINE=0 | OFFLINE=1 |
|---|---|---|
check.terraform.validate | Remove .terraform/, init -backend=false, validate | skip: offline Terraform init (<dir>), then validate |
check.terraform.lint | tflint --init, then lint each root | skip: offline TFLint plugin init, then lint |
check.terraform.fmt | Format check | Unchanged — needs no network |
check.hugo, check.links | Build and check | Unchanged |
Keeping setup out of validation#
The scripts standard keeps “networked setup separate from offline validation”
and keeps “dependency installation and long-running setup out of ad hoc
scripts”. Make targets use the environment rather than create it: the Node
tooling is restored by an update-content.d/ hook, CI tools by
scripts/ci/setup-ci-toolchain.sh, and validation targets only consume them.
Examples#
The validate recipe, reflowed from its single line for reading:
if [ "$(OFFLINE)" = "1" ]; then
printf 'skip: offline Terraform init (%s)\n' "$$dir"
else
rm -rf -- "$$dir/.terraform"
terraform -chdir="$$dir" init -backend=false -reconfigure
fi
terraform -chdir="$$dir" validate
Locally, the switch is a make variable like any other:
make validate # downloads providers and plugins as needed
make validate OFFLINE=1 # uses what is already on disk
Connections