Skip to content

Merge dev into main for release sync #346

Merge dev into main for release sync

Merge dev into main for release sync #346

Workflow file for this run

name: CI
on:
push:
branches: [ main, dev ]
pull_request:
branches: [ main, dev ]
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
defaults:
run:
shell: bash
env:
FORCE_COLOR: "1"
jobs:
changelog-check:
name: CHANGELOG Check
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/dev' || github.base_ref == 'dev'
steps:
- name: Checkout code
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Check for CHANGELOG updates
run: |
if [ "${{ github.event_name }}" = "pull_request" ]; then
BASE="origin/${{ github.base_ref }}"
else
LAST_NIGHTLY=$(git tag --list "nightly-*" --sort=-version:refname | head -n 1)
BASE="${LAST_NIGHTLY:-HEAD~1}"
fi
CHANGED_FILES=$(git diff --name-only "$BASE"..HEAD)
SRC_CHANGED=$(echo "$CHANGED_FILES" | grep -E "^src/" || true)
CHANGELOG_CHANGED=$(echo "$CHANGED_FILES" | grep -E "^CHANGELOG\.md$" || true)
if [ -n "$SRC_CHANGED" ] && [ -z "$CHANGELOG_CHANGED" ]; then
echo "::warning::⚠️ Source files changed but CHANGELOG.md was not updated!"
exit 0
elif [ -n "$SRC_CHANGED" ] && [ -n "$CHANGELOG_CHANGED" ]; then
echo "✅ CHANGELOG.md updated. Good work!"
else
echo "ℹ️ No source changes detected."
fi
lint:
name: Lint
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Ruff format check
uses: astral-sh/ruff-action@v3
with:
args: format --check
- name: Ruff lint
uses: astral-sh/ruff-action@v3
with:
args: check
tests:
name: Tests (Ubuntu, Python ${{ matrix.python-version }})
runs-on: ubuntu-latest
needs: lint
strategy:
fail-fast: false
matrix:
python-version: ["3.11", "3.12"]
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: ${{ matrix.python-version }}
cache: pip
- name: Install dependencies
run: |
python -m pip install --upgrade pip
# Use prebuilt wx wheels only — never build from source.
# extras.wxpython.org provides Linux wheels for supported Python versions.
pip install \
-f https://extras.wxpython.org/wxPython4/extras/linux/gtk3/ubuntu-24.04 \
--only-binary wxPython \
-e ".[dev]"
- name: Run tests with coverage
env:
PYTHONPATH: src
run: |
mkdir -p reports
pytest tests/ -n auto -v --tb=short -m "not integration" \
--junitxml=reports/junit.xml \
--cov=src/portkeydrop \
--cov-report=xml:reports/coverage.xml \
--cov-report=term-missing
- name: Upload test report
if: always()
uses: actions/upload-artifact@v6
with:
name: junit-${{ matrix.python-version }}
path: reports/junit.xml
retention-days: 7
- name: Upload coverage report
if: always()
uses: actions/upload-artifact@v6
with:
name: coverage-${{ matrix.python-version }}
path: reports/coverage.xml
retention-days: 7
coverage-gate:
name: Coverage Gate
runs-on: ubuntu-latest
needs: tests
if: github.event_name == 'pull_request'
steps:
- name: Checkout code
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: "3.11"
cache: pip
- name: Install diff-cover
run: pip install diff-cover>=9.0.0
- name: Download coverage report
uses: actions/download-artifact@v7
with:
name: coverage-3.11
path: reports
- name: Check coverage on changed lines
run: |
diff-cover reports/coverage.xml \
--compare-branch=origin/${{ github.base_ref }} \
--fail-under=80 \
--diff-range-notation='..' \
--exclude '*/portkeydrop/ui/*' \
--exclude '*/portkeydrop/dialogs/*' \
--exclude '*/portkeydrop/importers/winscp.py'
echo "✅ New code meets coverage threshold!"