diff --git a/.github/workflows/consumer_test.yml b/.github/workflows/consumer_test.yml index 913aed95..1691b8e1 100644 --- a/.github/workflows/consumer_test.yml +++ b/.github/workflows/consumer_test.yml @@ -31,26 +31,29 @@ jobs: - name: Checkout PR uses: actions/checkout@v4.2.2 - - name: Prepare Python - run: | - bazel run //:ide_support - - name: Prepare report directory - run: | - mkdir -p reports + - name: Build and run dev container task + uses: devcontainers/ci@v0.3 + with: + cacheFrom: ghcr.io/eclipse-score/devcontainer@v1.2.0 + push: never + # The pipefail ensures that non 0 exit codes inside the pytest execution get carried into the pipe + # & make the tests red in the end. Without this we only would check the exit code of the 'tee' command. + runCmd: | + set -euxo pipefail + uv venv && uv pip install -r src/requirements.txt - # The pipefail ensures that non 0 exit codes inside the pytest execution get carried into the pipe - # & make the tests red in the end. Without this we only would check the exit code of the 'tee' command. - - name: Run Consumer tests + mkdir -p reports - run: | - set -o pipefail - .venv_docs/bin/python -m pytest -s -v src/tests/ --repo="$CONSUMER" --junitxml="reports/${{ matrix.consumer }}.xml" | tee "reports/${{ matrix.consumer }}.log" - env: - FORCE_COLOR: "1" - TERM: xterm-256color - PYTHONUNBUFFERED: "1" - CONSUMER: ${{ matrix.consumer }} + export FORCE_COLOR="1" + export TERM="xterm-256color" + export PYTHONUNBUFFERED="1" + export CONSUMER="${{ matrix.consumer }}" + export PYTHONPATH=. + uv run pytest -s -v src/tests/ \ + --repo="$CONSUMER" \ + --junitxml="reports/${{ matrix.consumer }}.xml" \ + | tee "reports/${{ matrix.consumer }}.log" - name: Upload consumer test report if: ${{ always() }} diff --git a/.github/workflows/format.yml b/.github/workflows/format.yml deleted file mode 100644 index 05664bac..00000000 --- a/.github/workflows/format.yml +++ /dev/null @@ -1,41 +0,0 @@ -# ******************************************************************************* -# Copyright (c) 2025 Contributors to the Eclipse Foundation -# -# See the NOTICE file(s) distributed with this work for additional -# information regarding copyright ownership. -# -# This program and the accompanying materials are made available under the -# terms of the Apache License Version 2.0 which is available at -# https://www.apache.org/licenses/LICENSE-2.0 -# -# SPDX-License-Identifier: Apache-2.0 -# ******************************************************************************* - -name: Formatting checks -on: - pull_request: - types: [opened, reopened, synchronize] - merge_group: - types: [checks_requested] -jobs: - formatting-check: - runs-on: ubuntu-latest - steps: - - name: Checkout repository - uses: actions/checkout@v4.2.2 - - name: Cache Bazel - uses: actions/cache@v4 - with: - path: ~/.cache/bazel - key: ${{ runner.os }}-format-${{ hashFiles('**/*.bazel', '**/BUILD', '**/*.bzl') }} - - - name: Setup Bazel with cache - uses: bazel-contrib/setup-bazel@0.15.0 - with: - disk-cache: true - repository-cache: true - bazelisk-cache: true - - name: Run formatting checks - run: | - bazel run //:ide_support - bazel test //src:format.check diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index eea69f21..e0332fd8 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -27,15 +27,9 @@ jobs: - name: Checkout repository uses: actions/checkout@v4.2.2 - - name: Setup Bazel - uses: bazel-contrib/setup-bazel@0.15.0 + - name: Build and run dev container task + uses: devcontainers/ci@v0.3 with: - disk-cache: true - repository-cache: true - bazelisk-cache: true - - - name: Install pre-commit - run: pip install pre-commit - - - name: Run pre-commit checks - run: pre-commit run -a + cacheFrom: ghcr.io/eclipse-score/devcontainer + push: never + runCmd: ${PIPX_BIN_DIR}/pre-commit run -a diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index a2f9ab93..8251af75 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -22,33 +22,17 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v4.2.2 - - name: Cache Bazel and pip - uses: actions/cache@v4 - with: - path: | - ~/.cache/bazel - ~/.cache/pip - key: ${{ runner.os }}-test-${{ hashFiles('**/*.bazel', '**/BUILD', '**/*.bzl', 'src/requirements.txt', 'src/**/*.py') }} - - name: Setup Bazel with cache - uses: bazel-contrib/setup-bazel@0.15.0 + - name: Build and run dev container task + uses: devcontainers/ci@v0.3 with: - disk-cache: true - repository-cache: true - bazelisk-cache: true - - name: Run test targets - run: | - bazel run //:ide_support - bazel test //src/... - - - name: Prepare bundled consumer report - if: always() - # Creating tests-report directory - # Follow Symlinks via '-L' to copy correctly - # Copy everything inside the 'test-reports' folder - run: | - mkdir -p tests-report - rsync -amL --include='*/' --include='test.xml' --include='test.log' --exclude='*' bazel-testlogs/ tests-report/ + cacheFrom: ghcr.io/eclipse-score/devcontainer@v1.2.0 + push: never + runCmd: | + bazel run //:ide_support + bazel test //src/... + mkdir -p tests-report + rsync -amL --include='*/' --include='test.xml' --include='test.log' --exclude='*' bazel-testlogs/ tests-report/ - name: Upload bundled consumer report if: always() diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 1012be46..4f58b1e5 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -18,8 +18,52 @@ repos: # use LOCAL hooks for python tooling so versions come from the virtualenv - repo: local hooks: - - id: Linter Scripts - name: Run linter script - entry: ./scripts/run-linters.sh - language: unsupported_script + - id: ruff + name: ruff + entry: ruff check --fix + language: system + types_or: [python, pyi] + + - id: ruff-format + name: ruff format + entry: ruff format + language: system + types_or: [python, pyi] + + # Can not get this to run ;/ + - id: basedpyright + name: basedpyright + entry: basedpyright + language: system + types_or: [python, pyi] pass_filenames: false + + - id: actionlint + name: actionlint (container) + entry: actionlint + language: system + files: ^\.github/workflows/.*\.ya?ml$ + + - id: yamlfmt + name: yamlfmt (container) + entry: yamlfmt + language: system + types: [yaml] + + - id: shellcheck + name: shellcheck (container) + entry: shellcheck + language: system + types: [shell] + + - id: buildifier fix + name: bazel linting fix (container) + entry: buildifier --lint=fix + language: system + files: '(^|/)(BUILD(\.bazel)?|MODULE\.bazel|.*\.bzl)$' + + - id: buildifier format + name: bazel formatting (container) + entry: buildifier + language: system + files: '(^|/)(BUILD(\.bazel)?|MODULE\.bazel|.*\.bzl)$' diff --git a/pyproject.toml b/pyproject.toml index 41a0a876..4452fbec 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,24 +1,58 @@ # This file is at the root level, as it applies to all Python code, # not only to docs or to tools. [tool.pyright] -extends = "bazel-bin/ide_support.runfiles/score_tooling+/python_basics/pyproject.toml" +typeCheckingMode = "standard" +pythonVersion = "3.12" # Keep in sync with MODULE.bazel + +# Warn if function parameters lack type annotations +reportMissingParameterType = "warning" + +# Warn if generic types (e.g. List) are missing type args +reportMissingTypeArgument = "warning" + +# Warn when using members marked as private (e.g. _log) +reportPrivateUsage = "warning" + +# Warn when variable type can't be inferred or is 'Any' +reportUnknownVariableType = "warning" + +# Warn about declared but unused variables +reportUnusedVariable = "warning" exclude = [ "**/__pycache__", "**/.*", "**/bazel-*", - ".venv*/**", ] venvPath = "." venv = ".venv_docs" [tool.ruff] -extend = "bazel-bin/ide_support.runfiles/score_tooling+/python_basics/pyproject.toml" - +#line-length=59 +target-version = "py312" # Keep in sync with MODULE.bazel extend-exclude = [ + "__pycache__", + ".*", + "bazel-*", "**/__pycache__", "/.*", - "bazel-*", ".venv*/**", ] + +# Selected rules for clean code, readability, and bug prevention +lint.select = [ + "E", # pycodestyle (PEP8) + "F", # pyflakes (undefined vars, unused imports) + "I", # isort (import sorting) + "B", # flake8-bugbear (likely bugs) + "C90", # mccabe (complexity checks) + "UP", # pyupgrade (modern Python 3.12+ features) + "SIM", # flake8-simplify (simplifies code patterns) + "RET" # flake8-return (consistent return statements) +] + +lint.ignore = [ + # Rules we want to ignore go in here. + # Always provide a comment explaining why. +] diff --git a/scripts/run-linters.sh b/scripts/run-linters.sh deleted file mode 100755 index b5bead94..00000000 --- a/scripts/run-linters.sh +++ /dev/null @@ -1,41 +0,0 @@ -#!/usr/bin/env bash -# ******************************************************************************* -# Copyright (c) 2025 Contributors to the Eclipse Foundation -# -# See the NOTICE file(s) distributed with this work for additional -# information regarding copyright ownership. -# -# This program and the accompanying materials are made available under the -# terms of the Apache License Version 2.0 which is available at -# https://www.apache.org/licenses/LICENSE-2.0 -# -# SPDX-License-Identifier: Apache-2.0 -# ******************************************************************************* -set -euo pipefail - -bazel run //:ide_support - -echo "Running Ruff linter..." -bazel run @score_tooling//tools:ruff check - -echo "Running basedpyright..." -.venv_docs/bin/python3 -m basedpyright - -echo "Running Actionlint..." -bazel run @score_tooling//tools:actionlint - -echo "Running Shellcheck..." -# SC2038: find/xargs pattern works fine here despite non-alphanumeric filename warning -# The recommended -print0 | xargs -0 solution causes: -# "openBinaryFile: does not exist" with bazel run -# shellcheck disable=SC2038 -find . \ - -type d \( -name .git -o -name .venv -o -name bazel-out -o -name node_modules \) -prune -false \ - -o -type f -exec grep -Il '^#!.*sh' {} \; | \ -# SC1128: Shebang after copyright header is intentional -xargs bazel run @score_tooling//tools:shellcheck -- --exclude=SC1128 - -echo "Running Yamlfmt..." -bazel run @score_tooling//tools:yamlfmt -- "$(find . \ - -type d \( -name .git -o -name .venv -o -name bazel-out -o -name node_modules \) -prune -false \ - -o -type f \( -name "*.yaml" -o -name "*.yml" \) | tr '\n' '\0' | xargs -0)" diff --git a/src/requirements.txt b/src/requirements.txt index 555dcaf0..03f6818c 100644 --- a/src/requirements.txt +++ b/src/requirements.txt @@ -512,7 +512,7 @@ iniconfig==2.3.0 \ --hash=sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730 \ --hash=sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12 # via - # -r /external/score_tooling+/python_basics/requirements.txt + # -r /score_tooling+/python_basics/requirements.txt # pytest jinja2==3.1.6 \ --hash=sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d \ @@ -825,7 +825,7 @@ nodejs-wheel-binaries==24.11.1 \ --hash=sha256:c79a7e43869ccecab1cae8183778249cceb14ca2de67b5650b223385682c6239 \ --hash=sha256:cde41d5e4705266688a8d8071debf4f8a6fcea264c61292782672ee75a6905f9 # via - # -r /external/score_tooling+/python_basics/requirements.txt + # -r /score_tooling+/python_basics/requirements.txt # basedpyright numpy==2.4.2 \ --hash=sha256:00ab83c56211a1d7c07c25e3217ea6695e50a3e2f255053686b081dc0b091a82 \ @@ -907,7 +907,7 @@ packaging==25.0 \ --hash=sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484 \ --hash=sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f # via - # -r /external/score_tooling+/python_basics/requirements.txt + # -r /score_tooling+/python_basics/requirements.txt # matplotlib # pytest # sphinx @@ -1013,7 +1013,7 @@ pluggy==1.6.0 \ --hash=sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3 \ --hash=sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746 # via - # -r /external/score_tooling+/python_basics/requirements.txt + # -r /score_tooling+/python_basics/requirements.txt # pytest pycparser==3.0 \ --hash=sha256:600f49d217304a5902ac3c37e1281c9fe94e4d0489de643a9504c5cdfdfc6b29 \ @@ -1035,7 +1035,7 @@ pygments==2.19.2 \ --hash=sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887 \ --hash=sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b # via - # -r /external/score_tooling+/python_basics/requirements.txt + # -r /score_tooling+/python_basics/requirements.txt # accessible-pygments # pydata-sphinx-theme # pytest @@ -1083,7 +1083,7 @@ pyspellchecker==0.8.4 \ pytest==9.0.1 \ --hash=sha256:3e9c069ea73583e255c3b21cf46b8d3c56f6e3a1a8f6da94ccb0fcf57b9d73c8 \ --hash=sha256:67be0030d194df2dfa7b556f2e56fb3c3315bd5c8822c6951162b92b32ce7dad - # via -r /external/score_tooling+/python_basics/requirements.txt + # via -r /score_tooling+/python_basics/requirements.txt python-dateutil==2.9.0.post0 \ --hash=sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3 \ --hash=sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427