Guide
CI/CD Pipeline
Complete build pipeline for the Land code editor - stages from environment variable resolution through binary artifact production, profile system, artifact layout, and automation details.
The complete build pipeline for the Land code editor, from environment variable resolution through binary artifact production. The pipeline coordinates Rust, TypeScript, and static asset compilation across 15+ component workspaces.
Pipeline Overview
The Land build has six stages:
- VS Code platform compile - produces the compiled JavaScript platform code
- TypeScript build -
pnpm prepublishOnlyfor Wind, Cocoon, Output, Sky, Worker - PreBake - walks extension roots, writes
extensions.manifest.json - Rust build -
cargo build -p Mountain - Tauri bundle -
pnpm tauri build - Re-sign - strips quarantine bits and re-applies entitlements
sequenceDiagram
participant Env as .env.Land files
participant BS as Maintain/Debug/Build.sh
participant S1 as Stage 1: VS Code
participant S2T as Stage 2: TypeScript
participant S3 as Stage 3: PreBake
participant S4R as Stage 4: Rust
participant S5 as Stage 5: Tauri bundle
participant S6 as Stage 6: Re-sign
participant App as Land Application
Env->>BS: Export 18 env files across 6 domains
BS->>S1: Invoke npm install + npm run compile
BS->>S2T: Invoke pnpm prepublishOnly (ESBuild / Vite / Astro)
BS->>S4R: Invoke cargo build -p Mountain
S4R->>S5: pnpm tauri build
S5->>S3: beforeBundleCommand triggers PreBake
S3-->>S5: extensions.manifest.json written
S5->>S6: BundleLevel=debug sh Maintain/Script/SignBundle.sh
S1-->>S4R: Compiled platform code
S1-->>S2T: Compiled platform code
S4R->>App: Native backend (Mountain, Echo, Mist, etc.)
S2T->>App: Frontend bundles (Sky, Wind, Cocoon)
S6->>App: Correctly-entitled .app bundleStage 1: VS Code Platform Compilation
The VS Code source is vendored as a Git submodule at Dependency/Microsoft/Dependency/Editor. This stage produces the compiled JavaScript platform code that Cocoon and Sky consume.
Important
This step is a mandatory prerequisite for every Land build. You must be on Node 24 (tracked in .nvmrc).
cd Dependency/Microsoft/Dependency/Editor
nvm use 24
git fetch --all
git reset --hard Parent/main
git clean -dfx
pnpm install
pnpm run compile
pnpm run compile-extensions-buildThe compile-extensions-build step produces out-<platform> directories containing compiled extension JavaScript and metadata. These are consumed by Output for bundling into @codeeditorland/output.
Stage 2: Land Application Assembly
Stage 2 compiles the native Rust backend and bundles the TypeScript frontend into a runnable Tauri application:
cd Land
export Trace=all Record=1 Disable=false
./Maintain/Debug/Build.sh --profile debug-electron-bundledThe build script invokes, in sequence:
TypeScript build (
pnpm prepublishOnly) - Output, Cocoon, Worker, Wind, Sky- Output artifact bundling via ESBuild for VS Code platform code
- Cocoon compilation via ESBuild for the extension host
- Worker compilation via ESBuild for the service worker
- Wind + Sky compilation via Vite/Astro for the UI layer
PreBake - runs via
beforeBundleCommandinsidetauri.conf.json; walks extension roots and writesextensions.manifest.json. Fires in all build paths (directpnpm tauri build,Build.sh, CI). Consumed byLoadFromCache.rsat boot (<50ms vs ~1200ms live scan).Rust workspace compilation via
cargo build -p MountainTauri bundling for the final
.appbundleRe-sign - strips macOS quarantine bits with
xattr -cr, then re-signs withcodesign --force --deep --sign -plusEntitlements.plist:BundleLevel=debug sh Maintain/Script/SignBundle.sh
Environment Variable System
Land uses a multi-file .env system with 18 files across 6 domains.
File Discovery
The build script resolves env files in this priority order:
$Land_Env_File(if explicitly exported).env.Land(local gitignored overrides)../.env.Land(one level up).env.Land.Sample(checked-in defaults)../.env.Land.Sample
The resolved file is sourced via set -a; . "$EnvFile"; set +a, exporting every key-value pair into the shell environment so every child tool inherits the same variable set.
File Hierarchy by Domain
| Domain | Suffix | Dev File | Sample File | Production File |
|---|---|---|---|---|
| Core | (none) | .env.Land | .env.Land.Sample | .env.Land.Production |
| Node | .Node | .env.Land.Node | .env.Land.Node.Sample | .env.Land.Production.Node |
| Extensions | .Extensions | .env.Land.Extensions | .env.Land.Extensions.Sample | .env.Land.Production.Extensions |
| PostHog | .PostHog | .env.Land.PostHog | .env.Land.PostHog.Sample | .env.Land.Production.PostHog |
| Diagnostics | .Diagnostics | .env.Land.Diagnostics | .env.Land.Diagnostics.Sample | .env.Land.Production.Diagnostics |
| Bundled | .Bundled | .env.Land.Bundled | .env.Land.Bundled.Sample | .env.Land.Production.Bundled |
Profile-to-File Mapping
Each build profile loads a specific combination of env files:
| Profile | Files Loaded | Purpose |
|---|---|---|
| Development | .env.Land | Default local development |
| Development + Bundled | .env.Land + .env.Land.Bundled | Dev with pre-compiled workbench |
| Development + Extensions | .env.Land + .env.Land.Extensions | Dev with extension installation |
| Development + Node | .env.Land + .env.Land.Node | Dev with specific Node version |
| Development + PostHog | .env.Land + .env.Land.PostHog | Dev with telemetry |
| Development + Diagnostics | .env.Land + .env.Land.Diagnostics | Dev with debug tracing |
| Production | .env.Land.Production | Release build |
| Production + Bundled | .env.Land.Production + .env.Land.Production.Bundled | Release with bundled workbench |
| Production + Extensions | .env.Land.Production + .env.Land.Production.Extensions | Production with extension skip |
| Production + Node | .env.Land.Production + .env.Land.Production.Node | Production with specific Node |
| Production + PostHog | .env.Land.Production + .env.Land.Production.PostHog | Production with telemetry |
| Production + Diagnostics | .env.Land.Production + .env.Land.Production.Diagnostics | Production with trace/record |
Profile System
Available Build Profiles
| Profile String | Workbench | Feature Coverage | Output Type |
|---|---|---|---|
debug | Browser | 70–80% | Dev binary |
debug-mountain | Mountain | 80–90% | Dev binary (recommended) |
debug-electron | Electron | 95%+ | Dev binary |
debug-electron-rest | Electron + OXC | 95%+ + fastest TS | Dev binary |
debug-electron-minimal | Electron | No built-in extensions | Dev binary |
debug-mountain-only | Mountain | No Cocoon subprocess | Dev binary |
debug-cocoon-headless | None | Mountain + Cocoon, Wind disabled | Dev binary |
debug-kernel | None | Pure Mountain, no built-ins | Dev binary |
debug-electron-compiled | Electron | Single-binary embedded resources | Dev binary |
debug-mountain-compiled | Mountain | Single-binary embedded resources | Dev binary |
debug-electron-bundled | Electron | Vite/Astro compiled workbench | Dev binary |
debug-browser-bundled | Browser | Vite/Astro compiled workbench | Dev binary |
debug-sessions-bundled | Sessions | Vite/Astro compiled workbench | Dev binary |
debug-workbench-bundled | Workbench | Vite/Astro compiled workbench | Dev binary |
debug-bundled-all | All four | Single Rollup pass | Dev binary |
production-electron-bundled | Electron | Optimized release | Prod binary |
production-electron-unbundled | Electron | Release without bundled assets | Prod binary |
Program Launch Options
| Flag | Effect |
|---|---|
--run | Launch application immediately after build |
--profile <name> | Select build profile (default: debug) |
--help | Show profile documentation |
Env Propagation to Each Element
Each Element reads the resolved environment variables through its own build system path:
graph LR
A[.env.Land files] --> B[Maintain/Debug/Build.sh]
B --> C[Rust build.rs]
B --> D[ESBuild define]
B --> E[Vite define map]
C --> F[Mountain env! / cfg features]
D --> G[Cocoon __LandTier_ globals]
E --> H[Wind import.meta.env]
F --> I{Tier Banner Agreement}
G --> I
H --> I
I --> J[Runtime tier validation]Rust Elements (Mountain, Common, Echo, Mist, Rest, SideCar, Air, Grove, Vine)
Maintain/Debug/Build.sh
|
| exports every Tier* and Product* env var
v
Cargo / build.rs
|
+---> PropagateTierGating() emits:
| cargo:rustc-env=Tier<Capability>=<Value>
| cargo:rustc-cfg=feature="Tier<Capability><Value>"
| cargo:rerun-if-changed=<envfile>
|
v
Mountain/src/main.rs
|
+---> env!("TierFileSystem") // compile-time constant
+---> #[cfg(feature = "TierFileSystemLayer4")] // conditional compilationTypeScript Elements (Cocoon)
Maintain/Debug/Build.sh
|
| serialises every Tier* var into CocoonEsbuildDefine JSON blob
v
Cocoon/Source/Configuration/ESBuild/Config/TargetConfig.ts
|
| merges blob into esbuild define map
v
ESBuild bundle
|
| __LandTier_FileSystem__ is substituted at bundle time
v
Cocoon/Source/Bootstrap/Implementation/CocoonMain.ts
|
| populates globalThis.__LandTiers from substituted identifiers
| falls through to process.env.Tier<Capability>
| falls through to hard-coded defaults
v
Cocoon/Source/Utility/Tier.ts
|
| exposes const Tier = { ... } as constTypeScript Elements (Sky/Wind)
Maintain/Debug/Build.sh
|
| exports Tier* and Product* env vars
v
Sky/astro.config.ts
|
| forwards every Tier* env var to Vite define map
v
Vite bundle
|
| import.meta.env.TierFileSystem is substituted at build time
v
Wind/Source/Utility/Tier.ts
|
| reads import.meta.env.Tier<Capability>
| falls through to globalThis.__LandTiers
| falls through to hard-coded defaults
| emits console.info() boot bannerCross-Element Agreement
All three runtime banners must report identical tier values:
| Element | Banner Mechanism |
|---|---|
Mountain | Rust env!() banner |
Cocoon | LandFixLog.Info banner |
Wind | console.info banner |
A mismatch indicates one build tool read a different env file.
Rust Build Process
Workspace Structure
The Rust elements form a workspace at Land/Cargo.toml:
[workspace]
members = [
"Element/Common",
"Element/Echo",
"Element/Mist",
"Element/Mountain",
"Element/Rest",
"Element/SideCar",
"Element/Air",
"Element/Grove",
"Element/Vine",
]build.rs Tier Propagation
Every Rust element with tier-gated features has a build.rs that:
- Calls
PropagateTierGating()which scans the resolved env file - Emits
cargo:rustc-env=for every row (defaults + overrides) - For non-default values, emits
cargo:rustc-cfg=feature="Tier<Capability><Value>" - Calls
IsDeclaredTierFeature()to validate againstCargo.toml [features] - Calls
IsDefaultTierValue()to identify no-op default values - Emits
cargo:warning=for any unrecognized(Key, Value)pair
TypeScript Build Process
ESBuild Compilation (Cocoon, Output, Worker)
Cocoon, Output, and Worker compile through ESBuild with:
- Env-injected defines via
CocoonEsbuildDefineJSON blob - Target configuration via
TargetConfig.ts(resolves platform, arch, profile) - Output to
Element/<Name>/Target/orElement/<Name>/Compiled/
Vite/Astro Compilation (Sky, Wind)
Sky and Wind compile through Vite with Astro:
- Vite define map receives every
Tier*env var asimport.meta.env.Tier* - Astro pages are rendered to static HTML + JS bundles
- SkyBridge (~2900 lines) is compiled as the runtime event bridge
- Output to
Element/Sky/Target/
Artifact Layout
After a successful build, artifacts are placed in per-Element target directories:
Land/Element/
├── Mountain/Target/
│ ├── debug/Mountain
│ ├── debug/bundle/macos/Mountain.app
│ └── debug/extensions.manifest.json
├── Air/Target/
├── Cocoon/Compiled/
│ ├── cocoon-bootstrap.js
│ └── bundles/
├── Output/Target/
│ └── @codeeditorland/output/
├── Sky/Target/Static/
│ ├── Application/ # VS Code workbench assets
│ └── Bundled/Electron/ # Vite-bundled workbench
└── Wind/Target/
└── Function/Install/Notable artifacts:
| Path | Description |
|---|---|
Element/Mountain/Target/<level>/Mountain | Native binary |
Element/Mountain/Target/<level>/bundle/macos/*.app | Signed .app bundle |
Element/Mountain/Target/<level>/extensions.manifest.json | Pre-baked extension list |
Element/Sky/Target/Static/Application/ | VS Code workbench assets |
Element/Sky/Target/Static/Bundled/Electron/ | Vite-bundled workbench |
Element/Cocoon/Compiled/cocoon-bootstrap.js | Extension host bundle |
Output Transform Pipeline
The Output element manages compilation of VS Code platform source code through two parallel compiler paths:
Primary Path (ESBuild)
- Input:
Dependency/Editor/out/(Stage 1 compiled VS Code) - Processing: ESBuild applies transforms for Tauri compatibility:
- Module resolution remapping (
electron→@tauri-apps/api) require()interceptor patches- Source map generation
- Polyfill injection
- Module resolution remapping (
- Output:
Output/Target/@codeeditorland/output/
Optional Path (Rest/OXC)
- Input: Same VS Code source
- Processing:
Rest(Rust OXC) re-compiles TypeScript 2–3x faster:- OXC parser handles decorators, class fields, JSX
- OXC transformer produces VS Code-compatible output
Rest --compilerCLI flag activates this path
- Output: Same layout, substituted for ESBuild output when
--compiler restis set
Worker Build Process
The Worker element compiles independently through ESBuild with no runtime dependencies:
- Input:
Element/Worker/Source/ - ESBuild produces:
- Service worker script (caching strategy, offline handler)
- CSS module interceptor
- Output:
Element/Worker/Target/ - Consumed by: Sky at build time (bundled into UI)
SideCar Binary Management
The SideCar element manages vendored Node.js runtime binaries:
- Binary resolution:
Build.shreadsNodeVersionandNodePlatformfrom env - Download: SideCar’s tool fetches the exact binary from official sources
- Caching: Binaries cached by version + platform key in
SideCar/Cache.json - Git LFS: Large binaries stored via Git LFS
- Consumption: Mountain’s build process copies the resolved binary into the app bundle
Target triples supported:
aarch64-apple-darwin(Apple Silicon macOS)x86_64-apple-darwin(Intel macOS)aarch64-unknown-linux-gnu(ARM64 Linux)x86_64-unknown-linux-gnu(x86_64 Linux)aarch64-pc-windows-msvc(ARM64 Windows)x86_64-pc-windows-msvc(x86_64 Windows)
Related Documentation
- Getting Started - Build instructions and prerequisites
- Quickstart - Concise build reference
- Configuration - Complete env var reference
- Deep Dives - Component architecture details