Skip to content

v0.16.0 - Upload: Push Local Data to a Remote Server (2026-07-10)

What Changed?

This release adds upload, a third rsync transfer direction alongside fetch (remote → local) and backup (local → external), tracked as #54. upload sends local files to a remote server over SSH — the mirror of fetch. It also removes a set of orphaned Japanese documentation pages that had drifted out of sync with the actual CLI.


What's New

Main Feature: fnb upload

What it does: A new [upload.LABEL] config section and fnb upload LABEL command push local data to a remote host via rsync, reusing the same SSH password automation, FNB_TIMEOUT handling, and --dry-run/--create-dirs options as fetch. Because upload is the mirror of fetch, host describes the target instead of the source: source is always a local path, and target is the remote destination (or a local path when host = "none").

fnb status now shows an Upload Tasks table alongside Fetch and Backup, checking the local-side directory (source, not target) for existence.

upload is intentionally not part of syncsync still only chains fetchbackup. Run upload on its own when you need to push data out.

How to use it:

[upload.reports]
label = "reports"
summary = "Publish generated reports to a remote server"
host = "admin@report-server.example.com"
source = "./dist/reports/"
target = "/var/www/reports/"
options = ["-auvz", "--delete"]
enabled = true
fnb upload reports
fnb upload reports --dry-run
fnb upload reports --create-dirs

Design note: RsyncTaskConfig.rsync_source/rsync_target were left untouched — those properties already encode "host describes the source" for fetch/backup. Rather than overload them, uploader.py builds its remote target path locally with a small _remote_target() helper, keeping the direction-specific logic out of the shared config model.


Installation

Quick Start

# Get the release
git checkout v0.16.0

# Setup
uv sync --all-groups

# Run CLI
uv run fnb --help

What's Different from the Last Version?

✅ Added

  • fnb upload LABEL command and [upload.LABEL] config section
  • src/fnb/uploader.py, the local-to-remote counterpart to fetcher.py
  • fnb status now displays an Upload Tasks table
  • [upload.logs] example added to the fnb init config template

🔧 Changed

  • FnbConfig gained an upload: dict[str, RsyncTaskConfig] field; get_enabled_tasks()/get_task_by_label() accept "upload" alongside "fetch"/"backup"
  • User Guide (docs/usage/) and Developer Guide (docs/references/architecture.en.md) updated to document upload

🐛 Fixed

  • ConfigReader._expand_env_vars() expanded a leading ~ on the wrong side for a local-to-remote transfer: it always expanded target and conditionally expanded source, which is correct for fetch/backup (host describes the source) but backwards for upload (host describes the target). Without this fix, a ~ in an upload task's local source would never be expanded, and since fnb no longer goes through a shell that would expand it (see #51), rsync would fail on the literal ~ path.

🗑️ Removed

  • 10 orphaned .ja.md documentation pages (docs/usage/*.ja.md, docs/references/*.ja.md, docs/faq.ja.md, docs/development/releasing.ja.md). The site config sets language = "en" with no i18n plugin, so these pages were never reachable from the built site, and their content had drifted out of date (still calling the tool "rfb", missing most current CLI options) since before the Zensical migration in v0.14.0.

Is It Safe to Upgrade?

Backward Compatible: Yes.

  • Configuration file format (fnb.toml) and existing CLI commands are unchanged; [upload.LABEL] is a new, optional section
  • If you were linking to any of the removed .ja.md pages from outside the repo, those links will now 404 — none were reachable from the live documentation site, so this should not affect real traffic

Tests Passed

  • ✅ 156 unit and integration tests passed
  • ✅ 89% code coverage
  • ✅ All pre-commit hooks pass (mypy, ruff, trailing whitespace, etc.)
  • uv run --group docs zensical build — no new warnings from the doc changes
  • ✅ Manual verification: fnb initfnb status (Upload Tasks table) → fnb upload --help

Release Details

  • Date: 2026-07-10
  • Version: v0.16.0
  • Commits: 8 feature/doc commits since v0.15.0, all closing out issue #54
  • f42f6bd: feat(config): add upload section to FnbConfig
  • 6a9704d: feat(uploader): add local-to-remote upload module
  • d540567: feat(cli): add fnb upload command
  • 18c32d5: feat(reader): show upload tasks in fnb status, fix ~ expansion direction
  • 006ab68: feat(assets): add [upload.logs] example to config.toml template
  • b008700: docs: remove orphaned Japanese doc pages
  • be5707c: docs: document the upload command and module
  • 363dd4b: docs(reader): fix stale "target directory" wording in _directory_status

Next Steps

  • Re-introduce Japanese documentation as a fresh translation effort against the current English docs, rather than reviving the removed .ja.md pages
  • Continue triaging remaining items from the 2026-07 codebase review (issues #48-#53 are complete)