diff --git a/.github/actions/setup-python/action.yml b/.github/actions/setup-python/action.yml deleted file mode 100644 index 921d96b61..000000000 --- a/.github/actions/setup-python/action.yml +++ /dev/null @@ -1,23 +0,0 @@ -name: Set up Python -input: -inputs: - python-version: - required: true - -runs: - using: composite - - steps: - - name: Set up the Python environment - uses: actions/setup-python@v5 - with: - python-version: ${{ matrix.python-version }} - cache: 'pip' - - - name: Install Python dependencies - run: pip install -r python/requirements.txt - shell: bash - - - name: Set up environment variables - run: echo PYTHONPATH=$PYTHONPATH:/`pwd`/python:/`pwd`/python/react-series-data-viewer >> $GITHUB_ENV - shell: bash diff --git a/.github/workflows/loristest.yml b/.github/workflows/loristest.yml index 0710dfbdf..a52425121 100644 --- a/.github/workflows/loristest.yml +++ b/.github/workflows/loristest.yml @@ -1,8 +1,6 @@ name: LORIS Test Suite -on: - - push - - pull_request +on: workflow_dispatch jobs: docker: diff --git a/.github/workflows/python-checks.yml b/.github/workflows/python-checks.yml index fddf5c1f1..fecc6720d 100644 --- a/.github/workflows/python-checks.yml +++ b/.github/workflows/python-checks.yml @@ -1,12 +1,46 @@ name: Python checks -on: - - push - - pull_request +on: pull_request jobs: + docker: + name: Docker + runs-on: ubuntu-latest + + strategy: + matrix: + python-version: ["3.11", "3.12"] + + steps: + - name: Check out LORIS-MRI + uses: actions/checkout@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v2 + + - name: Build Docker image + id: build-and-push + uses: docker/build-push-action@v4 + with: + context: . + file: ./test/python.Dockerfile + build-args: | + PYTHON_VERSION=${{ matrix.python-version }} + WORKSPACE=/workspace + tags: loris-python:${{ matrix.python-version }} + cache-from: type=gha,scope=loris-python-${{ matrix.python-version }} + cache-to: type=gha,scope=loris-python-${{ matrix.python-version }} + outputs: type=docker,dest=/tmp/loris-python-${{ matrix.python-version }}.tar + + - name: Upload Docker image + uses: actions/upload-artifact@v4 + with: + name: loris-python-${{ matrix.python-version }} + path: /tmp/loris-python-${{ matrix.python-version }}.tar + ruff: - name: "Ruff" + name: Ruff + needs: docker runs-on: ubuntu-latest strategy: @@ -14,19 +48,26 @@ jobs: python-version: ["3.11", "3.12"] steps: - - name: Check out LORIS-MRI - uses: actions/checkout@v4 + - name: Checkout LORIS-MRI + uses: actions/checkout@v4 - - name: Set up Python - uses: ./.github/actions/setup-python - with: - python-version: ${{ matrix.python-version }} + - name: Download Docker image + uses: actions/download-artifact@v4 + with: + name: loris-python-${{ matrix.python-version }} + path: /tmp - - name: Run Ruff - run: ruff check --output-format=github + - name: Load Docker image + run: docker load -i /tmp/loris-python-${{ matrix.python-version }}.tar + + - name: Run Ruff + run: | + docker run -v ${{ github.workspace }}:/workspace -w /workspace loris-python:${{ matrix.python-version }} \ + ruff check --output-format=github pyright-strict: - name: "Pyright strict" + name: Pyright strict + needs: docker runs-on: ubuntu-latest strategy: @@ -37,20 +78,23 @@ jobs: - name: Check out LORIS-MRI uses: actions/checkout@v4 - - name: Set up Python - uses: ./.github/actions/setup-python + - name: Download Docker image + uses: actions/download-artifact@v4 with: - python-version: ${{ matrix.python-version }} + name: loris-python-${{ matrix.python-version }} + path: /tmp + + - name: Load Docker image + run: docker load -i /tmp/loris-python-${{ matrix.python-version }}.tar - # Like in the other Pyright run, the `jq` arcane is used to translate the errors from JSON to - # the GitHub actions format - name: Run Pyright run: | - pyright --outputjson | jq -r '.generalDiagnostics[] | "::error file=\(.file),line=\(.range.start.line),col=\(.range.start.character)::\(.message)"' - (exit ${PIPESTATUS[0]}) + docker run -v ${{ github.workspace }}:/workspace -w /workspace loris-python:${{ matrix.python-version }} bash -c \ + "set -o pipefail && pyright --outputjson | bash test/pyright_to_github.sh" pyrigh-global: - name: "Pyright global" + name: Pyright global + needs: docker runs-on: ubuntu-latest strategy: @@ -58,16 +102,19 @@ jobs: python-version: ["3.11", "3.12"] steps: - - name: Check out LORIS-MRI - uses: actions/checkout@v4 - - - name: Set up Python - uses: ./.github/actions/setup-python - with: - python-version: ${{ matrix.python-version }} - - - name: Run Pyright - run: | - cd test - pyright --outputjson | jq -r '.generalDiagnostics[] | "::error file=\(.file),line=\(.range.start.line),col=\(.range.start.character)::\(.message)"' - (exit ${PIPESTATUS[0]}) + - name: Check out LORIS-MRI + uses: actions/checkout@v4 + + - name: Download Docker image + uses: actions/download-artifact@v4 + with: + name: loris-python-${{ matrix.python-version }} + path: /tmp + + - name: Load Docker image + run: docker load -i /tmp/loris-python-${{ matrix.python-version }}.tar + + - name: Run Pyright + run: | + docker run -v ${{ github.workspace }}:/workspace -w /workspace loris-python:${{ matrix.python-version }} bash -c \ + "cd test && set -o pipefail && pyright --outputjson | bash pyright_to_github.sh" diff --git a/test/pyright_to_github.sh b/test/pyright_to_github.sh new file mode 100644 index 000000000..1a8a69899 --- /dev/null +++ b/test/pyright_to_github.sh @@ -0,0 +1,3 @@ +# This is a simple script to format Pyright errors (in JSON format) into GitHub errors, used by CI. +# TODO: Add formatting for warnings +jq -r '.generalDiagnostics[] | "::error file=\(.file),line=\(.range.start.line),col=\(.range.start.character)::\(.message)"' diff --git a/test/python.Dockerfile b/test/python.Dockerfile new file mode 100644 index 000000000..a86218d54 --- /dev/null +++ b/test/python.Dockerfile @@ -0,0 +1,25 @@ +# This is a minimal Docker image to run static tests on the Python code of LORIS-MRI. +# It sets up Python and our Python dependencies, but does not configure a full setup +# to test LORIS-MRI (Perl code, database...). + +# Python version to use for the tests +ARG PYTHON_VERSION=3.11 + +FROM python:${PYTHON_VERSION}-slim + +# Path of the LORIS-MRI repository in the container +ARG WORKSPACE + +RUN apt-get update + +# Required for the Python library `mysqlclient` +RUN apt-get install -y default-libmysqlclient-dev build-essential pkg-config + +# Used to format the Pyright errors to the GitHub format +RUN apt-get install -y jq + +COPY ./python/requirements.txt requirements.txt + +RUN pip install --no-cache-dir --root-user-action=ignore -r requirements.txt + +ENV PYTHONPATH=${WORKSPACE}/python:${WORKSPACE}/python/react-series-data-viewer