git-pr-cleanup (prc) tried `branch -d` then fell back to `branch -D` unconditionally, silently destroying an unmerged branch when prc was run before the PR merged or against the wrong branch. Keep the safe `-d` for the normal post-merge path, but prompt before forcing so unmerged commits aren't lost without consent; decline keeps the branch. |
||
|---|---|---|
| .. | ||
| presets | ||
| scripts | ||
| tests | ||
| config.nix | ||
| default.nix | ||
| lib.nix | ||
| options.nix | ||
| README.md | ||
modules/dev-env
Declarative NixOS module for managing a multi-project dev environment around an LNbits stack — bare repos, worktrees, navigation helpers, tmux sessions, the regtest docker env, and the upstream-PR workflow.
Design principles
-
Nix owns the configuration, bash owns the runtime. Nix renders
/etc/dev-env/config.sh+projects.json; installed bash scripts source those at call time. Navigation helpers walk the filesystem at runtime — adding a new branch isgit worktree add, nevernixos-rebuild. -
Projects are explicit, git-host-agnostic. Each project declares its
originurldirectly (any forgejo / gitea / codeberg / github URL). The only github-specific knob isgithub.forkUser, used to derive a personalforkremote for upstream PRs. -
Bootstrap is user-invoked, not an activation hook.
dev-env-bootstrapmaterializes bare repos + worktrees. It is never run duringnixos-rebuild— rebuilds stay fast and offline.
Files
| File | Purpose |
|---|---|
default.nix |
Imports options, lib, config. Module entry point. |
options.nix |
mkOption declarations for every knob. |
lib.nix |
mkProject constructor + path/remote helpers. |
config.nix |
Renders config files, installs scripts, wires git hooks. |
presets/example.nix |
A worked, generic project list — copy and edit. |
scripts/*.sh |
Bash helpers loaded via builtins.readFile. |
scripts/git-hooks/pre-commit |
Shared secret-scanner hook (via core.hooksPath). |
tests/smoke.nix |
nix flake check evaluation test for the schema. |
Using it
# configuration.nix
imports = [
./modules/dev-env
./modules/dev-env/presets/example.nix # opt-in; copy and edit
];
lnbits-sensei.devEnv = {
enable = true;
scaffoldPath = "/home/you/dev/lnbits-sensei";
github.forkUser = "octocat";
deploy.targets = {
prod = "root@prod-host";
staging = "root@staging-host";
};
};
Bootstrap workflow
# 1. Rebuild with dev-env enabled
sudo nixos-rebuild switch --flake .#<host>
# 2. Dry-run to see what will be created
dev-env-bootstrap --dry-run
# 3. Materialize bare repos + worktrees
dev-env-bootstrap
# 4. Navigate (shell functions, sourced into interactive shells)
lb dev # → ~/dev/lnbits/dev
g extensions myext # → ~/dev/extensions/myext
ext <name> # → ~/dev/shared/extensions/<name>
prb lnbits fix-x # → ~/dev/upstream-prs/lnbits-fix-x on upstream/main
# 5. Inspect / sync
dev-status # dirty + ahead/behind for every worktree
wts # fetch all bare repos, summarize worktree status
rebase status # which forks need rebasing onto upstream
lnbits-status # lnbits dev/main divergence vs upstream
# 6. Regtest (when devEnv.regtest.enable = true; needs docker)
regtest-start dev # build lnbits from ~/dev/lnbits/dev, bring stack up
regtest-stop
# 7. Deploy
dev-deploy prod # uses the locked deploy-flake input
dev-deploy --local staging # overrides inputs with local worktrees
Command summary
| Command | What |
|---|---|
dev-env-bootstrap |
Materialize bare repos + worktrees from projects.json. |
dev-status |
Dirty/ahead/behind report across all worktrees. |
dev-tm <session> |
Launch a declarative tmux session. |
dev-deploy <host> |
nixos-rebuild against your deploy flake. |
rebase [status|all|<path>] |
Safe fork-onto-upstream rebase with backups. |
regtest-start / -stop / -status |
Bitcoin/Lightning regtest stack. |
lb / g / ext / dep / prs / shared / repos |
Navigation (shell functions). |
wt / wts / wtu / wtn |
Worktree list / sync / upstream-fetch / spawn. |
prb / prc / prl |
Upstream-PR worktree branch / cleanup / list. |
lnbits-status / lnbits-sync-dev / lnbits-sync-main |
lnbits fork workflow. |
What this module does NOT do
- Run
git fetch/git pullautomatically — usewts/wtuor a manualgit fetch --all. - Manage per-worktree
.envrcbeyond writing a defaultuse flakehint on bootstrap (never clobbers an existing file). - Install docker for you —
devEnv.regtest.enableinstalls theregtest-*helpers, but you must provide the container engine.