-
Notifications
You must be signed in to change notification settings - Fork 0
Development
Scala 3 Β· Mill Β· GraalVM. No sbt, Maven, Gradle, npm or Make β use the checked-in ./mill
launcher for everything.
| Need | Version |
|---|---|
| JDK | 21+ |
| GraalVM | 21, only for building native images locally |
| Mill | Pinned by .mill-version; the ./mill launcher fetches it |
app βββΆ cli βββΆ core βββΆ config
The graph is acyclic and core never imports CLI code.
| Module | Owns |
|---|---|
config |
YAML reading (SnakeYAML Engine), typed decoding, enum validation, rejecting installer scripts, duplicate names, unknown versionRefs, SHA-256 shape, sudo gating. |
core |
Variable and version resolution, HTTPS validation, --only/--skip selection, bounded downloads, checksum verification, archive extraction, staging and replacement, symlinks, apply state, typed installer events. |
cli |
Picocli parsing, exit codes, script-friendly output, coloured apply progress, command routing. |
app |
Process entry and exit-code propagation. Nothing else. |
Focused:
./mill config.test
./mill core.test
./mill cli.testBroad:
./mill __.compile
./mill __.test
./mill mill.scalalib.scalafmt/checkFormatAll
git diff --checkRepair formatting:
./mill mill.scalalib.scalafmt/reformatAll
β οΈ Don't pipe Mill output throughgrep,head,tailor/dev/nullβ it hides diagnostics you'll want for the follow-up fix. Stream it to a file instead:LOGFILE="/tmp/binstaller-check-$(date +%s).log" ./mill __.test 2>&1 | tee "$LOGFILE"
./mill app.run --help
./mill app.run plan --config config.example.yaml
./mill app.run apply --config config.example.yaml
./mill app.run versions --config config.example.yaml
./mill app.run lock --config config.example.yaml --output /tmp/binstaller.lock.jsonGRAALVM_HOME=/path/to/graalvm ./mill app.nativeImageNative options live in build.mill: --no-fallback, -O2,
--initialize-at-build-time=scala. Picocli reflection configuration is generated as part of the
build.
Tests use utest and never hit the network. Downloads and text fetches are injected:
- A fake
HttpTextClientreturns pinned resolver values forhttp-textversions, and routes GitHub latest-release metadata used byversions. - A fake
BinaryDownloadClientreturns bytes or a typedBinaryDownloadError. - Progress tests override
download(url, observer)and emit started / advanced / finished events before returning bytes.
Tests receive the repository root through -Dbinstaller.repoRoot, set by the build, so fixtures
can locate checked-in files such as config.example.yaml.
When adding behaviour, prefer a test at the lowest module that owns the rule β decoding rules in
config, resolution and safety rules in core, output and exit codes in cli.
core emits renderer-agnostic events; the CLI is one consumer among possible others.
ResolvingStarted Β· PlanReady Β· ToolStarted Β· ToolPhaseChanged Β· DownloadProgress
LogLine Β· ToolResult Β· ToolSkipped Β· Summary
Phases: Resolving, Planning, LoadingState, Downloading, VerifyingChecksum, Staging,
ApplyingModes, ReplacingInstall, VerifyingExecutables, CreatingSymlinks, SavingState.
If you add a phase or event, update
docs/architecture.md
in the same change.
Releases are GraalVM native binaries built by .github/workflows/release.yml, triggered by a
v* tag or a manual workflow_dispatch with a tag input.
Per target (linux-amd64, linux-arm64, macos-amd64, macos-arm64) the workflow:
- Checks out and sets up GraalVM 21 with
native-image - Runs
./mill __.test - Builds
./mill app.nativeImage - Packages
binstaller-<version>-<target>.tar.gz - Smokes native
--help,planandversions - Writes a per-file
.sha256
The publish job then re-verifies checksums, signs every artifact with keyless Sigstore
(cosign sign-blob using the workflow's GitHub OIDC identity), and publishes the release assets
including config.example.<version>.yaml and install.sh.
All GitHub Actions are pinned to commit SHAs; Mill is pinned via .mill-version.
Full detail: docs/release.md.
| Surface | Source | Published by |
|---|---|---|
| π Website |
site/ + assets/
|
.github/workflows/pages.yml |
| π This wiki | wiki/ |
.github/workflows/wiki.yml |
Terminal screenshots in assets/ are SVG renderings of real command output β regenerate them
from a real run rather than hand-editing, so the docs can't drift from the tool.
Edit wiki pages in wiki/ and open a pull request. Direct edits in the GitHub wiki UI are
overwritten on the next sync.
- Open an issue first for anything that changes the manifest contract or the CLI surface β the narrow scope is a feature, and scope changes deserve a discussion.
- Keep
corefree of CLI concerns. - Add tests at the module that owns the rule.
- Run
./mill __.testand./mill mill.scalalib.scalafmt/checkFormatAllbefore pushing. - Update the relevant
docs/page in the same change.
- π Home
- π Getting Started
- ποΈ CLI Reference
- π³ Manifest Cookbook
- π§ Lock Files
- π Security Model
- π©Ί Troubleshooting
- β FAQ
- π οΈ Development