- Python 3.8 or later
- uv - Fast Python package installer
- git
curl -LsSf https://astral.sh/uv/install.sh | sh# Clone repository
git clone https://github.com/feelpp/apt.git
cd apt
# Run setup script
./setup-dev.sh
# Or manually:
uv venv
source .venv/bin/activate
uv pip install -e ".[dev]"# Format code
make format
# Run linter
make lint
# Type check
make type-check
# Run all quality checks
make quality# Run all tests
make test
# Run specific test
pytest tests/test_publisher.py -v
# Run with coverage
pytest --cov=feelpp_aptly_publisher --cov-report=html# Build distribution packages
make build
# Check build
ls -lh dist/We use Black for consistent code formatting:
# Format all code
black src/ tests/
# Check formatting without changes
black --check src/ tests/Configuration: pyproject.toml
- Line length: 120
- Target versions: Python 3.8+
We use Flake8 for code linting:
# Lint all code
flake8 src/ tests/Configuration: .flake8
- Max line length: 120
- Ignored errors: E203 (whitespace before ':'), W503 (line break before binary operator)
- Plugins: flake8-bugbear, flake8-comprehensions
We use Mypy for static type checking:
# Type check
mypy src/Configuration: pyproject.toml
- Python version: 3.8
- Warn on unused configs
- Return types checked
apt/
├── src/
│ └── feelpp_aptly_publisher/
│ ├── __init__.py # Package initialization
│ ├── __main__.py # CLI entry point
│ ├── cli.py # Command-line interface
│ ├── publisher.py # Core publishing logic
│ └── py.typed # Type stub marker
├── tests/
│ ├── __init__.py
│ ├── test_publisher.py # Publisher tests
│ └── test_cli.py # CLI tests
├── examples/
│ ├── aptly.conf # Example aptly config
│ └── publish_example.sh # Example usage script
├── .github/
│ └── workflows/
│ ├── quality.yml # Quality checks CI
│ ├── build.yml # Build and test CI
│ └── publish.yml # PyPI publishing CI
├── pyproject.toml # Project metadata and config
├── Makefile # Development commands
├── setup-dev.sh # Development setup script
├── .flake8 # Flake8 configuration
├── .gitignore # Git ignore rules
└── README_PYPI.md # Package README
Runs on every push and PR:
- Black formatting check
- Flake8 linting
- Mypy type checking
- Pytest with coverage
- Tests on Python 3.8-3.12
Runs on every push and PR:
- Builds package
- Validates with twine
- Tests installation on multiple Python versions
- Tests CLI functionality
Runs on releases or manual trigger:
- Builds package
- Publishes to PyPI (on release)
- Publishes to Test PyPI (manual)
- Uses trusted publishing (no API tokens needed)
# Build
make build
# Publish to Test PyPI
make test-publish
# Test installation
pip install --index-url https://test.pypi.org/simple/ feelpp-aptly-publisher- Update version in
pyproject.toml - Commit and push
- Create GitHub release with tag
v1.0.0 - CI automatically publishes to PyPI
# Build and publish
make publish
# Or step by step
make build
twine check dist/*
twine upload dist/*# Install in development mode
uv pip install -e .
# Test help
feelpp-apt-publish --help
# Test version
feelpp-apt-publish --version
# Test with dry-run (without actual publishing)
feelpp-apt-publish \
--component test \
--channel testing \
--distro noble \
--verbosefrom feelpp_aptly_publisher import AptlyPublisher
pub = AptlyPublisher(
component="test",
distro="noble",
channel="testing",
verbose=True,
)
# This would publish, so be careful
# pub.publish(debs_dir="./packages/")- Create feature branch:
git checkout -b feature/my-feature - Write code with tests
- Run quality checks:
make quality - Run tests:
make test - Commit and push
- Create pull request
- Create bugfix branch:
git checkout -b fix/issue-123 - Write failing test
- Fix the bug
- Verify test passes
- Run quality checks
- Commit and push
- Create pull request
# Update all dependencies
uv pip install --upgrade -e ".[dev]"
# Update specific dependency
uv pip install --upgrade black
# Freeze requirements
uv pip freeze > requirements-dev.txtIf you see import errors in your IDE:
# Reinstall in development mode
uv pip install -e .
# Or set PYTHONPATH
export PYTHONPATH="${PYTHONPATH}:$(pwd)/src"# Run with verbose output
pytest -vv
# Run specific test
pytest tests/test_publisher.py::test_publisher_init -v
# Debug with pdb
pytest --pdb# Run mypy with verbose output
mypy --show-error-codes src/
# Ignore specific error
# type: ignore[error-code]Follow Conventional Commits:
feat: add support for multiple architectures
fix: handle missing GPG key gracefully
docs: update README with examples
test: add tests for error handling
ci: update GitHub Actions to use uv
feature/description- New featuresfix/issue-number- Bug fixesdocs/description- Documentation updatesrefactor/description- Code refactoringtest/description- Test improvements
- Update version in
src/feelpp_aptly_publisher/__init__.py - Update version in
pyproject.toml - Update CHANGELOG (if exists)
- Commit:
git commit -m "chore: bump version to 1.1.0" - Tag:
git tag v1.1.0 - Push:
git push && git push --tags - Create GitHub release
- CI publishes to PyPI automatically