Skip to content

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

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

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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