Skip to content

[DEVOPS] CI/CD: Automated testing, linting & deployment pipeline #7

@farcomiot

Description

@farcomiot

⚙️ 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 lintingflake8 or ruff on every push
  • Type checkingmypy for critical modules
  • Import validation — ensure all imports resolve (mock hardware libs)
  • Syntax checkpy_compile on all .py files
  • Markdown lintingmarkdownlint for documentation
  • Pre-commit hooks — local developer checks before push

Phase 2: Testing Framework

  • Unit testspytest for 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-enviro

Repository 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 libraryunittest.mock to 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

  1. Every push triggers lint + test (green badge in README)
  2. Tagged releases auto-deploy to Pi
  3. Failed deploys auto-rollback
  4. Test coverage > 60% for non-hardware code
  5. Zero manual SSH needed for routine updates

Ref: #1 Roadmap — DevOps & Infrastructure

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions