SeedSync is a Docker-based tool that syncs files from a remote seedbox to a local machine using LFTP.
- Frontend: Angular 21 (Bootstrap 5.3, Font Awesome 7, Vitest)
- Backend: Python 3.12 with Bottle
- Container: Multi-arch Docker image (amd64, arm64)
- Registry: ghcr.io/nitrobass24/seedsync
src/
├── angular/ # Angular 21 frontend
├── python/ # Python backend
├── docker/ # Docker build files
└── e2e/ # End-to-end tests
website/ # Docusaurus documentation site
- master - Stable release branch
- develop - Integration branch for all new work
All work MUST follow this branching discipline:
- Always start from
develop: Before writing any code, checkoutdevelopand pull latest:git checkout develop && git pull origin develop - Create a feature branch: Every task (feature, bugfix, refactor) gets its own branch off
develop:git checkout -b feat/short-description # or fix/short-description - Commit only to the feature branch: Never commit directly to
developormaster. - One concern per branch: Do not mix unrelated changes into the same branch. If you discover a separate issue while working, finish or stash your current work, then create a new branch for the other issue.
- Open a PR to
develop: When the work is complete, push the feature branch and open a PR targetingdevelop. Include a summary and test plan. - Do not carry dirty working-tree changes across branches: Before switching branches, either commit or stash. Never rely on uncommitted edits surviving a
git checkout.
When merging a PR or completing significant work, follow this release process:
Add a new version entry at the top with:
- Version number following semver (major.minor.patch)
- Date in YYYY-MM-DD format
- Sections: Changed, Added, Fixed, Removed, Security (as applicable)
Example:
## [0.10.0] - 2026-01-27
### Changed
- **Feature name** - Description of change
### Fixed
- **Bug name** - Description of fixIf the change relates to modernization tasks:
- Update task status (🔄 IN PROGRESS → ✅)
- Update version references
- Update architecture diagram if needed
Update the version in src/angular/package.json to match the release version. This is displayed on the About page.
# Commit all changes
git add CHANGELOG.md MODERNIZATION_PLAN.md src/angular/package.json
git commit -m "Release vX.Y.Z - Brief description"
git push origin master
# Create and push tag
git tag vX.Y.Z
git push origin vX.Y.ZThe CI workflow will automatically:
- Build multi-arch Docker images
- Push to ghcr.io
- Create GitHub release with auto-generated notes
After CI creates the release, update the release notes with detailed changelog:
gh release edit vX.Y.Z --repo nitrobass24/seedsync --notes "$(cat <<'EOF'
## What's Changed
### Fixed
- **Bug name** - Description of fix (#issue)
### Changed
- **Feature name** - Description of change
### Added
- **New feature** - Description
## Docker Pull
```bash
docker pull ghcr.io/nitrobass24/seedsync:X.Y.ZFull Changelog: https://github.com/nitrobass24/seedsync/compare/vPREV...vX.Y.Z EOF )"
Format should match CHANGELOG.md entries with:
- Section headers: Fixed, Changed, Added, Removed, Security
- Bold feature/bug names
- Issue references where applicable
- Always include a "Docker Pull" section with the `docker pull` command for the release version
### 6. Verify Release
- Check GitHub Actions completed successfully
- Verify image is available: `docker pull ghcr.io/nitrobass24/seedsync:X.Y.Z`
- Verify GitHub release notes are formatted correctly
## Version Numbering
- **Major** (X.0.0): Breaking changes, major rewrites
- **Minor** (0.X.0): New features, significant improvements (e.g., Angular upgrade)
- **Patch** (0.0.X): Bug fixes, minor updates
## Key Files
| File | Purpose |
|------|---------|
| `CHANGELOG.md` | Release history and notes |
| `MODERNIZATION_PLAN.md` | Project modernization status |
| `src/docker/build/docker-image/Dockerfile` | Multi-stage Docker build |
| `.github/workflows/ci.yml` | CI/CD pipeline |
| `.github/workflows/docs-pages.yml` | Documentation deployment |
| `website/` | Documentation site (Docusaurus) |
## CI/CD Workflows
### CI (`ci.yml`)
| Trigger | Build & Test | Publish Image | Create Release |
|---------|--------------|---------------|----------------|
| PR to master | ✅ | ❌ | ❌ |
| Push to master | ✅ | ❌ | ❌ |
| Push tag (v*.*.*) | ✅ | ✅ | ✅ |
- **Build & Test**: Builds Docker image and verifies container starts
- **Publish Image**: Pushes multi-arch image to ghcr.io (only on release tags)
- **Create Release**: Creates GitHub release with auto-generated notes (only on release tags)
### Docs (`docs-pages.yml`)
- Triggers only when `website/` directory changes
- Builds and deploys Docusaurus site to GitHub Pages
## Common Tasks
### Building Locally
```bash
make build # Build Docker image
make run # Run container
make logs # View logs
make stop # Stop container
cd src/angular && npx ng test # Angular Vitest unit tests
# Python tests run in Docker via CI (pytest in test-image)
# CI also runs: Docker build, container startup, web UI accessibilityEvery PR MUST include appropriate test changes. Tests are not optional — they ship with the code.
- Add unit tests for all new logic (services, components, utilities, handlers)
- Cover the happy path, edge cases, and error/validation paths
- If adding a new API endpoint, add integration tests using
WebTest/TestApp
- Add a test that reproduces the bug (fails before fix, passes after)
- If the bug was in untested code, add baseline tests for the surrounding logic
- Existing tests must continue to pass without modification (unless the refactor intentionally changes behavior)
- If refactoring reveals untested code, add tests for it
- Remove or update tests that cover the deleted code
- Do not leave dead test code behind
| Layer | Framework | Location | Runner |
|---|---|---|---|
| Angular unit tests | Vitest | src/angular/src/**/*.spec.ts |
cd src/angular && npx ng test |
| Python unit tests | unittest | src/python/tests/unittests/ |
pytest (in Docker test-image) |
| Python integration tests | unittest + WebTest | src/python/tests/integration/ |
pytest (in Docker test-image) |
- Angular: Use
describe/itfrom Vitest. Mock services withvi.fn(). UseTestBedfor component tests. Query DOM by text content or stable attributes, not positional selectors (nth-of-type). - Python: Use
unittest.TestCase. Useunittest.mock.MagicMock/patchfor mocking. Integration tests for web handlers usewebtest.TestAppwithBaseTestWebApp. - Naming: Test files mirror source files —
foo.service.ts→foo.service.spec.ts,controller.py→test_controller.py. - No flaky tests: Avoid
time.sleepin tests where possible. Usethreading.Eventor barriers for synchronization. Usetimeout_decoratorfor tests that might hang.
- Repo: github.com/nitrobass24/seedsync
- Docs: nitrobass24.github.io/seedsync
- Issues: Use for bug reports and feature requests