emulebb-build is the canonical build and test orchestration layer for the
workspace rooted at EMULE_WORKSPACE_ROOT.
emulebb-build owns workspace materialization, generated workspace topology, and
build/test orchestration. It is responsible for:
- canonical repo and worktree materialization
- dependency builds under
repos\third_party - app builds for the canonical workspace app worktrees
- shared test builds from
repos\emulebb-build-tests - parity, coverage, and live-diff execution against the canonical app variants
python -m emule_workspace is the authoritative orchestration surface.
Clone this repo as <workspace-root>\repos\emulebb-build, then use the supported
emule_workspace command to materialize and operate the workspace. The package
owns typed command parsing, workspace topology loading, locking, subprocess
routing, build/test execution, live-test wrapping, and release packaging.
This repo is the source of truth for workspace materialization and the full
layout contract. A materialized workspace uses the standard
EMULE_WORKSPACE_ROOT\repos\... plus
EMULE_WORKSPACE_ROOT\workspaces\workspace\... layout.
In practice this repo needs:
repos\emulebbrepos\emulebb-buildrepos\emulebb-build-testsrepos\emulebb-toolingrepos\amutorrentrepos\emulebb-pagesrepos\emulebb-org-profilerepos\third_party\...workspaces\workspace\app\emulebb-mainworkspaces\workspace\app\emulebb-community-baselineworkspaces\workspace\app\emulebb-community-tracing-harness
repos\emulebb is not a normal development checkout. Python materialization owns
it as the canonical app anchor, and it is expected to stay detached at
origin/main. Active app development belongs in the managed worktrees under
workspaces\workspace\app\..., especially emulebb-main for the mainline branch.
Canonical managed app variants use short variant keys in
python -m emule_workspace commands. The worktree folder and branch names stay
descriptive, but they are not CLI variant keys:
| Variant key | Worktree | Branch |
|---|---|---|
main |
workspaces\workspace\app\emulebb-main |
main |
community |
workspaces\workspace\app\emulebb-community-baseline |
baseline/community-0.72a |
tracing-harness |
workspaces\workspace\app\emulebb-community-tracing-harness |
tracing-harness/community-0.72a |
Branch roles, release intent, and baseline rules are owned by
EMULE_WORKSPACE_ROOT\repos\emulebb-tooling\docs\WORKSPACE-POLICY.md.
The active app layout and workspace repo paths are topology-driven from
workspaces\workspace\deps.json, with build-specific settings kept in this repo's
deps.json. Test, coverage, and live-diff flows resolve their app roots from
configured variant names rather than duplicating hardcoded worktree paths.
The generated manifest also tracks the public pages repo and organization
profile repo so web/documentation repos are materialized with the rest of the
workspace under repos\.
Python-first commands:
python -m emule_workspace materialize
python -m emule_workspace sync
python -m emule_workspace status
python -m emule_workspace dep-updates
python -m emule_workspace compare
python -m emule_workspace env-check
python -m emule_workspace dep-status
python -m emule_workspace validate
python -m emule_workspace cleanup
python -m emule_workspace build libs
python -m emule_workspace build app
python -m emule_workspace build tests
python -m emule_workspace build all
python -m emule_workspace test python
python -m emule_workspace test all
python -m emule_workspace test live-diff
python -m emule_workspace test protocol-parity
python -m emule_workspace test live-e2e
python -m emule_workspace test amutorrent-session
python -m emule_workspace test community-core-coverage
python -m emule_workspace full
python -m emule_workspace package-releaseCommand behavior:
helpprints supported commands and common options.env-checkverifies the core toolchain discovery for Git, Visual Studio, and MSBuild.dep-statusreports branch and worktree status for the dependency repos and canonical app worktrees that exist locally.validateverifies required workspace paths, canonical app worktree presence, branch alignment, required test helper scripts, modified tracked-file editorconfig compliance, the PowerShell boundary, and the shared static policy audits fromemulebb-tooling\ci.cleanupdry-runs generated artifact pruning by default. Use--applyonly after reviewing the candidate summary.- The Python
package-releasecommand may reanchor a cleanrepos\emulebbcheckout back to detachedorigin/mainbefore building package artifacts. build libsbuilds the shared dependency set for the selected--configand--platform.build libsincludes the CMake-builtlibpcpnatpmpstatic library, and the currentmainapp build now links it for the PCP/NAT-PMP NAT-mapping backend.build appbuilds all canonical app variants for the selected--configand--platform.build testsbuilds the shared test harness against the configured build variant.test pythonruns the fast pytest harness suite fromemulebb-build-tests; use--path,--expression, and--quietto narrow the pytest selection.test allruns parity tests, native coverage, and live diff using the configured test target variants.test live-diffruns parity and divergence comparison directly against any two configured app variants.test protocol-parityruns the focused Kad/eD2K gate: protocol surface diff, protocol oracle golden validation, andprotocol-paritynative live-diff.test live-e2eruns the aggregate UI, REST API, and live-wire E2E suite fromemulebb-build-tests.test amutorrent-sessionstarts a disposable interactive aMuTorrent session against eMuleBB REST and leaves both processes running for operator testing.test community-core-coverageruns community-core coverage checks with live REST E2E coverage enabled.build allrunsbuild libs,build app, andbuild tests.fullrunsbuild all, thentest all, then prints a workspace summary.package-releasebuilds the main Release app, language DLLs, release ZIP, and release manifest.
All top-level emule_workspace commands are serialized per workspace root.
This single-owner workspace lock is intentional. It prevents overlapping
env-check, build, test, and live-diff commands from trampling shared state,
logs, and outputs in the same workspace.
If another command already owns the workspace lock, the next command fails fast with a clear owner message instead of running concurrently against the same workspace. When commands are launched back-to-back, the second command may need to wait briefly for the first command's lock window to close fully before it can start.
cleanup prunes generated workspace artifacts only from known output roots. It
does not run broad git clean, does not remove tracked files, and defaults to a
dry run:
python -m emule_workspace cleanup
python -m emule_workspace cleanup --applyThe default routine profile targets old scratch artifacts under
workspaces\workspace\state\test-artifacts, heavyweight payloads and
timestamped reports under workspaces\workspace\state\test-reports, old
workspaces\workspace\state\build-logs runs, and Python test caches. Legacy
workspaces\workspace\state\live-e2e-artifacts runs are also pruned when they
age out, but new harness output should not be written there. Build outputs and
superseded release rehearsal state require explicit flags:
python -m emule_workspace cleanup --include-build-outputs
python -m emule_workspace cleanup --include-release-stateDependencies and app builds honor the selected invocation parameters:
-Config Debug|Release-Platform x64|ARM64-BuildOutputMode Full|Warnings|ErrorsOnly-CleanWin32is not part of the active workspace build matrix
Examples:
build-app -Config Debug -Platform x64builds onlyDebug|x64build-libs -Config Release -Platform ARM64builds onlyRelease|ARM64build-allandfulluse the same selected target instead of expanding to a hidden multi-target matrix
Build commands default to a quiet filtered console view plus a short step recap.
Use -BuildOutputMode Full when you want raw MSBuild output for troubleshooting.
Use -Clean when you explicitly want rebuild/cleanup behavior; normal runs stay incremental.
Build runs write text logs, MSBuild binary logs, and a machine-readable recap under
workspaces\<workspace>\state\build-logs\.
Build and test run directories use UTC YYYYMMDDTHHMMSSZ prefixes. Build recaps
are named build-result.json; certification and release-campaign recaps are
named certification-result.json and release-campaign-run-result.json.
Test reports use <suite>\latest snapshots and suite-scoped leaves such as
<suite>-result.json, <suite>-result.partial.json, and <suite>-summary.json.
Shared test builds support x64 and ARM64. Test execution remains x64
only:
test all --platform ARM64fails with a clear unsupported-platform error
ARM64 remains available for dependency and app builds, but x64 is still the primary stabilized acceptance path for the end-to-end canonical workflow.
Live-diff examples:
live-diff -Config Debug -Platform x64uses the configured defaults (mainvscommunity)live-diff -Config Debug -Platform x64 -TestRunVariant main -BaselineVariant communitycompares main against the parity/regression baselinelive-diff -Config Release -Platform x64 -TestRunVariant broadband -BaselineVariant communitycompares broadband behavior against the parity/regression baseline
Live E2E examples:
live-e2e -Config Release -Platform x64runs the full maintained UI, REST API, and live-wire lane, including the default six-term server/Kad release search matrix and one paused live search-result download triggerpython -m emule_workspace test live-e2e --profile beta-green --fail-fastruns the short beta gate: REST contract coverage, REST smoke stress, shared-directories REST, and reduced Prowlarr/eMuleBB search resiliencepython -m emule_workspace test live-e2e --profile controller-surface --fail-fastruns the focused controller API surface gate: native/api/v1, qBittorrent-compatible/api/v2, Torznab/Arr, and aMuTorrent browser smokepython -m emule_workspace test live-e2e --profile beta-release --fail-fastextends the beta gate with Radarr and Sonarr full acquisition plus cold-start dump stresslive-e2e -Config Release -Platform x64 -RestDownloadTriggerCount 0disables the REST live download trigger for diagnosislive-e2e -Config Release -Platform x64 -LiveSuite preference-ui -LiveSuite rest-apiruns a focused subsetlive-e2e -Config Release -Platform x64 -SkipLiveSeedRefreshreuses the checked-in live seed files for offline diagnosis
Interactive aMuTorrent example:
amutorrent-session -Config Debug -Platform x64 -LiveNetworklaunches Debug x64 eMuleBB with a disposable profile, starts aMuTorrent against the eMuleBB REST API, opens the aMuTorrent URL, and writes astop-session.cmdhelper into the session report directory.
Python test examples:
python-testsruns the default fast pytest collectionpython-tests -PythonTestPath tests/python/test_auto_browse_live.py -PythonTestExpression pending -PythonTestQuietruns one focused pytest expression
validate is intended to catch canonical workspace drift before a longer build:
- missing
reposorworkspacesroots - missing dependency repos
- missing canonical app worktrees
- stale canonical app anchor state in
repos\emulebb - app worktrees checked out on the wrong branches
- dependency repos not aligned with their active local
origin/HEADpins - active documentation hardcoding machine-specific absolute paths
- active workflow docs/scripts drifting back to
.sln/.slnxentrypoints - active warning suppressions drifting beyond the approved narrow third-party exceptions
- modified tracked text files drifting from repo
.editorconfig/.gitattributes - tracked PowerShell files outside the approved
repos\emulebb-tooling\scriptsrelease/admin boundary - missing shared test helper scripts
Tracked-file cleanliness is intentionally a separate explicit audit via
repos\emulebb-tooling\ci\check-clean-worktree.py, so in-progress feature work
does not get blocked by routine validate.
The setup/build contract is intentionally narrow:
emulebb-buildowns workspace topology, managed app worktree creation, and fullsyncreconciliation.emulebb-buildassumes that topology exists and only self-heals the clean setup-ownedrepos\emulebbanchor when validation needs it to match currentorigin/main.
The test flows use the manifest-configured app variants:
- test build target:
community - test run target:
main - live-diff baseline target:
community
The tracing harness variant is part of the canonical buildable app set, but it is not the default test-run or baseline target unless explicitly selected.
build-tests honors the selected -Config value for both x64 and ARM64.
test honors the selected -Config value, but requires -Platform x64.
- ARM64 Crypto++ overrides are generated under
workspaces\<workspace>\state\instead of the workspace root. - Tool-install fallbacks are allowed where they are genuinely about tool discovery, such as standard Perl or Visual Studio install locations.
- Workspace-specific hardcoded local paths are not part of the supported model.
- Legacy pre-canonical branch names are not part of the supported workflow.