forked from pimoroni/enviroplus-python
-
Notifications
You must be signed in to change notification settings - Fork 0
Open
Description
⚙️ CI/CD: Automated Testing, Linting & Deployment Pipeline
Current State
- Manual deployment via SSH: edit script on Pi, restart service
- No automated tests
- No linting or code quality checks
- No version tagging or release management
- Dashboard deployed manually via WordPress base64 pipeline
Goal
Establish a professional CI/CD pipeline that ensures code quality, catches regressions, and automates deployment to the Raspberry Pi.
Proposed Pipeline
Phase 1: Code Quality (GitHub Actions)
- Python linting —
flake8orruffon every push - Type checking —
mypyfor critical modules - Import validation — ensure all imports resolve (mock hardware libs)
- Syntax check —
py_compileon all.pyfiles - Markdown linting —
markdownlintfor documentation - Pre-commit hooks — local developer checks before push
Phase 2: Testing Framework
- Unit tests —
pytestfor non-hardware logic (AQI calculation, alert thresholds, data formatting) - Mock sensor tests — simulate BME280, PMS5003, LTR559 readings
- MQTT payload tests — validate JSON structure and field types
- SQLite tests — verify 24h rolling storage, data retention
- Dashboard JS tests — Jest for gauge rendering, threshold logic
- Integration test — full pipeline mock (sensor → MQTT → dashboard)
Phase 3: Automated Deployment
- Git-based deploy — Pi pulls latest from GitHub on tagged release
- systemd service restart — automatic service restart after deploy
- Rollback mechanism — keep previous version, revert if health check fails
- Health check — verify MQTT publishing resumes within 30s of deploy
- Dashboard deploy — automated base64 encode + WordPress REST API POST
GitHub Actions Workflow
# .github/workflows/ci.yml
name: CI Pipeline
on: [push, pull_request]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.9'
- run: pip install ruff
- run: ruff check .
test:
runs-on: ubuntu-latest
needs: lint
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.9'
- run: pip install pytest paho-mqtt
- run: pytest tests/ -v
deploy:
runs-on: ubuntu-latest
needs: test
if: startsWith(github.ref, 'refs/tags/v')
steps:
- name: Deploy to Pi via SSH
uses: appleboy/ssh-action@v1
with:
host: ${{ secrets.PI_HOST }}
username: ${{ secrets.PI_USER }}
key: ${{ secrets.PI_SSH_KEY }}
script: |
cd ~/enviroplus-python
git pull origin master
sudo systemctl restart farcom-enviroRepository Structure Changes
enviroplus-python/
├── .github/
│ └── workflows/
│ ├── ci.yml # Lint + test on push
│ └── deploy.yml # Deploy on tag
├── tests/
│ ├── test_aqi.py # AQI calculation tests
│ ├── test_alerts.py # Threshold logic tests
│ ├── test_mqtt_payload.py # JSON payload validation
│ ├── test_sqlite.py # Database operations
│ └── conftest.py # Pytest fixtures + mocks
├── .pre-commit-config.yaml # Local pre-commit hooks
├── pyproject.toml # Ruff + pytest config
└── ...
GitHub Secrets Required
| Secret | Purpose |
|---|---|
PI_HOST |
Raspberry Pi hostname/IP |
PI_USER |
SSH username |
PI_SSH_KEY |
SSH private key for passwordless deploy |
WP_REST_TOKEN |
WordPress application password for dashboard deploy |
Testing Strategy for Hardware-Dependent Code
Since sensors can't run in GitHub Actions:
- Mock library —
unittest.mockto simulate sensor reads - Hardware abstraction — refactor sensor reads into injectable classes
- Data validation — test processing logic with known input/output pairs
- Separate concerns — isolate display, MQTT, storage from sensor reading
Success Criteria
- Every push triggers lint + test (green badge in README)
- Tagged releases auto-deploy to Pi
- Failed deploys auto-rollback
- Test coverage > 60% for non-hardware code
- Zero manual SSH needed for routine updates
Ref: #1 Roadmap — DevOps & Infrastructure
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels