Mise tasks
Everything here is built, tested and linted through Mise ⧉ monorepo tasks.
mise run //croesus:build # one task in one project
mise run '//...:lint' # that task in every project defining it
mise tasks --all # everything available
Run a bare task name from inside a project directory, or address any project from anywhere with
//<project>:<task>. Quote the wildcard, or the shell globs it.
Rules: build rules. The tool itself, and the mise/tasks/ trap:
Mise.
Where a task comes from
| Piece | Holds |
|---|---|
mise/includes/{go,python}.toml |
the task definitions, once per language family |
mise/includes/{go,python}-service-image.toml |
the container-image tasks |
mise/scripts/*.bash |
the logic every task body calls |
<project>/mise.toml |
the includes, and the project's identity |
root mise.toml |
tool pins, [env], and config_roots |
Shared configuration lives in the root mise.toml because an [env] block inside an include is a
parse error: Mise reads it as a task named env.
Go projects
Via mise/includes/go.toml.
| Task | Does |
|---|---|
proto |
Generate Go protobuf sources. A fast no-op where there is nothing to generate |
build |
Generate protobuf, then build every cmd/ binary natively and for amd64 |
install |
Copy the amd64 binaries into infra/build_artifacts/bin/amd64/ |
lint |
gofmt -s -l, go vet and golangci-lint, against the repository .golangci.yml. All three run, and every finding is reported |
format |
gofmt -s -w . |
test-fast |
go test -short -race |
test-integration |
testsintegration/ only, caching disabled |
test-all |
Both test tasks |
clean |
Remove generated protobuf files and build artefacts |
- Test tasks do not depend on
build.go testcompiles what it needs, and the dependency would double the compile under--jobs. - On amd64 Linux,
buildhard-links the native binaries intobuild/amd64/instead of compiling twice. Hard links, not symlinks (the Make rules do the same): same tree, same filesystem, so the link always succeeds and is a real directory entry. installhandles amd64 only. Nothing wrote or readbin/native/. It does not clear the directory first: a--jobsrun has several projects writing there at once, and binary names are distinct across the repository.buildandinstallstay separate.installaggregates each project's output into one flat directory keyed by binary name. That is the shape Ansible andrelease-infra-deploy.ymlresolve against.- An unstamped binary reports
unknown, not empty.go-env.bashfalls back whengit rev-parseis unavailable, which is every container build.
Python projects
Via mise/includes/python.toml.
| Task | Does |
|---|---|
lint |
ruff format --check, ruff check and ty check, from the repository root |
format |
ruff format and ruff check --fix |
test-fast |
pytest over the project's tests/. Skips cleanly where there is none |
test-all |
test-fast. There is no Python integration suite yet |
build |
Build wheels for native and amd64 Linux. Nothing without a [build-system] |
install |
Copy the wheels into infra/build_artifacts/wheels/amd64/ |
install is local. Publishing is a separate task
Neither build nor install touches a registry. Publishing is always its own named task,
normally run by CI: push-image for container images, and nothing yet for binaries and wheels,
which is tracked debt. See
BUILD-8.
build and install serve the Python services Ansible deploys onto VMs: the copy_python_wheels
role installs the gateway's wheel. Python service images build through sync-venv instead.
Container images
Via mise/includes/{go,python}-service-image.toml.
| Task | Does |
|---|---|
build-image |
Build this service's image from the shared Dockerfile for its family |
push-image |
Build, then push to the service's repository. Skips a pushed commit |
sync-venv |
(Python) Sync the venv the image runs from. Called by the Dockerfile |
A service declares only DOCKER_PROJECT_DIR/DOCKER_IMAGE_NAME/DOCKER_BINARY (Go) or
DOCKER_PACKAGE/DOCKER_IMAGE_NAME (Python). mise/scripts/docker-env.bash derives the region,
repository, Dockerfile, tag, version stamp and build arguments, so mise run '//...:push-image'
needs no per-service parameters. The caller supplies DOCKER_GCP_PROJECT.
Base images and pins
Under //infra/docker:
| Task | Does |
|---|---|
repin-base-images |
Rewrite our base-image digests in every file naming them |
open-base-image-repin-pr |
Repin, then open the pull request |
check-image-pins |
Static: every copy of a digest agrees, Python base tag matches .python-version |
check-pinned-tags |
Pull each pinned image, confirm the tag beside it is honest |
//infra/docker/go-service:check-base-image |
Confirm the pinned builder matches mise.lock |
check-image-pins runs in pre-commit. check-pinned-tags needs a registry, so it runs in
check-image-pins.yml.
GitHub repositories
Under //infra/terraform/github. See GitHub repositories.
| Task | Does |
|---|---|
check-inventory |
Validate infra/inventory/repositories.yaml and responsible against people/ |
lint-terraform |
Format-check, validate and tflint the unit and its module, offline |
lint |
check-inventory, ruff on the check script, and lint-terraform |
format |
ruff and terraform fmt, the mutating twin of lint |
plan |
Compare the repositories on GitHub with the inventory, through neph |
apply |
Update GitHub to match the inventory, through neph. Prompts first |
lint-terraform and format call mise/scripts/terraform-lint.bash and terraform-format.bash.
Both take the unit from the working directory and the environment from LYC_DEPLOY_ENV, so any
Terragrunt unit can adopt them. plan and apply authenticate through gh auth login, or as a
GitHub App through GITHUB_APP_*.
Platform state bucket
Under //infra/terraform/platform/state_bucket. One unit for every platform project. DO name
the environment: LYC_DEPLOY_ENV=platform-staging mise run //infra/terraform/platform/state_bucket:apply.
See bootstrapping platform images.
| Task | Does |
|---|---|
lint-terraform, lint |
Format-check, validate and tflint the unit and its module, offline |
format |
Format the unit and its module |
bootstrap-backend |
terragrunt backend bootstrap. The bare bucket, in the env file's location |
plan |
Compare the bucket with the reference settings |
apply |
bootstrap-backend, then adopt the bucket and set the rest |
Staging service images
Also under //infra/docker:
| Task | Does |
|---|---|
push-staging-images |
Build and push every staging service image, or the project dirs given, then repin |
repin-staging-images |
Rewrite the digest pins in staging.env from the recorded digests |
pin-staging-images |
Rewrite the digest pins in staging.env to the registry's images for one commit |
list-staging-images |
List the newest commits' images and every pinned image, and mark the pinned ones |
A pin whose image was not pushed does not move. pin-staging-images <commit> <service>... moves only
the named pins, by directory or image name. It fails instead if one has no image for that commit. See
Deploying staging for the promotion steps.
Infrastructure and repository tasks
| Task | Does |
|---|---|
//infra/ansible:env |
Install Ansible collections |
//infra/ansible:lint |
Lint, failing on warnings as CI does |
//infra/ansible:format |
Format and auto-fix |
//infra/k8s:build |
Render an overlay to stdout (--env, defaults to devel) |
//infra/k8s:apply / :delete |
Render and apply or delete. --env required |
//infra/neph:deploy-staging |
Apply the staging service units with neph terraform |
//infra/neph:move-state |
Move a unit's state to the backend it names now, with neph |
//people:list-emails |
List addresses, optionally filtered by group |
//people:import-keys |
Import and ultimately trust every GPG key |
//mise:lint |
shellcheck over the shared bash |
//docs/wiki:build |
Build this wiki into docs/wiki/site/. Needs Graphviz's dot |
//docs/wiki:serve |
Serve this wiki with live reload on localhost:8000 |
//docs/wiki:deploy |
Upload site/ to Cloudflare Pages. --branch required |
//infra/k8s:build takes a default environment so a '//...:build' sweep can include it. apply
and delete do not: an unnamed environment must never be applied.
Related
- Build rules
- Mise: installing it, adding a tool, the
mise/tasks/trap