From 863cef5e64a8af6b429888d34e9dd8001ff2a1f2 Mon Sep 17 00:00:00 2001 From: oakkitten Date: Tue, 7 Jun 2022 23:04:13 +0100 Subject: [PATCH 1/3] =?UTF-8?q?Tests:=20use=20time=20machine=20to=20?= =?UTF-8?q?=E2=80=9Cpin=E2=80=9D=20Anki=20dependencies?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Packages anki and aqt do not pin their requirements, which breaks anki <= 2.1.49 because of protobuf major version bump. While it's possible to use requirements.txt as constraints, it might not be the best idea: * requirements.txt can’t be used as constraints without some careful sed’ding to remove hashes and extras; * its location changes between versions; * you can’t get this file for a pre-release version of Anki since these don't get git tags; * it’s rarely updated anyway and hence won’t reliably produce the environment that actual Anki uses. So use a pypi-timemachine, which prevents pip from using packages that were uploaded after a specified date. While the code is a tad complex, it feels slightly less hacky, and is likely to be producing more accurate environments. --- tox-install-command | 20 +++++++++++++++++++ tox.ini | 48 +++++++++++++++++++++++---------------------- 2 files changed, 45 insertions(+), 23 deletions(-) create mode 100644 tox-install-command diff --git a/tox-install-command b/tox-install-command new file mode 100644 index 0000000..d75f3f3 --- /dev/null +++ b/tox-install-command @@ -0,0 +1,20 @@ +#!/bin/bash + +set -eux +trap '[[ -v SERVER_PID ]] && pkill -P $SERVER_PID' EXIT +print_first_group() { perl -snle 'm/$re/; print $1; exit 0' -- -re="$1"; } + +envname="$1" +toxworkdir="$2" +packages=("${@:3}") + +version=$(print_first_group 'anki([\d\.a-z]+)' <<< "$envname") +upload_time=$(curl https://pypi.org/pypi/anki/json \ + | jq --arg v "$version" -r '.releases[$v][0].upload_time_iso_8601') +cutoff_time=$(date --utc -d "$upload_time +1 hour" '+%Y-%m-%dT%H:%M:%S') + +coproc SERVER { "$toxworkdir"/.tox/bin/python -um pypi_timemachine "$cutoff_time"; } +index_url=$(print_first_group '(http\S+)' <&"${SERVER[0]}") + +python -m pip install --index-url "$index_url" "anki==$version" "$AQT==$version" +python -m pip install "${packages[@]}" diff --git a/tox.ini b/tox.ini index a3def46..b1ba085 100644 --- a/tox.ini +++ b/tox.ini @@ -42,42 +42,44 @@ # QT_DEBUG_PLUGINS=1 # ANKIDEV=1 +# Note: pypi packages anki and aqt do not pin their dependencies. +# To tests against historically accurate dependencies, we use a “time machine” +# that prevents pip from using packages that were uploaded after a specified date. + [tox] minversion = 3.24 skipsdist = true skip_install = true -envlist = py38-anki{45,46,47,48,49},py39-anki{50qt5,50qt6} +requires = + pypi-timemachine +envlist = + py38-anki2.1.{45,46,47,48,49} + py39-anki2.1.50-qt{5,6} + +[testenv:.tox] +install_command = + python -m pip install {packages} [testenv] +install_command = + bash tox-install-command {envname} {toxworkdir} {packages} + commands = env HOME={envtmpdir}/home xvfb-run python -m pytest {posargs} + setenv = - anki50qt6: DISABLE_QT5_COMPAT=1 + DISABLE_QT5_COMPAT=1 + + !qt{5,6}: AQT=aqt + qt5: AQT=aqt[qt5] + qt6: AQT=aqt[qt6] + allowlist_externals = + bash env xvfb-run + deps = pytest==7.1.1 pytest-forked==1.4.0 pytest-anki @ git+https://github.com/oakkitten/pytest-anki.git@a0d27aa5 - - anki45: anki==2.1.45 - anki45: aqt==2.1.45 - - anki46: anki==2.1.46 - anki46: aqt==2.1.46 - - anki47: anki==2.1.47 - anki47: aqt==2.1.47 - - anki48: anki==2.1.48 - anki48: aqt==2.1.48 - - anki49: anki==2.1.49 - anki49: aqt==2.1.49 - - anki50qt5: anki==2.1.50 - anki50qt5: aqt[qt5]==2.1.50 - - anki50qt6: anki==2.1.50 - anki50qt6: aqt[qt6]==2.1.50 From b01dd47deca79249b2fa2695df25bf309d879897 Mon Sep 17 00:00:00 2001 From: oakkitten Date: Tue, 7 Jun 2022 23:41:47 +0100 Subject: [PATCH 2/3] Tests: Run CI tests in parallel --- .github/workflows/main.yml | 32 ---------------------- .github/workflows/tests.yml | 53 +++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 32 deletions(-) delete mode 100644 .github/workflows/main.yml create mode 100644 .github/workflows/tests.yml diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml deleted file mode 100644 index 72bf0ce..0000000 --- a/.github/workflows/main.yml +++ /dev/null @@ -1,32 +0,0 @@ -name: Tests - -on: [push, pull_request, workflow_dispatch] - -jobs: - run-tests: - name: Run tests - runs-on: ubuntu-latest - steps: - - name: Install dependencies - run: | - sudo apt-get update - sudo apt-get install -y pyqt5-dev-tools xvfb - - - name: Setup Python 3.8 - uses: actions/setup-python@v2 - with: - python-version: 3.8 - - - name: Setup Python 3.9 - uses: actions/setup-python@v2 - with: - python-version: 3.9 - - - name: Install tox - run: pip install tox - - - name: Checkout repository - uses: actions/checkout@v2 - - - name: Run tests - run: tox -- --forked --verbose \ No newline at end of file diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 0000000..4d2ac11 --- /dev/null +++ b/.github/workflows/tests.yml @@ -0,0 +1,53 @@ +name: Tests + +on: [push, pull_request, workflow_dispatch] + +jobs: + run-tests: + name: ${{ matrix.name }} + runs-on: ubuntu-latest + strategy: + matrix: + include: + - name: Anki 2.1.45 + python: 3.8 + environment: py38-anki2.1.45 + - name: Anki 2.1.46 + python: 3.8 + environment: py38-anki2.1.46 + - name: Anki 2.1.47 + python: 3.8 + environment: py38-anki2.1.47 + - name: Anki 2.1.48 + python: 3.8 + environment: py38-anki2.1.48 + - name: Anki 2.1.49 + python: 3.8 + environment: py38-anki2.1.49 + - name: Anki 2.1.50 (Qt5) + python: 3.9 + environment: py39-anki2.1.50-qt5 + - name: Anki 2.1.50 (Qt6) + python: 3.9 + environment: py39-anki2.1.50-qt6 + fail-fast: false + + steps: + - name: Install dependencies + run: | + sudo apt-get update + sudo apt-get install -y pyqt5-dev-tools xvfb jq + + - name: Setup Python ${{ matrix.python }} + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python }} + + - name: Install tox + run: pip install tox + + - name: Checkout repository + uses: actions/checkout@v2 + + - name: Run tests + run: tox -vvve ${{ matrix.environment }} -- --forked --verbose From cfcb1616ce23bb16714f9e577b5ac624179f7cd6 Mon Sep 17 00:00:00 2001 From: oakkitten Date: Tue, 7 Jun 2022 23:46:52 +0100 Subject: [PATCH 3/3] Tests: add environments for Anki 2.1.51 to 53 --- .github/workflows/tests.yml | 18 ++++++++++++++++++ tox.ini | 2 +- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 4d2ac11..537d0ea 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -30,6 +30,24 @@ jobs: - name: Anki 2.1.50 (Qt6) python: 3.9 environment: py39-anki2.1.50-qt6 + - name: Anki 2.1.51 (Qt5) + python: 3.9 + environment: py39-anki2.1.51-qt5 + - name: Anki 2.1.51 (Qt6) + python: 3.9 + environment: py39-anki2.1.51-qt6 + - name: Anki 2.1.52 (Qt5) + python: 3.9 + environment: py39-anki2.1.52-qt5 + - name: Anki 2.1.52 (Qt6) + python: 3.9 + environment: py39-anki2.1.52-qt6 + - name: Anki 2.1.53 (Qt5) + python: 3.9 + environment: py39-anki2.1.53-qt5 + - name: Anki 2.1.53 (Qt6) + python: 3.9 + environment: py39-anki2.1.53-qt6 fail-fast: false steps: diff --git a/tox.ini b/tox.ini index b1ba085..015f09f 100644 --- a/tox.ini +++ b/tox.ini @@ -54,7 +54,7 @@ requires = pypi-timemachine envlist = py38-anki2.1.{45,46,47,48,49} - py39-anki2.1.50-qt{5,6} + py39-anki2.1.{50,51,52,53}-qt{5,6} [testenv:.tox] install_command =