Command Surface
An identical root Makefile in every repository, with the repository’s own components declared once in scripts/build/repository.mk.
- Kind
- Architecture
- Domain
- Environment & Tooling
- Applies at
Makefile- Status
- Stable
- Source · managed
Makefile
01 Defines
The repository’s stable set of make commands: a generic, managed root Makefile that loads repository configuration and then a fixed sequence of make modules, so the same verbs work the same way in every repository.
02 Applies when
- Developers, CI workflows, and agents need one predictable way to build, check, and deploy.
- Several repositories should share commands without sharing their component lists.
- Shared make modules are provided by the development environment as well as by the repository.
03 Boundaries
- The root
Makefilecontains no repository-specific targets or paths. - Which components exist is declared in
repository.mk; nothing is discovered. - Make orchestrates; larger behaviour lives in scripts the targets call.
Expected behaviour
- 01The root
Makefileis byte-for-byte the same in every repository and is never edited locally. - 02
repository.mkdeclares concrete components such asHUGO_DIRS,TERRAFORM_DIRS, andLINT_COMMAND. - 03Modules load in
MAKE_MODULE_ORDER; each resolves from library directories first, thenscripts/build/. - 04A module missing from every directory is simply not loaded.
- 05Running
makewith no target prints the generated help.
Behaviour#
The command surface is what a developer or workflow actually types: make doctor, make build, make validate, make lint, make deploy. Behind it,
the root Makefile does only three things — it finds the repository root, reads
repository.mk, and includes each module in a fixed order.
- 01
Root
REPO_ROOTfrom theMakefile’s own location - 02
Configure
Include
scripts/build/repository.mk - 03
Resolve
For each name in
MAKE_MODULE_ORDER, the first<name>.mkacross the library and repository directories - 04 Include Load the resolved modules in order Make Module Registries
How the modules then contribute targets without editing each other is the Make Module Registries pattern.
Library and repository modules#
Module lookup searches MAKE_LIBRARY_DIRS — ~/.mklib/make and the usual
system share and lib locations — before the repository’s own
scripts/build/. A module can therefore be installed once by the
Development Container
and shared, or carried in the repository.
The order is fixed either way, and a name found nowhere is skipped, because
wildcard returns nothing for it.
Examples#
MAKE_MODULE_DIRS := $(MAKE_LIBRARY_DIRS) $(MAKE_REPO_MODULE_DIR)
MAKE_MODULE_ORDER := 00-config 10-help 20-doctor 30-repo 40-docs 52-hugo 53-terraform 60-scripts 70-security 80-artifacts 81-deploy 90-aggregates
include $(MAKE_REPO_CONFIG)
define resolve_make_module
$(firstword $(wildcard $(foreach dir,$(MAKE_MODULE_DIRS),$(dir)/$(1).mk)))
endef
This repository has no 60-scripts or 80-artifacts module, and the surface
works without them.
HELP_START := Start here: make doctor (check tools), make check.hugo (build site), make help (all targets)
HUGO_DIRS := www/specifications
HUGO_PREPARE_COMMAND := node scripts/docs/prepare-site-content.mjs
TERRAFORM_DIRS := workspaces/site env/staging/release env/prod/release
LINT_COMMAND := bash "$(REPO_ROOT)/scripts/lint.sh"
Connections