diff --git a/.github/workflows/testing.yml b/.github/workflows/ci.yml similarity index 57% rename from .github/workflows/testing.yml rename to .github/workflows/ci.yml index 4c9514e..67ad87e 100644 --- a/.github/workflows/testing.yml +++ b/.github/workflows/ci.yml @@ -1,4 +1,4 @@ -name: Testing +name: CI on: push: @@ -9,64 +9,8 @@ on: workflow_call: jobs: - test: - name: Test Python ${{ matrix.python-version }} on ${{ matrix.os }} - runs-on: ${{ matrix.os }} - strategy: - fail-fast: false - matrix: - os: [ubuntu-latest] - python-version: ["3.11", "3.12"] - - steps: - - name: Checkout code - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v5 - with: - python-version: ${{ matrix.python-version }} - - - name: Install uv - uses: astral-sh/setup-uv@v5 - with: - enable-cache: true - - - name: Install dependencies - run: | - uv sync --all-extras - - - name: Download spaCy models - run: | - uv run python -m spacy download en_core_web_sm - uv run python -m spacy download ja_core_news_sm - uv run python -m spacy download xx_ent_wiki_sm - - - name: Download NLTK data - run: | - uv run python -m nltk.downloader punkt - uv run python -m nltk.downloader averaged_perceptron_tagger - uv run python -m nltk.downloader maxent_ne_chunker - uv run python -m nltk.downloader words - - - name: Run tests - run: | - uv run pytest tests/ -v --tb=short --maxfail=5 - - - name: Upload test results - if: always() - uses: actions/upload-artifact@v4 - with: - name: test-results-${{ matrix.os }}-${{ matrix.python-version }} - path: | - .pytest_cache/ - test-results/ - retention-days: 7 - - security: - name: Security Checks + lint: + name: Lint and Format Check runs-on: ubuntu-latest steps: @@ -84,16 +28,24 @@ jobs: enable-cache: true - name: Install dependencies - run: | - uv sync --extra dev + run: uv sync --extra dev + + - name: Run ty type checking + run: uv run ty check - - name: Run bandit security checks + - name: Run ruff run: | - uv run bandit -c bandit.yaml -r src/ + uv run ruff check src/ tests/ + uv run ruff format --check src/ tests/ - coverage: - name: Test Coverage - runs-on: ubuntu-latest + test: + name: Test Python ${{ matrix.python-version }} on ${{ matrix.os }} + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest] + python-version: ["3.11", "3.12", "3.13"] steps: - name: Checkout code @@ -101,10 +53,10 @@ jobs: with: fetch-depth: 0 - - name: Set up Python + - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: ${{ matrix.python-version }} - name: Install uv uses: astral-sh/setup-uv@v5 @@ -112,8 +64,7 @@ jobs: enable-cache: true - name: Install dependencies - run: | - uv sync --all-extras + run: uv sync --all-extras - name: Download spaCy models run: | @@ -128,18 +79,30 @@ jobs: uv run python -m nltk.downloader maxent_ne_chunker uv run python -m nltk.downloader words - - name: Run tests with coverage - # --cov-fail-under enforces the overall regression floor (configured in - # pyproject.toml [tool.coverage.report] fail_under = 33). + - name: Run tests + # On 3.12 also collect coverage in the same invocation to avoid running + # the suite twice. --cov-fail-under enforces the overall regression floor + # (configured in pyproject.toml [tool.coverage.report] fail_under = 33). # Patch coverage (new/changed lines ≥ 80%) is enforced by Codecov below. run: | - uv run pytest tests/ \ - --cov=src/risk_assessment \ - --cov-report=xml \ - --cov-report=html \ - --cov-report=term-missing + EXTRA_ARGS="" + if [ "${{ matrix.python-version }}" = "3.12" ]; then + EXTRA_ARGS="--cov=src/risk_assessment --cov-report=xml --cov-report=html --cov-report=term-missing" + fi + uv run pytest tests/ -v --tb=short --maxfail=5 \ + --junitxml=test-results/junit-${{ matrix.os }}-${{ matrix.python-version }}.xml \ + $EXTRA_ARGS + + - name: Upload test results + if: always() + uses: actions/upload-artifact@v4 + with: + name: test-results-${{ matrix.os }}-${{ matrix.python-version }} + path: test-results/ + retention-days: 7 - name: Upload coverage to Codecov + if: matrix.python-version == '3.12' uses: codecov/codecov-action@v5 with: token: ${{ secrets.CODECOV_TOKEN }} @@ -148,8 +111,8 @@ jobs: verbose: true - name: Upload HTML coverage report as artifact + if: always() && matrix.python-version == '3.12' uses: actions/upload-artifact@v4 - if: always() with: name: coverage-html-report path: htmlcov/ diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 265cf87..ad2a14a 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -15,7 +15,6 @@ jobs: runs-on: ubuntu-latest permissions: security-events: write - actions: read contents: read steps: diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml deleted file mode 100644 index 8a1f368..0000000 --- a/.github/workflows/lint.yml +++ /dev/null @@ -1,45 +0,0 @@ -name: Lint - -on: - push: - branches: [ main ] - pull_request: - branches: [ main ] - workflow_dispatch: - workflow_call: - -jobs: - lint: - name: Lint and Format Check - runs-on: ubuntu-latest - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Install uv - uses: astral-sh/setup-uv@v5 - with: - enable-cache: true - - - name: Install dependencies - run: | - uv sync --extra dev - - - name: Run ruff linter - run: | - uv run ruff check src/ tests/ - - - name: Run ruff formatter check - run: | - uv run ruff format --check src/ tests/ - - - name: Run ty type checking - run: | - uv run ty check - continue-on-error: true diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 0270721..99e0537 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -1,30 +1,23 @@ name: Publish to PyPI on: - push: - tags: - - "v*" + release: + types: [published] workflow_dispatch: permissions: contents: read jobs: - test: - name: Reuse testing workflow - uses: ./.github/workflows/testing.yml + ci: + name: Run CI checks + uses: ./.github/workflows/ci.yml secrets: inherit - lint: - name: Reuse lint workflow - uses: ./.github/workflows/lint.yml - publish: name: Build and publish package to PyPI runs-on: ubuntu-latest - needs: - - test - - lint + needs: ci environment: name: pypi url: https://pypi.org/p/readi-privacy @@ -38,11 +31,6 @@ jobs: with: fetch-depth: 0 - - name: Ensure tag points to main history - run: | - git fetch origin main --depth=1 - git merge-base --is-ancestor "${GITHUB_SHA}" "origin/main" - - name: Set up Python uses: actions/setup-python@v5 with: @@ -52,8 +40,7 @@ jobs: uses: astral-sh/setup-uv@v5 - name: Build distributions - run: | - uv build + run: uv build - name: Publish distributions to PyPI uses: pypa/gh-action-pypi-publish@release/v1