CI: add build + test + bootstrap-cfree workflows (currently only docs runs) #32
Labels
No labels
area:ci
area:docs
area:input
area:net
area:rendering
area:repo
area:stdlib
area:tooling
area:types
cleanup
dx
priority:high
priority:low
priority:medium
proposal
status:in-progress
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: workshopsoft/ludic#32
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Problem
The repo has no CI that builds or tests the language. The only workflow is
.forgejo/workflows/docs.yml, which regenerates the docs site. That means:bin/x test(the regression suite that builds thecompiler, compiles/runs examples, checks save/load + diagnostics).
bin/x bootstrap-cfreerebuilds the compiler fromthe IR seed with no C compiler and reproduces its own IR byte-for-byte — is
never verified automatically. A regression here is invisible until someone runs
it locally.
ludic-fmt), notest-toolsrun.Proposal
Add Forgejo Actions workflows (matching the existing
runs-on: dockerrunnerconvention already used by
docs.yml):ci.ymlon PRs + pushes tomain:bin/x test(examples + save/load + diagnostics),bin/x test-tools(fmt idempotence + LSP traffic),ludic-fmtcheck (fail if formatting would change source).bootstrap.yml: runbin/x bootstrap-cfreeand assert the rebuiltcompiler reproduces
selfhost/ludicc.seed.llbyte-for-byte (the C-free +fixpoint guarantee).
Acceptance criteria
test+test-toolspass.docker).Part of the repository-cleanup / DX pass.
Done in
1c1192e— and verified on the live runner: both new workflows went green on the push (build-and-test✓,cfree-fixpoint✓).The wrinkle worth recording: the toolchain is macOS-first. The self-hosted compiler emits the Darwin libc standard-stream globals
@__stdoutp/@__stderrp, which is the single thing that stops its IR from linking on Linux — everything else (the seed, the whole self-compile, the byte-for-byte fixpoint) is host-neutral. The Forgejo runner is a Linuxdockerexecutor, and no macOS runner is registered, so rather than block on that I bridged the one gap with a C-free LLVM-IR shim (tools/ci/linux_stdio_shim.ll) that defines the Darwin-named globals over glibc'sstdout/stderrand is injected into every clang link throughLUDIC_CC. No C compiler enters the picture — the no-C guarantee holds.Workflows (both on
runs-on: docker, reusing the runner'snode:20-bookwormbase +clang-16/python3):ci.yml— bootstrap the toolchain from the seed, thenx test+x test-tools+ the docs-cover-the-implementation checks, on pushes tomainand PRs.bootstrap.yml—x bootstrap-cfree: asserts the seed rebuilds itself byte-for-byte (non-zero exit on drift). This is the guarantee the issue flagged as "never verified automatically" — it now is, on every push and PR.Acceptance criteria:
test+test-tools.ludic-fmtidempotence (fmt(fmt(x)) == fmt(x), already inx test-tools). Note: I deliberately did not add a strictfmt(x) == xgate — this codebase keeps hand alignment on purpose (there's even a "hand alignment preserved" fmt test), so--checkwould fight that contract and fail on current source.docker).Honest scope note: to keep a Linux run green without hiding anything, the cases that are genuinely macOS-ABI bound now print a visible
skipoff Darwin rather than fail — the Cocoa-windowedludicc -olink, the golden render hashes (blessed on macOS; text raster differs by a hair elsewhere), theOsknown-folder/uname surface, andFs.list+ the LSP workspace walk (both read the BSDdirentlayout). On macOS every one still runs (suites stay 56 / 29 / 29 green); on Linux they run 51 / 28 (+skips), bootstrap-cfree byte-identical on both. Making those runtime pieces portable (a Linuxdirent/utsnamepath, a non-Cocoa window backend) is a proper platform-port effort and deserves its own issue.Follow-up already noted in the workflow comments: a prebuilt CI image with
clang-16/python3baked in would shave the per-runapt-get(ties into #33's packaging).