Porting approach (branching)
Background for D-16. The Python implementation is preserved on a python-archive branch, and the port continues directly on main. No long-lived feature branch and no swap.
Why it is cleaner. One default branch from the start: Dependabot (config and security updates), branch protection, required checks, issues, README and the repository name need no changes later. There is no rename procedure and no drift between two long-lived branches. The cost is that main is not a working product for the duration of the port; this is acceptable because MicroDCS is not in production (D-8) and python-archive is the usable version in the meantime.
Procedure and consequences
- Freeze point (done 2026-11-07).
python-archivewas created frommainat12c1415unchanged: no Python changes, no Valkey switch (D-5), no tag. Rule: security fixes only, through pull requests intopython-archive. The Valkey compatibility run was done beforehand (Valkey findings). No history secret scan was run at the freeze: the project never used credentials, and the first full-history Gitleaks run in S03 covers the shared history anyway. - First commit on
mainafter the freeze (S01): remove the Python code. The keep/replace/remove table is in the S01 block. Python stays readable via the branch (git show python-archive:path). - Walking skeleton before features. First PRs:
global.json,Directory.Build.props, solution, CI with build, unit tests and AOT publish smoke, the compose test harness (D-15) with one trivial end-to-end test. Everything after that has CI from the first commit. - Workflows on the archive branch need no change.
ci.ymltriggers onpushtomain, on everypull_request(no branch filter) and on a weeklyschedule. A security-fix PR intopython-archivetherefore still runs the Python tests. Pushes topython-archivetrigger nothing, and the weekly run stops oncemaincarries the .NETci.yml(scheduled runs use the default branch); both are acceptable for a frozen branch.docs.ymltriggers only on pushes tomain, so the archive branch cannot deploy the site; from S01 thegithub-pagesenvironment also allows deployments frommainonly.python-archivereceives no Dependabot updates (config is read from the default branch only). - Docs site is the live work-in-progress (decided).
docs.ymlstays onmainand keeps deploying on every push, so the published site always shows the current .NET state (readable on a phone, including this plan). It builds withzensical buildand, from S01, deploys through GitHub Actions (upload-pages-artifactanddeploy-pages) instead of pushing to agh-pagesbranch, which is then deleted. The Python docs remain readable in the archive branch'sdocs/folder. Pages that are not ported yet still describe the Python version, so mark them: - A WIP notice on the site (announcement bar if zensical supports it, otherwise an admonition on the home page): "Port to .NET in progress. Pages marked Python describe the archived implementation (
python-archivebranch)." - An admonition at the top of each not yet ported page, removed when the page is ported (S23 checks that none is left).
- The plan is published on the site:
docs/porting/with a nav entry "Port to .NET (WIP)" (the nav is inzensical.toml). Rendering check: tables and mermaid. - Visibility. README on
main: port to .NET in progress, the Python implementation is onpython-archive. - Branch protection on
main: from S01 pull requests required (no required approvals, single maintainer); required checks added in S02 and S03. Small vertical PRs. - Parity gate (S23, replaces the swap). Acceptance checklist: parity scenarios pass in compose, AOT image builds and runs, docs ported (no "not yet ported" notice left, WIP notice removed), security behaviours reproduced. Then release.
Alternatives
| Option | Assessment |
|---|---|
python-archive branch, port on main (chosen) |
Cleanest and cheapest: no swap, default branch features work from day one. main is not usable until parity |
Long-lived dotnet branch, swap with main at the end (earlier D-16) |
Keeps main usable, but needs the rename procedure, Dependabot target-branch entries, recreated branch protection and invisible progress |
.NET in a dotnet/ folder on main |
No swap, but mixed toolchains and path-filtered CI for months |
| New repository | Loses issues, stars and doc URLs; not needed |