Repository navigation
Contributor Workflow
How a change gets tested before it ships: what runs on the machine you work on, what runs in the dev VM, and what CI runs on the PR.
-
The machine you work on runs
stable(the newest release tag). You live on it; a bad change should not be able to log you out of it. -
The dev VM runs
edge(the currentdevtree) or a PR branch. It is disposable: a broken test run costs a reset, not a reimage.
# on your daily machine
./install.sh --channel stable --profile full --no-assistant
# in the dev VM, for current dev
./install.sh --channel edge --profile full --no-assistantSee Dev VM for building the VM itself (libvirt or Proxmox) and Installation for the full flag reference.
The cycle for any PR that touches the installer, the shell, or anything a user would run:
-
Fetch the branch. From a local clone of the repo:
git fetch origin pull/299/head:pr-299for PR 299, or clone the author's fork directly in the VM. -
Reset the VM so the test starts clean:
tools/devvm/proxmox.sh reset(the Proxmox path), or destroy and recreate the libvirt guest. -
In the VM: check out the branch, then
./install.sh --profile full --no-assistant. A PR branch is its own state, so no--channelis needed. -
Check the result:
aphotic doctorin the VM, plus whatever the PR is supposed to fix. - After a failed test, reset again. Do not stack tests on a VM that a broken install already touched; the reset is cheap and the diagnosis is cleaner.
aphotic sync from a checkout re-copies its configs over an existing
install, which is how a running machine picks up config-only changes
without a full reinstall.
A PR into dev is gated by these checks:
| Check | What it is |
|---|---|
test |
The full test suite: tests/test_*.sh (bash) and tests/test_*.py (pytest) |
shellcheck |
Advisory; warnings do not block a merge |
bash-syntax |
bash -n over the shell files |
Analyze (python) |
Python analysis |
Analyze (actions) |
Workflow analysis |
A run named "Code scanning AI findings" never blocks a merge, so ignore
it. Changes to install.sh, lib/, or profiles/ also trigger an
installer dry-run in a container.
tools/ci/local.sh runs the CI checks in a checkout shaped like
GitHub's and prints only what failed, with a rerun: command for each
failure:
tools/ci/local.sh # everything, the way CI runs it
tools/ci/local.sh --test tests/test_x.sh # one bash test
tools/ci/local.sh --here # fast loop in your own tree
tools/ci/local.sh --only syntax|sh|py # one suiteGreen locally means green for test and bash-syntax. If a PR goes red
on CI, run tools/ci/triage.py <pr-number>: it names the failing test
and its error lines, and prints the reproduce: command to run after
fixing.
- One ticket, one branch, one PR into
dev. Never stack on another open PR's branch. -
devandmainare protected: never push them, never merge. A maintainer merges after the required checks pass. - Open the PR against
dev, notmain.