Contributing, Development, and Testing
This guide is for people who want to run SFTPWarden from source, contribute a change, build documentation, or validate the project before publishing a release.
For the shorter GitHub contribution guide, see CONTRIBUTING.md.
Branch Model
SFTPWarden uses dev as the integration branch and main as the protected
production/release branch.
Contributors should not work directly on dev or open normal pull requests to
main. Instead:
Fork the repository.
Create your own branch from
dev.Develop and validate your change in that branch.
Open a Pull Request from your branch to
dev.
git clone https://github.com/<your-user>/sftpwarden.git
cd sftpwarden
git remote add upstream https://github.com/kithuto/sftpwarden.git
git fetch upstream
git checkout -b dev upstream/dev
git checkout -b fix/my-change
After development, push your branch and open:
fix/my-change -> dev
The maintainer promotes accepted changes from dev to main when preparing
production updates or public releases.
Install from Source
git clone https://github.com/kithuto/sftpwarden.git
cd sftpwarden
git checkout dev
python -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip
python -m pip install -e ".[dev,docs,mysql,postgres,mongodb]"
sftpwarden --version
The mysql extra also enables MariaDB because both providers use PyMySQL. The
mariadb extra is an alias for the same dependency.
Use Python 3.11, 3.12, 3.13, or 3.14. Install the Python versions locally before
running the full tox matrix.
Development Workflow
Create a branch from dev before changing files:
git checkout dev
git pull origin dev
git checkout -b fix/my-change
Run the CLI from the editable install:
sftpwarden doctor
sftpwarden validate --config examples/yaml/sftpwarden.yaml
Build the runtime image when changing Docker/runtime behavior:
docker build -t sftpwarden:local -f docker/runtime/Dockerfile .
docker run --rm --entrypoint sh sftpwarden:local -c 'command -v sshd && command -v sftpwarden'
For Kubernetes, Helm, or runtime changes that affect the container in a cluster,
run a real Kubernetes or Helm smoke test when feasible. At minimum, render the
manifests or values, run helm lint, and confirm the runtime image builds.
Build the watcher image when changing watcher behavior:
docker build -t sftpwarden-watcher:local -f docker/watcher/Dockerfile .
docker run --rm --entrypoint sh sftpwarden-watcher:local -c 'command -v sftpwarden'
Testing
Run the full validation:
tox
The default tox run covers:
lint and formatting;
tests on Python 3.11, 3.12, 3.13, and 3.14;
coverage once, instead of repeating it for every Python version;
Sphinx documentation build;
package build and wheel content check;
dependency audit.
Run one part:
tox -e lint
tox -e py311
tox -e py312
tox -e py313
tox -e py314
tox -e coverage
tox -e docs
tox -e package
tox -e audit
tox -e clean
Run pytest directly while iterating:
python -m pytest
python -m pytest tests/test_cli.py
Documentation
The Sphinx source lives in docs/. docs/index.md owns the main navigation,
and static assets live under docs/_static/.
Build the Sphinx site locally:
python -m pip install -e ".[docs]"
sphinx-build -b html docs docs/_build/html
The CI-friendly validation command is:
tox -e docs
Keep the README focused on adoption. Put deeper explanations in the specific docs pages:
The public documentation site is published by .github/workflows/docs.yml.
Pushes to main that touch README.md, CONTRIBUTING.md, SECURITY.md,
CODE_OF_CONDUCT.md, or docs/** build the HTML site on Python 3.14 with:
sphinx-build -b html docs docs/_build/html
The workflow uploads docs/_build/html as a GitHub Pages artifact and deploys it
with actions/deploy-pages. Documentation-only pull requests should still run
tox -e docs before review so broken links, invalid MyST, and Sphinx warnings
are caught before the workflow publishes from main.
Adding or Changing Features
Keep public behavior stable unless the change is intentional and documented:
CLI command names and option names should remain compatible.
sftpwarden.yaml, provider files, SQL schemas, and context registry formats should remain compatible.Runtime state should remain readable across upgrades.
JSON output should stay parseable.
For user/provider changes, add tests that cover both service behavior and CLI behavior when the CLI output matters.
For remote/deploy/watcher changes, include dry-run coverage so generated SSH, rsync/scp, Docker, and scheduler commands stay reviewable.
Tox cleans Python caches, coverage output, docs output, and package artifacts
after the environments that generate them. Run tox -e clean to clean the same
local artifacts plus Docker smoke-test images.
Pull Request Checklist
Before opening a PR:
target
dev, notmain;for docs-only changes, run
tox -e docs;for code changes, run
tox;for Docker/runtime changes, build the affected Docker image locally;
update README/docs when adoption or operations behavior changes;
update examples when configuration changes;
redact secrets from logs and screenshots;
describe the user-facing behavior, validation performed, and any known limits.
Release Readiness
Before a public release:
tox
python -m build
docker build -t sftpwarden:local -f docker/runtime/Dockerfile .
docker build -t sftpwarden-watcher:local -f docker/watcher/Dockerfile .
sftpwarden validate --config examples/yaml/sftpwarden.yaml
sftpwarden validate --config examples/csv/sftpwarden.yaml
sftpwarden validate --config examples/sqlite/sftpwarden.yaml
SFTPWARDEN_MYSQL_DSN=mysql://user:pass@localhost/sftp \
sftpwarden validate --config examples/mysql/sftpwarden.yaml
SFTPWARDEN_MARIADB_DSN=mariadb://user:pass@localhost/sftp \
sftpwarden validate --config examples/mariadb/sftpwarden.yaml
SFTPWARDEN_POSTGRES_DSN=postgresql://user:pass@localhost/sftp \
sftpwarden validate --config examples/postgres/sftpwarden.yaml
SFTPWARDEN_MONGODB_DSN=mongodb://localhost:27017/sftp \
sftpwarden validate --config examples/mongodb/sftpwarden.yaml
helm lint charts/sftpwarden
helm template sftpwarden charts/sftpwarden --namespace sftpwarden
Also check the repository-level security workflow before publishing: dependency audit, container scan, SBOM generation, and OpenSSF Scorecard.