Which jadpo runs
On this page
A project is written for one release line of Jadpo, such as 0.1, and
while Jadpo is at 0.x a minor release may break an app. So the jadpo
that runs a command is the one the project names, whatever you have
installed. You don't do anything for that.
The jadpo you install (Homebrew, the npm package @jadpo/jadpo, or the
shell or PowerShell installer) is a whole jadpo that can also start
another release, as the go command does. Before a command runs, it
finds the project: the folder you run it from, walked up to app.jadpo,
or else the first argument that names a file or folder in a project. It
reads the line from application { jadpo: "0.1" }
(The root).
When the project is on the installed jadpo's own line, or names no
line, the installed jadpo runs the command. Otherwise it runs the
release the project needs, in the same folder and with the same
arguments, and exits as that release does. It picks:
- the release
jadpo.lockpins, if there is one (see "Pin a release" below); - else the newest release of the line it already keeps;
- else the newest release of the line published on GitHub, which it fetches once.
A project on the installed jadpo's own line runs with that jadpo, so
a newer patch of the line is used once you install it, or pin it.
Outside a project there is no line to read, so jadpo new,
jadpo --version, jadpo help and every other command run with the
installed version. The VS Code extension runs jadpo lsp from the
project's folder, so it gets the project's release with no setting.
Fetching a release
A release comes from github.com/jadpo-dev/jadpo's releases, and is kept
in jadpo/releases/<version>/ in your cache folder: $XDG_CACHE_HOME,
else ~/.cache, else %LOCALAPPDATA% on Windows. Nothing is written
anywhere else, and two commands that need the same release at once fetch
it once.
Nothing in a download runs until it passes two checks. Its SHA-256 has to
be the one the release publishes beside it. Its GitHub artifact
attestation has to verify too: that is a signed record, kept by GitHub
and Sigstore's public log, saying this repository's release.yml built
that archive at the release's tag. jadpo checks it with Sigstore's own
verifier against the trusted root it carries. A download that fails
either check is refused, and nothing is kept.
While it fetches, stderr shows a live line, Fetching Jadpo 0.2.3 for aarch64-apple-darwin, with a bar once the archive's size is known, or
that line once where stderr doesn't animate. Then it says what it got,
and the command's own output follows:
✓ Fetched Jadpo 0.2.3 (24.1 MB) and checked its SHA-256 and attestation in 2.3 sUnder --json, nothing is written but the command's own document.
The releases kept
| Command | Does |
|---|---|
jadpo toolchain (or list) |
Lists the releases kept, newest first, with each one's size |
jadpo toolchain remove <version> |
Deletes a kept release |
Both take --json, and both always run with the jadpo you installed,
since they look after its cache. A release you remove is fetched again
the next time a project needs it.
Pin a release
Pin the exact release a project runs with when its builds must be reproducible:
| Command | Does |
|---|---|
jadpo toolchain pin |
Writes the release the project runs with into jadpo.lock |
jadpo toolchain unpin |
Takes the pin out again |
The pin is the lock's first line, jadpo version 0.1.2
(What is committed).
pin runs as the project's release, so that is the release it writes.
Commit the lock with the code. A pin on another line than jadpo: names
is out of date, record.out_of_date, until jadpo toolchain pin writes
it again.
Run your own build on every project
People working on the compiler set JADPO_TOOLCHAIN=local, so the
jadpo they start runs every command itself, whatever line the project
names. A project on another line is then refused by jadpo check, with
the errors below.
When the release can't be run
When jadpo can't run the release a project needs, because it is offline
with nothing kept, the line has no release yet, or a download fails its
checks, it stops. It never compiles the project itself. The error names
the release to install, says why it couldn't be fetched, and gives the
next step for that cause. It is toolchain.version_newer when the
project needs a later release than this one, and
toolchain.version_older when it needs an earlier one.
What a release must keep, for older launchers
Every jadpo ever installed goes on running the releases later projects
name, so it fetches them by what it was built knowing. These are a
contract with every installed jadpo, and changing any of them is a
breaking change to all of them. A test pins each
(crates/jadpo-cli/src/launcher.rs, contract), so a change fails the
gate pointing here.
- The line.
application { jadpo: "X.Y" }inapp.jadpo, thejadpo:member of theapplicationsingleton with its value a string of two numbers, read on its own without the rest of the project (jadpo_check::jadpo_version::declared). Anyapp.jadpoa later release accepts must still put the line there in that form. - The pin. A
jadpo version X.Y.Zline injadpo.lock, a release with no pre-release, read without the rest of the lock. - Where releases are. GitHub Releases of
jadpo-dev/jadpo, taggedvX.Y.Z, each archive athttps://github.com/jadpo-dev/jadpo/releases/download/vX.Y.Z/jadpo-cli-<target>.tar.gz,.zipforx86_64-pc-windows-msvc, for each targetdist-workspace.tomlnames; a target dropped from it can never run a later release. - The SHA-256 and the archive.
<archive>.sha256beside it, its first word the archive's SHA-256 in hex (sha256sum's form); inside the archive,jadpo(jadpo.exeon Windows) at its top or in its one folder,jadpo-cli-<target>/. Nothing else in the archive is used. - The attestation. A GitHub artifact attestation of the archive's
digest on Sigstore's public-good instance, whose certificate GitHub
Actions issued to
https://github.com/jadpo-dev/jadpo/.github/workflows/release.yml@refs/tags/vX.Y.Z: the repository, the workflow's path and its run at the tag (release-please starts it with--ref "$TAG"). Renaming the repository or the workflow, or running it on a branch, makes every installedjadporefuse the release. - Finding a line's newest release. GitHub's API without signing in,
https://api.github.com/repos/jadpo-dev/jadpo/releases?per_page=100, pages of 100 up to ten, reading each release'stag_name,draftandprerelease; and/attestations/sha256:<digest>for the attestation, itsattestations[].bundle. GitHub allows 60 such requests an hour from one address. A fetch takes two or three, and a kept release none, so the limit is met only on a shared address such as CI's. When it is met, the error says GitHub's API refused it for that limit and to run the command again in an hour; nothing is fetched or kept. - The handshake. A release a
jadpostarts getsJADPO_TOOLCHAIN_LAUNCHEDset to its own version and runs the command itself when that is its version, so it never hands the command on again;JADPO_TOOLCHAIN=localruns everything with thejadpostarted. The command line reaches the release whole, before any of it is read, so a command or flag a later release adds works through any launcher. - The cache.
jadpo/releases/<X.Y.Z>/jadpoin the user's cache folder, written whole by a rename under.<X.Y.Z>.lock; a folder there is a release that was checked. - The trusted root. Each
jadpochecks attestations against the Sigstore trusted root it was built with, without refreshing it. After Sigstore rotates a key that signs GitHub's attestations, older launchers refuse releases signed with the new key: the error says Jadpo X couldn't be fetched to run it because its archive's attestation doesn't verify, and to run again, then to install the newestjadpo, whose trusted root may be newer, if it fails the same way. Installing ajadpobuilt after the rotation is the fix, and its release notes say so.
Markdown for agents: /docs/which-jadpo-runs.md.Built from Jadpo main at a707efb.