v0.13.0 - Reliability Fixes and Faster CI (2026-07-06)¶
What Changed?¶
This release closes several reliability gaps found during a full codebase review: rsync failures could previously be reported as success, and sync could push an incomplete local copy on top of a good backup.
It also fixes an SSH password template that never actually worked, unifies how commands find the config file, and cuts the GitLab CI pipeline from ~183s to ~43s.
What's New¶
Main Feature: Failures Are No Longer Silently Swallowed¶
What it does:
Previously, a failed rsync transfer (bad exit code, or an SSH connection that closed before authentication) could still be reported as "completed successfully" with exit code 0.
Worse, fnb sync would run backup even after fetch failed, risking an incomplete local copy overwriting or deleting good data on the backup target (especially with --delete).
How to use it:
No change to the CLI interface.
fnb fetch, fnb backup, and fnb sync now correctly exit with code 1 on failure, so scripts and cron jobs can detect problems that were previously invisible.
fnb sync stops before running backup if fetch fails.
# A failed fetch now aborts sync before it can touch the backup target
fnb sync logs
echo $? # 1 on failure, instead of always 0
Installation¶
Quick Start¶
# Get the release
git checkout v0.13.0
# Setup development environment
task env:setup
# Run all tests with formatting and pre-commit validation
task test:ci
# Run CLI
uv run fnb --help
What's Different from the Last Version?¶
✅ Added¶
- CI dependency groups:
pyproject.tomlgains[dependency-groups](test,lint) so CI jobs install only what they need instead of the fulldevextra publish:buildtask: dedicated Taskfile task for building distributions, used by both TestPyPI and PyPI publish tasks
🔧 Changed¶
--configdefault unified:fetchandbackupnow auto-detect the config file the same waystatusandsyncalready did, instead of being hard-coded to./fnb.toml- CI pipeline parallelized: verification jobs (
test,code-quality,docs-quality,build-package) now run in parallel vianeeds: []instead of sequential stages; the image switched toghcr.io/astral-sh/uv:python3.12-bookworm(uv preinstalled);docs-qualityis skipped on MRs that don't touch docs-related files FNB_PASSWORD_*host normalization:get_ssh_passwordnow also checks the uppercase form (FNB_PASSWORD_USER_EXAMPLE_COM) documented inenv.sample, falling back to the older as-is form
🐛 Fixed¶
- rsync failures no longer report success: the pexpect-based password automation path now raises
subprocess.CalledProcessErroron a non-zero rsync exit code instead of logging a warning and returningTrue;fetcher.run()/backuper.run()now checkrun_rsync()'s return value instead of ignoring it fnb syncno longer runs backup after a failed fetch: prevents an incomplete local copy from overwriting or deleting good data on the backup targetenv.sampleprefix corrected: the generated.envtemplate documentedRFB_PASSWORD_*, but the code readsFNB_PASSWORD_*— passwords set up by following the template were silently ignoreduse --clear flag in before_script uv venv: fixes stale virtualenv state between CI runs
Is It Safe to Upgrade?¶
Backward Compatible: Yes, with one behavior change worth noting.
- CLI arguments and configuration file format are unchanged
fnb fetch/fnb backup/fnb synccan now exit with code 1 in situations that previously exited 0 (specifically: rsync failures, and fetch failures duringsync). If you rely on exit codes in scripts or cron jobs, this is the intended fix — a genuine failure is no longer reported as success- If you generated
.envfiles from an olderfnb init envtemplate usingRFB_PASSWORD_*, rename those variables toFNB_PASSWORD_*(orFNB_PASSWORD_DEFAULT) so fnb picks them up
Tests Passed¶
- ✅ 147 unit and integration tests passed (previously masked failures in integration test mocks were fixed as part of this release)
- ✅ 80% code coverage maintained
- ✅ All pre-commit hooks pass (mypy, ruff, trailing whitespace, etc.)
- ✅
glab ci lintvalidates the updated.gitlab-ci.yml
Release Details¶
- Date: 2026-07-06
- Version: v0.13.0
- Files Changed: 15 (
.gitlab-ci.yml,pyproject.toml,src/fnb/{cli,env,fetcher,backuper,gear,logger,options}.py,src/fnb/assets/env.sample, tests) - Commits:
- 2030a05: fix(env): correct env.sample prefix RFB_ to FNB_ and honor uppercase form
- 741153d: fix(cli): unify --config default to auto-detection across commands
- 2f22639: fix: propagate rsync failures to CLI exit codes and abort sync on fetch failure
- ce590e3: refactor: use uv sync instead of uv venv in CI
- 8889a73: fix: use --clear flag in before_script uv venv
- 1fe6976: ci: parallelize pipeline jobs and minimize per-job dependency installs
Next Steps¶
- Harden the pexpect-based SSH path further: list-based command execution instead of string concatenation, and handling for the SSH host-key confirmation prompt on first connection (#51)
- Maintainability cleanup: remove duplicate config-loading code, fix
logger.bind()not affecting log format, expand~in local paths (#52)