Monitor, build, and compare the health of all MoonBit packages published on mooncakes (MoonBit's package registry) plus a curated set of Git repositories. The dashboard tracks buildability across OS (Linux / macOS / Windows), backend targets (wasm / wasm-gc / js / native), and channels (stable vs nightly) to surface regressions and inconsistencies quickly.
- Enumerates every MoonBit package from the local mooncakes index (
~/.moon/registry/index/user). - Applies per-package overrides from
resources/repos.ymland exclusion rules fromresources/exclude.yml. - Clones configured GitHub repos and downloads mooncakes package archives.
- Runs a matrix of
moon check,moon build,moon test(test currently build-only) across selected backends & OS. - Captures stdout/stderr, timing, success/failure per command/backend.
- Writes structured line-delimited JSON (
.jsonl) for later rendering in the web UI. - Compares nightly vs stable channel results and labels:
regression– nightly failed but stable succeeded (potential toolchain regression)inconsistent– results differ across platformsok– consistent success or uniformly skipped
| Layer | File(s) | Responsibility |
|---|---|---|
| CLI parsing | lib/cli.ts |
Parse args (--channel, --repos, --exclude, --only). |
| Source discovery | lib/core.ts#getMooncakeSources |
Merge mooncakes index + repos config + exclusions. |
| Mooncakes index access | lib/mooncakesio.ts |
Read local index, filter out test-only packages, discover versions. |
| Download / clone | lib/mooncakesio.ts#downloadTo, lib/git.ts |
Fetch package zip or clone git repo at rev. |
| Execution wrapper | lib/moon.ts#runMoon |
Run moon commands with timeout & capture output. |
| Build matrix | lib/core.ts#runMatrix |
Execute check/build/test for each backend on current OS. |
| Result aggregation | lib/core.ts#stat |
Collect metadata (run id, toolchain version, timestamps). |
| Type system / schemas | lib/types.ts, schema.ts |
Zod schemas, JSON schema emission. |
| Web UI | web.ts + index.html |
Render table, fetch published .jsonl artifacts, classify results. |
Each output file: data/{os}-{channel}.jsonl
First line: Metadata object:
{
"runId": "<CI_RUN_ID>",
"runNumber": "<CI_RUN_NUMBER>",
"startTime": "2025-10-20T00:00:00.000Z",
"toolchainVersion": ["moon <version lines>"]
}Subsequent lines: BuildResult objects:
{
"source": {"type": "mooncakes", "name": "foo", "version": "1.2.3"},
"cbt": {
"check": {"wasm": {"status": "Success", "elapsed": 123, ...}, ...},
"build": { ... },
"test": { ... }
}
// or "error": "Unable to download"
}Skipped backends/commands use {"status": "Skipped"}.
Previously each Result embedded full stdout and stderr strings directly in the JSONL, producing very large files
and slow initial page loads.
Now logs are written to separate files under data/logs/ and the JSONL stores lightweight path references:
The file name uses a SHA-256 hash (first 16 hex chars) of the tuple (type, sourceId, command, backend) to keep names
short yet unique:
<hash>.out.log
<hash>.err.log
Frontend behavior: when you click a cell the UI fetches these two log files on demand instead of constructing a Blob from embedded strings. This reduces bandwidth and speeds up initial render.
Benefits:
- Much smaller
data/*.jsonlartifacts. - Browser/CDN can cache individual log files.
- Faster initial dashboard load with lazy log fetching.
Future migration script (planned): deno run -A scripts/migrate-logs.ts <old.jsonl> <new.jsonl> will extract embedded
logs from older artifacts into data/logs/ and rewrite each line with path references.
If a log file is missing or fetch fails, the UI displays a clear error message in the opened tab.
resources/repos.yml– whitelist of GitHub repos and mooncakes overrides (OS/backends/version pinning).resources/exclude.yml– list of mooncakes to skip globally.schema.ts– emits JSON Schemas:resources/repos.schema.json,resources/exclude.schema.json.
Run schema generation:
deno run -A schema.tsgithub-repos:
- name: corelib
link: https://github.com/moonbitlang/corelib
branch: main
running_os: [linux, macos]
running_backend: [wasm, native]
mooncakes:
- name: foo
version: 1.2.3
running_os: [linux, macos, windows]
running_backend: [wasm, wasm-gc, js, native]Requires the MoonBit toolchain (moon executable) in PATH and populated ~/.moon/registry/index/user.
Stat run (default channel=stable):
deno run -A main.ts stat --channel nightly --repos resources/repos.yml --exclude resources/exclude.ymlGenerates: data/<os>-<channel>.jsonl for the current OS only. (CI runs across all OS variants.)
--channel stable|nightly– choose toolchain channel under test.--repos PATH– repos configuration file (defaultrepos.yml).--exclude PATH– exclusion list (defaultexclude.yml).--only– only process entries explicitly listed in repos.yml (skip full index scan). Useful for debugging.
The analyze.ts helper can scan a produced file and print slow (>1000ms) or failing tasks:
deno run -A analyze.ts data/linux-nightly.jsonlExample output lines:
failed https://github.com/... - build - wasm
slow [email protected] - test - native - 2150ms
The frontend (web.ts) bundles to web.js and fetches published artifacts (e.g. from GitHub Pages). It:
- Merges per-source results across all (OS, channel) combinations.
- Computes a per-source label (
regression,inconsistent,ok). - Provides per-cell click to open raw logs (stdout/stderr + timing) for a specific command/backend.
Dev bundle (watch):
deno task devEach moon command is wrapped with a 60s timeout to avoid hanging builds/tests. Test runs use --build-only to prevent
potentially long-running suites.
For each platform: if nightly fails while stable succeeds → mark regression. If mixed success/failure exists across platforms within a channel → inconsistent.
- Line-delimited JSON allows streaming parse in web UI and incremental processing.
- Separation of source discovery and build execution keeps logic modular.
- Zod schemas ensure config validation early and enable automatic JSON Schema generation.
- Stateless execution: each source builds in a fresh temp dir, avoiding cross-contamination.
- Missing
moonbinary → install MoonBit toolchain first. - Empty index → ensure you have fetched packages (
moon updateto sync registry). - Lots of
Skippedstatuses → current OS not in packagerunning_os; check overrides inrepos.yml. - Timeout failures → inspect logs; consider increasing timeout logic if legitimately long builds.