name: Tests on: push: branches: [main] pull_request: branches: [main] jobs: lint: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-python@v5 with: python-version: "3.11" - name: Install tox run: pip install tox - name: Lint (ruff via tox) run: tox -e lint test: runs-on: ubuntu-latest needs: lint # Required for publish-unit-test-result-action to post check runs and PR comments permissions: contents: read checks: write pull-requests: write steps: - uses: actions/checkout@v4 - uses: actions/setup-python@v5 with: python-version: "3.11" - name: Cache pip uses: actions/cache@v4 with: path: ~/.cache/pip key: pip-${{ hashFiles('poetry.lock') }} restore-keys: pip- - name: Install tox run: pip install tox - name: Run tests (via tox) id: tests run: tox -e ci # Posts a check annotation + PR comment showing pass/fail counts. # Visible in the GitHub mobile app under Checks and in PR conversations. - name: Publish test results uses: EnricoMi/publish-unit-test-result-action@v2 if: always() with: files: reports/junit.xml check_name: "pytest results" comment_title: "Test Results" report_individual_runs: true - name: Enforce coverage floor (60%) if: always() && steps.tests.outcome == 'success' run: | python -c " import xml.etree.ElementTree as ET, sys tree = ET.parse('reports/coverage.xml') rate = float(tree.getroot().attrib['line-rate']) * 100 print(f'Coverage: {rate:.1f}%') if rate < 60: print(f'FAIL: Coverage {rate:.1f}% is below 60% floor') sys.exit(1) print('PASS: Coverage is above 60% floor') " # Coverage report available as a downloadable artifact in the Actions tab - name: Upload coverage report uses: actions/upload-artifact@v4 if: always() with: name: coverage-report path: reports/coverage.xml retention-days: 14 docker-build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Build Docker image run: DOCKER_BUILDKIT=1 docker build -t timmy-time:ci .