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:

  1. Fork the repository.

  2. Create your own branch from dev.

  3. Develop and validate your change in that branch.

  4. 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, not main;

  • 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.