diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fa319ba..f0ef1bb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,8 +7,8 @@ on: branches: [ main, develop ] jobs: - code-quality: - name: Code Quality + pre-commit: + name: Pre-commit Checks runs-on: ubuntu-latest strategy: matrix: @@ -26,97 +26,16 @@ jobs: uses: actions/cache@v4 with: path: ~/.cache/pip - key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements*.txt', 'pyproject.toml') }} + key: ${{ runner.os }}-pip-${{ matrix.python-version }}-${{ hashFiles('**/requirements*.txt', 'pyproject.toml') }} restore-keys: | - ${{ runner.os }}-pip- + ${{ runner.os }}-pip-${{ matrix.python-version }}- - name: Install dependencies run: | python -m pip install --upgrade pip pip install -e ".[dev]" - - name: Code formatting with Black - run: | - black --check --diff meshcore_mqtt/ tests/ - - - name: Linting with Flake8 - run: | - flake8 meshcore_mqtt/ tests/ - - - name: Type checking with MyPy - run: | - mypy meshcore_mqtt/ tests/ - - - name: Import sorting with isort - run: | - isort --check-only --diff meshcore_mqtt/ tests/ - - test: - name: Tests - runs-on: ubuntu-latest - strategy: - matrix: - python-version: ["3.11", "3.12"] - - steps: - - uses: actions/checkout@v4 - - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v5 + - name: Run pre-commit + uses: pre-commit/action@v3.0.1 with: - python-version: ${{ matrix.python-version }} - - - name: Cache pip dependencies - uses: actions/cache@v4 - with: - path: ~/.cache/pip - key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements*.txt', 'pyproject.toml') }} - restore-keys: | - ${{ runner.os }}-pip- - - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -e ".[dev]" - - - name: Run tests with pytest - run: | - pytest -v --cov=meshcore_mqtt --cov-report=xml --cov-report=term-missing - - - name: Upload coverage to Codecov - uses: codecov/codecov-action@v3 - with: - file: ./coverage.xml - flags: unittests - name: codecov-umbrella - fail_ci_if_error: false - - build-test: - name: Build Test - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v4 - - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install build dependencies - run: | - python -m pip install --upgrade pip - pip install build twine - - - name: Build package - run: | - python -m build - - - name: Check package - run: | - twine check dist/* - - - name: Test installation - run: | - pip install dist/*.whl - python -c "import meshcore_mqtt; print('Package installed successfully')" + extra_args: --all-files diff --git a/.github/workflows/code-quality.yml b/.github/workflows/code-quality.yml deleted file mode 100644 index a45d8c8..0000000 --- a/.github/workflows/code-quality.yml +++ /dev/null @@ -1,72 +0,0 @@ -name: Code Quality - -on: - push: - branches: [ main, develop ] - pull_request: - branches: [ main, develop ] - -jobs: - lint: - name: Lint and Format Check - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v4 - - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Cache pip dependencies - uses: actions/cache@v4 - with: - path: ~/.cache/pip - key: ${{ runner.os }}-pip-lint-${{ hashFiles('**/requirements-dev.txt') }} - restore-keys: | - ${{ runner.os }}-pip-lint- - - - name: Install linting dependencies - run: | - python -m pip install --upgrade pip - pip install black flake8 mypy isort bandit - - - name: Check code formatting with Black - run: | - echo "::group::Black formatting check" - black --check --diff --color meshcore_mqtt/ tests/ - echo "::endgroup::" - - - name: Check import sorting with isort - run: | - echo "::group::Import sorting check" - isort --check-only --diff meshcore_mqtt/ tests/ - echo "::endgroup::" - - - name: Lint with Flake8 - run: | - echo "::group::Flake8 linting" - flake8 meshcore_mqtt/ tests/ --statistics - echo "::endgroup::" - - - name: Type check with MyPy - run: | - echo "::group::MyPy type checking" - # Install package dependencies for type checking - pip install -r requirements-dev.txt - mypy meshcore_mqtt/ tests/ - echo "::endgroup::" - - - name: Security check with Bandit - run: | - echo "::group::Bandit security scan" - bandit -r meshcore_mqtt/ -ll - echo "::endgroup::" - - # - name: Dependency security check with Safety - # run: | - # echo "::group::Safety dependency check" - # pip install -r requirements.txt - # safety check - # echo "::endgroup::" diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml deleted file mode 100644 index ead4ddf..0000000 --- a/.github/workflows/test.yml +++ /dev/null @@ -1,133 +0,0 @@ -name: Tests - -on: - push: - branches: [ main, develop ] - pull_request: - branches: [ main, develop ] - -jobs: - test: - name: Test Suite - runs-on: ${{ matrix.os }} - strategy: - fail-fast: false - matrix: - os: [ubuntu-latest] - python-version: ["3.11", "3.12"] - - steps: - - uses: actions/checkout@v4 - - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v5 - with: - python-version: ${{ matrix.python-version }} - - - name: Cache pip dependencies - uses: actions/cache@v4 - with: - path: | - ~/.cache/pip - ~/.local/share/virtualenvs - key: ${{ runner.os }}-pip-${{ matrix.python-version }}-${{ hashFiles('**/requirements*.txt') }} - restore-keys: | - ${{ runner.os }}-pip-${{ matrix.python-version }}- - - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -r requirements.txt - pip install -r requirements-dev.txt - - - name: Run tests with pytest - run: | - pytest -v --tb=short --cov=meshcore_mqtt --cov-report=xml --cov-report=term-missing --cov-report=html - - - name: Generate coverage report - if: matrix.os == 'ubuntu-latest' && matrix.python-version == '3.12' - run: | - echo "## Test Coverage Report" >> $GITHUB_STEP_SUMMARY - echo "```" >> $GITHUB_STEP_SUMMARY - coverage report --show-missing >> $GITHUB_STEP_SUMMARY - echo "```" >> $GITHUB_STEP_SUMMARY - - - name: Upload coverage to Codecov - if: matrix.os == 'ubuntu-latest' && matrix.python-version == '3.12' - uses: codecov/codecov-action@v3 - with: - file: ./coverage.xml - flags: unittests - name: codecov-umbrella - fail_ci_if_error: false - - - name: Archive coverage reports - if: matrix.os == 'ubuntu-latest' && matrix.python-version == '3.12' - uses: actions/upload-artifact@v4 - with: - name: coverage-report - path: htmlcov/ - - - name: Test CLI functionality - run: | - # Test CLI help - python -m meshcore_mqtt.main --help - - # Test version info (if available) - python -c "import meshcore_mqtt; print('Package version check passed')" - - test-examples: - name: Test Configuration Examples - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v4 - - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -r requirements.txt - pip install pyyaml - - - name: Validate JSON configuration examples - run: | - python -c " - import json - with open('config.example.json', 'r') as f: - config = json.load(f) - print('✓ config.example.json is valid JSON') - print(f'✓ Contains {len(config)} top-level keys') - " - - - name: Validate YAML configuration examples - run: | - python -c " - import yaml - with open('config.example.yaml', 'r') as f: - config = yaml.safe_load(f) - print('✓ config.example.yaml is valid YAML') - print(f'✓ Contains {len(config)} top-level keys') - " - - - name: Test configuration loading - run: | - python -c " - from meshcore_mqtt.config import Config - - # Test JSON config loading - config_json = Config.from_file('config.example.json') - print('✓ JSON configuration loads successfully') - print(f'✓ MQTT broker: {config_json.mqtt.broker}') - print(f'✓ Events configured: {len(config_json.meshcore.events)}') - - # Test YAML config loading - config_yaml = Config.from_file('config.example.yaml') - print('✓ YAML configuration loads successfully') - print(f'✓ MQTT broker: {config_yaml.mqtt.broker}') - print(f'✓ Events configured: {len(config_yaml.meshcore.events)}') - "