Makefile entrypoints¶
The platform build, test, audit, and publishing entrypoints live in the root Makefile. The workflows call these targets instead of repeating logic in YAML. Workflow triggers and gates are in Continuous integration and Releases.
Makefile entrypoints used by workflows¶
The workflows intentionally reuse a small set of Makefile targets:
make init-workspace
make hub-assets
make test
make fuzz-go [FUZZTIME=<duration>]
make dependency-audit
make dependency-audit-python
make dependency-audit-go
make dependency-audit-npm
make dependency-audit-fix
make dependency-update-check [-python|-go|-npm]
make dependency-update [-python|-go|-npm]
make check-lockstep-version
make print-version
make publish-images IMAGE_TAG=<tag>
make publish-helm CHART_VERSION=<semver> [IMAGE_TAG=<tag>]
make publish IMAGE_TAG=<tag> [CHART_VERSION=<semver>]
make publish-develop
make release
make release-notes
make build-docs
make publish-docs
make check-docs-nav
Their roles are:
| Target | Purpose |
|---|---|
make init-workspace |
Set up the uv workspace and install test requirements. If npm is installed, also run make hub-assets. |
make hub-assets |
Install the Hub frontend packages with npm ci --ignore-scripts from hub/frontend/package-lock.json, then copy the files in hub/frontend/vendor-files.json to the Hub static/vendor directory (git-ignored). Requires Node.js 24 and network access to the npm registry. |
make test |
Run the Python test suites for core, hub, operator, and site, including Lua-backed tests, and run the Go API tests. |
make fuzz-go [FUZZTIME=<duration>] |
Run each Go fuzz target of the Site API (FuzzParseContentRange, FuzzResolveRootPath) with generated inputs for FUZZTIME. A failing input fails the target and is written to api/testdata/fuzz/. make test runs only the seed inputs. |
make dependency-audit |
Run the Python, Go, and Hub frontend dependency audits in this order. Report findings as warnings. Fail if a scan cannot run. |
make dependency-audit-python |
Export the frozen workspace lockfile and run pip-audit==2.10.1 with --disable-pip --no-deps --strict. Findings are warnings. |
make dependency-audit-go |
Run govulncheck@v1.9.0 on the Go API module. Findings are warnings. |
make dependency-audit-npm |
Run npm audit --package-lock-only on hub/frontend/package-lock.json. Findings are warnings. |
make dependency-audit-fix |
Apply targeted Python, Go module, and Go toolchain fixes, then run the Python and Go audits. Local use only; the workflows do not call it. |
make dependency-update-check |
Run the Python, Go, and Hub frontend update checks in this order. List the newer packages. Change nothing. A package with an update is not a failure; only a tool that cannot run is, and one such tool does not hide the report of the other two. Local use only; the workflows do not call it. |
make dependency-update-check-python |
List each exact pyproject.toml pin with a newer release within the cooldown, naming the file that holds it. Then run uv lock --upgrade --dry-run --exclude-newer <cutoff> and list the lockfile changes it reports. |
make dependency-update-check-go |
Run go list -m -u -json all and list each module that go.mod requires with a newer version within the cooldown. List the modules that wait for the cooldown or need a manual change separately. |
make dependency-update-check-npm |
Run npm outdated --json --before <cutoff> in hub/frontend and list each package with a newer version. |
make dependency-update |
Run the three update targets in order. Local use only; the workflows do not call it. |
make dependency-update-python |
Rewrite each pin that has a newer release within the cooldown with uv add --frozen, then apply the checked lockfile changes with uv lock --upgrade and a plain uv lock. Run make init-workspace to install the result. |
make dependency-update-go |
Apply the checked module updates with go get and go mod tidy. Never changes the go or toolchain directives. |
make dependency-update-npm |
Rewrite each exact pin in hub/frontend/package.json with npm install --save-exact --ignore-scripts, then run make hub-assets. Review hub/frontend/vendor-files.json when a copied file name changes. |
make check-lockstep-version |
Verify that the Python packages, the Helm chart version and appVersion, and the chart images.tag match VERSION. |
make print-version |
Print the version read from VERSION. publish-develop, release, and release.yml use it. |
make publish-images IMAGE_TAG=<tag> |
Build and push all container images with the provided tag. |
make publish-helm CHART_VERSION=<semver> [IMAGE_TAG=<tag>] |
Copy the chart to a local build directory, set images.tag in the copy to IMAGE_TAG (default: CHART_VERSION), lint, package, and push the chart to oci://$(SITES_PRIVATE_REGISTRY)/$(SITES_PRIVATE_REGISTRY_PROJECT). |
make publish IMAGE_TAG=<tag> [CHART_VERSION=<semver>] |
Run publish-images and publish-helm. CHART_VERSION defaults to IMAGE_TAG. |
make publish-develop |
Publish develop images and the <VERSION>-develop chart. The chart copy is set to use the develop images (images.tag is rewritten by publish-helm). |
make release |
Verify lockstep versioning, read VERSION, then publish all release images and the chart with that version. |
make release-notes |
Print the CHANGELOG.md section for the version in VERSION. Fails if the section is missing or empty. |
make build-docs |
Check the documentation navigation (check-docs-nav), then stage the docs/ pages and build them as HTML with the locked docs dependency group (Zensical). Links to repository files outside docs/ point to the source at DOCS_SOURCE_REF (default main). Needs no credentials. |
make check-docs-nav |
Fail when a page under docs/ is missing from the nav list in utilities/release/docs/zensical.toml, or a nav entry has no file on disk. Runs first in make build-docs and make publish-docs. |
make publish-docs |
Check the documentation navigation (check-docs-nav), then build the site and upload the generated HTML with sitesctl to the sites site in the docs space, at /. Needs DOCS_BASE_URL (https:// URL) and DOCS_TOKEN. It uses separate CLI settings, passes the token in the environment, overwrites files, and deletes nothing. DOCS_SPACE and DOCS_SITE change the destination. |
Helm chart versions must be SemVer. The develop image tag is not a valid
chart version, thus the develop chart uses the <VERSION>-develop
pre-release version.
Makefile variables¶
These variables tune the targets. The workflow jobs set some of them; the rest are local overrides.
| Variable | Default | Used by |
|---|---|---|
VERSION_FILE |
VERSION |
print-version, release, check-lockstep-version |
UV_PYTHON |
3.13 |
init-workspace |
SITES_PRIVATE_REGISTRY |
eccr.ecmwf.int |
image and chart publishing |
SITES_PRIVATE_REGISTRY_PROJECT |
sites-oss |
image and chart publishing |
IMAGE_PLATFORM |
linux/amd64 |
publish-images — build platform for the images |
HELM_CHART_DIR |
helm/ecmwf-sites |
publish-helm |
HELM_BUILD_DIR |
dist/helm |
publish-helm — chart copy destination |
AUDIT_RUNNER |
uv run --no-project --python $(UV_PYTHON) python |
dependency-audit targets — command that runs audit tools |
AUDIT_FIX_RUNNER |
same as AUDIT_RUNNER |
dependency-audit-fix |
UPDATE_RUNNER |
same as AUDIT_RUNNER |
dependency-update targets — command that runs utilities/release/dependency_updates.py |
DEPENDENCY_COOLDOWN_DAYS |
7 |
dependency-update targets — newest release an update may select, counted back from now. Passed to the helper in the environment. 0 allows every current release. |
FUZZTIME |
30s |
fuzz-go — time for each fuzz target (a Go duration, or <n>x for a number of inputs) |
Dependency updates¶
Dependabot updates the uv, Go module, npm, GitHub Actions, and Docker
ecosystems, and Renovate updates site/proxy.Dockerfile. Both run weekly with
a seven-day cooldown. The dependency-update targets cover the same ground on
demand, for example before a release. They use the same cooldown, so they do
not select a release that Dependabot would still hold back.
utilities/release/dependency_updates.py implements both actions for one
ecosystem:
uv run --no-project --python 3.13 python utilities/release/dependency_updates.py {check|update} {python|go|npm}
The check action runs the tool in report mode and writes nothing. The
update action runs the same tool again to apply what the report lists, so it
applies no surprise. Both actions print the release cutoff they used.
A Python dependency lives in two places. Each member pyproject.toml file pins
its direct dependencies with ==, and uv lock --upgrade cannot move such a
pin. The tool therefore reads every pin, asks uv pip compile for the newest
release that the cooldown allows, rewrites the pin in place with
uv add --frozen, and then re-locks uv.lock. The final plain uv lock
removes the cutoff that a bounded lock records in uv.lock; it changes no
version, so a later uv sync leaves the file alone. A pin that already holds
the newest allowed release is not rewritten, and a requirement with a range
keeps its range. uv add needs a package name to select a manifest, so the
tool lists a pin of the workspace file for a manual change.
An update covers dependency files only. It does not run the tests, the audits,
or the license checks, and it does not open a pull request. Docker image pins,
the declared Go go and toolchain directives, and the pinned audit tool
versions are out of scope. The Go part covers the modules that go.mod
requires. go list -m -u all also reports a module that only the module graph
needs, with no line in go.mod; an update would add such a line, and
go mod tidy would remove it again, so the tool leaves that module to the one
that asks for it. Review the diff, run make test and
make dependency-audit, then commit the result on a branch.
Release-note extraction (make release-notes →
utilities/release/changelog-notes.sh) prints the CHANGELOG.md section for
the version in VERSION. Pass a version argument to select another section,
and set CHANGELOG_FILE to read another changelog: