Skip to content

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.toml gains [dependency-groups] (test, lint) so CI jobs install only what they need instead of the full dev extra
  • publish:build task: dedicated Taskfile task for building distributions, used by both TestPyPI and PyPI publish tasks

🔧 Changed

  • --config default unified: fetch and backup now auto-detect the config file the same way status and sync already 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 via needs: [] instead of sequential stages; the image switched to ghcr.io/astral-sh/uv:python3.12-bookworm (uv preinstalled); docs-quality is skipped on MRs that don't touch docs-related files
  • FNB_PASSWORD_* host normalization: get_ssh_password now also checks the uppercase form (FNB_PASSWORD_USER_EXAMPLE_COM) documented in env.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.CalledProcessError on a non-zero rsync exit code instead of logging a warning and returning True; fetcher.run() / backuper.run() now check run_rsync()'s return value instead of ignoring it
  • fnb sync no longer runs backup after a failed fetch: prevents an incomplete local copy from overwriting or deleting good data on the backup target
  • env.sample prefix corrected: the generated .env template documented RFB_PASSWORD_*, but the code reads FNB_PASSWORD_* — passwords set up by following the template were silently ignored
  • use --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 sync can now exit with code 1 in situations that previously exited 0 (specifically: rsync failures, and fetch failures during sync). 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 .env files from an older fnb init env template using RFB_PASSWORD_*, rename those variables to FNB_PASSWORD_* (or FNB_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 lint validates 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)