A command-line client
A command someone downloads and runs is the installed component kind — the
kind b itself ships as. Unlike the other kinds, nothing of ours runs at the
destination: the deploy publishes a package to a channel, and a person installs
from it. That is why the kind refuses a toolchain whose product needs a runtime
the user must install first.
kind = "installed"
links.todos = "api/todos"
absent-in = ["local", "cluster"]
The link is the whole integration. The api's languages = ["rust", "ts"] is
what makes a Rust client exist, and it is generated from the same endpoint
declarations as the page's TypeScript one, so an endpoint that changes breaks
both consumers at compile time.
Note the link names the api directly rather than the gateway. The gateway exists to turn a browser's cookie into a token; a command-line client carries its own token and has no use for it.
The variant says what it is made from and which machines it is published for:
toolchain = "cargo"
install-id = "todo"
platforms.darwin-aarch64 = { builder = "host" }
platforms.linux-x86_64 = { builder = "image", dockerfile = "tools/linux-builder" }
[dev-loop]
install-id = "todo-dev"
install-id is the name the binary takes on a PATH, and it is also the name of
the directories it keeps config and data in. The [dev-loop] block gives the
copy you are editing a different one, so a released install and a development
build coexist on one machine instead of overwriting each other — which is why
b and b-dev are separate commands in this repository.
Platforms are a promise about other people's machines
Each platform names the environment that builds it, because what a compiled
artifact demands of a stranger's machine is decided by the machine that built
it. A host builder is the machine you run the release on. An image builder is
a container, and the image you choose sets the floor: build against a new glibc
and the binary refuses to start on an older system.
A release builds every platform the variant claims, checks that each artifact
starts, and moves the channel's latest pointer only once all of them have
published. So a version at latest exists for every platform it claims, and a
machine that can only build some of them completes what it can and says which
are missing.
Two refusals when you add it
Adding this component to a working system produces two errors in turn.
The first is the rule from the previous page: a component belongs to every
environment unless it says otherwise, so absent-in is what keeps a command you
publish from one environment out of the others.
The second is that every deploy config whose environment holds an installed
component must bind an installed target — the channel the package goes to:
[deploy-configs.gcp]
environment = "gcp"
installed = "releases"
# targets.toml
[targets.releases]
kind = "installed"
upload-url = "gs://example-releases"