diff --git a/.github/actions/uv-setup/action.yml b/.github/actions/uv-setup/action.yml new file mode 100644 index 000000000..c42be0d85 --- /dev/null +++ b/.github/actions/uv-setup/action.yml @@ -0,0 +1,35 @@ +name: Setup UV and Sync +description: 'Install uv and sync the dependencies' +inputs: + sync: + description: 'Whether to run `uv sync` after setting up.' + required: false + default: 'true' + type: boolean + dev: + description: 'Whether to use `--no-dev` with `uv sync`.' + required: false + default: 'true' + type: boolean + activate-environment: + description: 'Wether to activate the virtual env or not' + required: false + default: true + type: boolean +runs: + using: 'composite' + steps: + - uses: astral-sh/setup-uv@bd01e18f51369d5a26f1651c3cb451d3417e3bba # v6.3.1 + with: + version: "0.7.x" + activate-environment: ${{ inputs.activate-environment }} + - if: inputs.sync == 'true' && inputs.dev == 'false' + run: uv sync --frozen --no-dev + shell: bash + env: + FORCE_COLOR: "1" + - if: inputs.sync == 'true' && inputs.dev == 'true' + run: uv sync --frozen + shell: bash + env: + FORCE_COLOR: "1" diff --git a/.github/workflows/code-checkers.yml b/.github/workflows/code-checkers.yml index 6a488855c..396b6bbf4 100644 --- a/.github/workflows/code-checkers.yml +++ b/.github/workflows/code-checkers.yml @@ -2,48 +2,49 @@ name: Static code checkers on: [push] +permissions: {} + jobs: mypy: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - name: Install uv - uses: astral-sh/setup-uv@v6 - with: - version: "0.7.x" - - name: Install dependencies - run: uv sync --frozen - - name: Create a dummy data.py - run: cp data.py-dist data.py - - name: Install additional typing data and check with mypy - run: uv run mypy --install-types --non-interactive lib/ conftest.py pkgfixtures.py tests/ + - uses: actions/checkout@v4 + with: + persist-credentials: false + - uses: ./.github/actions/uv-setup + - name: Create a dummy data.py + run: cp data.py-dist data.py + - run: mypy --install-types --non-interactive lib/ conftest.py pkgfixtures.py tests/ pyright: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - name: Install uv - uses: astral-sh/setup-uv@v6 - with: - version: "0.7.x" - - name: Install dependencies - run: uv sync --frozen - - name: Create a dummy data.py - run: cp data.py-dist data.py - - name: Check with pyright - run: uv run pyright lib/ conftest.py pkgfixtures.py # tests/ + - uses: actions/checkout@v4 + with: + persist-credentials: false + - uses: ./.github/actions/uv-setup/ + - name: Create a dummy data.py + run: cp data.py-dist data.py + - run: pyright lib/ conftest.py pkgfixtures.py # tests/ ruff: + runs-on: ubuntu-latest + env: + FORCE_COLOR: "1" + steps: + - uses: actions/checkout@v4 + with: + persist-credentials: false + - uses: ./.github/actions/uv-setup/ + - name: Create a dummy data.py + run: cp data.py-dist data.py + - run: ruff check lib/ tests/ + + flake8: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - name: Install uv - uses: astral-sh/setup-uv@v6 - with: - version: "0.7.x" - - name: Install dependencies - run: uv sync --frozen - - name: Create a dummy data.py - run: cp data.py-dist data.py - - name: Check with ruff - run: uv run ruff check lib/ tests/ + - uses: actions/checkout@v4 + with: + persist-credentials: false + - uses: ./.github/actions/uv-setup/ + - run: flake8 diff --git a/.github/workflows/format.yml b/.github/workflows/format.yml deleted file mode 100644 index c3b1a69ea..000000000 --- a/.github/workflows/format.yml +++ /dev/null @@ -1,30 +0,0 @@ -name: Check coding style - -on: [push] - -jobs: - pycodestyle: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Install uv - uses: astral-sh/setup-uv@v6 - with: - version: "0.7.x" - - name: Install dependencies - run: uv sync --frozen - - name: flake8 - run: uv run flake8 - - pydocstyle: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Install uv - uses: astral-sh/setup-uv@v6 - with: - version: "0.7.x" - - name: Install dependencies - run: uv sync --frozen - - name: pydocstyle - run: uv run pydocstyle diff --git a/.github/workflows/jobs-check.yml b/.github/workflows/jobs-check.yml index 59891a1ce..1ec892b37 100644 --- a/.github/workflows/jobs-check.yml +++ b/.github/workflows/jobs-check.yml @@ -2,18 +2,18 @@ name: Check jobs consistency on: [push] +permissions: {} + jobs: jobs-check: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - name: Install uv - uses: astral-sh/setup-uv@v6 - with: - version: "0.7.x" - - name: Install dependencies - run: uv sync --frozen - - name: Create a dummy data.py - run: cp data.py-dist data.py - - name: jobs-check - run: uv run ./jobs.py check + - uses: actions/checkout@v4 + with: + persist-credentials: false + - uses: ./.github/actions/uv-setup/ + with: + dev: false + - name: Create a dummy data.py + run: cp data.py-dist data.py + - run: ./jobs.py check diff --git a/.github/workflows/requirements-check.yml b/.github/workflows/requirements-check.yml index cadd7f5f3..d96f05e71 100644 --- a/.github/workflows/requirements-check.yml +++ b/.github/workflows/requirements-check.yml @@ -2,16 +2,17 @@ name: Check requirements file consistency on: [push] +permissions: {} + jobs: requirements-check: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - name: Install uv - uses: astral-sh/setup-uv@v6 - with: - version: "0.7.x" - - name: Install dependencies - run: uv sync --frozen - - run: uv run ./requirements/update_requirements.py - - run: git diff --exit-code + - uses: actions/checkout@v4 + with: + persist-credentials: false + - uses: ./.github/actions/uv-setup/ + with: + dev: false + - run: ./requirements/update_requirements.py + - run: git diff --exit-code diff --git a/.github/workflows/test-sequences.yml b/.github/workflows/test-sequences.yml index f40bb80f2..3e7aa342d 100644 --- a/.github/workflows/test-sequences.yml +++ b/.github/workflows/test-sequences.yml @@ -2,25 +2,26 @@ name: Check test-sequences consistency on: [push] +permissions: {} + jobs: jobs-check: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - name: Install uv - uses: astral-sh/setup-uv@v6 - with: - version: "0.7.x" - - name: Install dependencies - run: uv sync --frozen - - name: Create a dummy data.py - run: cp data.py-dist data.py - - name: jobs-check - run: | - FAILURES="" - for seq in $(find -name "*.lst"); do - if ! uv run pytest @$seq --collect-only --quiet; then - FAILURES="$FAILURES $seq" - fi - done - [ -z "$FAILURES" ] || { echo >&2 "ERROR: test sequences failed consistency check: $FAILURES"; exit 1; } + - uses: actions/checkout@v4 + with: + persist-credentials: false + - uses: ./.github/actions/uv-setup/ + with: + dev: false + - name: Create a dummy data.py + run: cp data.py-dist data.py + - name: jobs-check + run: | + FAILURES="" + for seq in $(find -name "*.lst"); do + if ! pytest @$seq --collect-only --quiet; then + FAILURES="$FAILURES $seq" + fi + done + [ -z "$FAILURES" ] || { echo >&2 "ERROR: test sequences failed consistency check: $FAILURES"; exit 1; } diff --git a/.github/workflows/zizmor.yml b/.github/workflows/zizmor.yml new file mode 100644 index 000000000..13711b28d --- /dev/null +++ b/.github/workflows/zizmor.yml @@ -0,0 +1,20 @@ +name: GitHub Actions Security Analysis with zizmor 🌈 + +on: [push] + +permissions: {} + +jobs: + zizmor: + name: zizmor latest + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + persist-credentials: false + - uses: ./.github/actions/uv-setup/ + with: + sync: false + - run: uvx zizmor --color=always . + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/pyproject.toml b/pyproject.toml index e77196b09..7602554fa 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,7 +3,7 @@ name = "xcp-ng-tests" version = "0.1.0" description = "Testing scripts for XCP-ng" readme = "README.md" -requires-python = "~=3.11" +requires-python = ">=3.11" dependencies = [ "cryptography>=3.3.1", "gitpython", @@ -21,6 +21,7 @@ dev = [ "bs4>=0.0.1", "mypy", "flake8", + "flake8-pyproject", "pydocstyle", "pyright", "pyyaml>=6.0", @@ -42,17 +43,38 @@ quote-style = "preserve" [tool.ruff.lint] select = [ + "D", # pydocstyle "F", # Pyflakes "I", # isort "SLF", # flake8-self "SIM", # flake8-simplify ] -# don't use some of the SIM rules +# don't use some of the default D and SIM rules ignore = [ + "D100", # undocumented-public-module + "D101", # undocumented-public-class + "D102", # undocumented-public-method + "D103", # undocumented-public-function + "D104", # undocumented-public-package + "D105", # undocumented-magic-method + "D106", # undocumented-public-nested-class + "D107", # undocumented-public-init + "D200", # unnecessary-multiline-docstring + "D203", # incorrect-blank-line-before-class + "D204", # incorrect-blank-line-after-class + "D205", # missing-blank-line-after-summary + "D210", # surrounding-whitespace + "D212", # incorrect-blank-line-before-class + "D400", # missing-trailing-period + "D401", # non-imperative-mood + "D403", # first-word-uncapitalized "SIM105", # suppressible-exception "SIM108", # if-else-block-instead-of-if-exp ] +# restrict to the PEP 257 rules +pydocstyle.convention = "pep257" + [tool.ruff.lint.extend-per-file-ignores] # pytest requires some import and function arguments to match, but # the linter doesn't know that @@ -76,3 +98,16 @@ section-order = [ "local-folder", "typing", ] + +# ruff doesn't provide all the pycodestyle rules, and pycodestyle is not well +# supported by some IDEs, so we use flake8 for that +[tool.flake8] +max-line-length = 120 +ignore = [ + "E261", # At least two spaces before inline comment + "E302", # Expected 2 blank lines, found 0 + "E305", # Expected 2 blank lines after end of function or class + "W503", # Line break occurred before a binary operator + "F", # already done by ruff +] +exclude=[".git", ".venv", "data.py", "vm_data.py"] diff --git a/requirements/dev.txt b/requirements/dev.txt index c5346f1aa..5a3c9d757 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -3,6 +3,7 @@ ansible>=5.0.1 bs4>=0.0.1 mypy flake8 +flake8-pyproject pydocstyle pyright pyyaml>=6.0 diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index 8b908666d..000000000 --- a/setup.cfg +++ /dev/null @@ -1,7 +0,0 @@ -[flake8] -max-line-length=120 -ignore=E261,E302,E305,W503,F -exclude=data.py,vm_data.py,.git,.venv - -[pydocstyle] -ignore=D100,D101,D102,D103,D104,D105,D106,D107,D203,D210,D212,D401,D403 diff --git a/uv.lock b/uv.lock index 32f308913..d7bfc6808 100644 --- a/uv.lock +++ b/uv.lock @@ -1,6 +1,6 @@ version = 1 revision = 2 -requires-python = ">=3.11, <4" +requires-python = ">=3.11" [[package]] name = "ansible" @@ -221,6 +221,17 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/9f/56/13ab06b4f93ca7cac71078fbe37fcea175d3216f31f85c3168a6bbd0bb9a/flake8-7.3.0-py2.py3-none-any.whl", hash = "sha256:b9696257b9ce8beb888cdbe31cf885c90d31928fe202be0889a7cdafad32f01e", size = 57922, upload-time = "2025-06-20T19:31:34.425Z" }, ] +[[package]] +name = "flake8-pyproject" +version = "1.2.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "flake8" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/5f/1d/635e86f9f3a96b7ea9e9f19b5efe17a987e765c39ca496e4a893bb999112/flake8_pyproject-1.2.3-py3-none-any.whl", hash = "sha256:6249fe53545205af5e76837644dc80b4c10037e73a0e5db87ff562d75fb5bd4a", size = 4756, upload-time = "2023-03-21T20:51:38.911Z" }, +] + [[package]] name = "gitdb" version = "4.0.12" @@ -675,6 +686,7 @@ dev = [ { name = "ansible" }, { name = "bs4" }, { name = "flake8" }, + { name = "flake8-pyproject" }, { name = "mypy" }, { name = "pydocstyle" }, { name = "pyright" }, @@ -701,6 +713,7 @@ dev = [ { name = "ansible", specifier = ">=5.0.1" }, { name = "bs4", specifier = ">=0.0.1" }, { name = "flake8" }, + { name = "flake8-pyproject" }, { name = "mypy" }, { name = "pydocstyle" }, { name = "pyright" },