name: CI on: push: branches: [main] pull_request: branches: [main] jobs: test-linux: name: Tests (Linux, Python ${{ matrix.python-version }}) runs-on: ubuntu-latest strategy: fail-fast: false matrix: python-version: ["3.9", "3.11", "3.12"] steps: - name: Checkout uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} cache: pip cache-dependency-path: | requirements.txt requirements-dev.txt - name: Install dependencies run: | python -m pip install --upgrade pip pip install -r requirements-dev.txt - name: Syntax check run: | python -m py_compile tagsync.py python -c "import pathlib, py_compile; [py_compile.compile(str(p), doraise=True) for p in pathlib.Path('tagsync').rglob('*.py')]" - name: CLI smoke test run: | python tagsync.py --help python tagsync.py status - name: Run tests with coverage run: | pytest --cov=tagsync --cov-report=term-missing --cov-report=xml - name: Upload coverage artifact if: matrix.python-version == '3.12' uses: actions/upload-artifact@v3 with: name: coverage-xml path: coverage.xml retention-days: 14 test-macos: name: Tests (macOS) runs-on: macos-latest # macOS runners are more expensive — only run on main-branch pushes # and PRs that touch platform_macos.py or core logic. if: github.event_name == 'push' || contains(github.event.pull_request.labels.*.name, 'platform') steps: - name: Checkout uses: actions/checkout@v4 - name: Set up Python uses: actions/setup-python@v5 with: python-version: "3.12" - name: Install dependencies run: pip install -r requirements-dev.txt - name: Run tests run: pytest -v test-windows: name: Tests (Windows) runs-on: windows-latest if: github.event_name == 'push' || contains(github.event.pull_request.labels.*.name, 'platform') steps: - name: Checkout uses: actions/checkout@v4 - name: Set up Python uses: actions/setup-python@v5 with: python-version: "3.12" - name: Install dependencies run: pip install -r requirements-dev.txt - name: Run tests run: pytest -v