From d1a4b30d9d70438572b45137870e609d8d6e5f94 Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Tue, 16 May 2023 20:45:59 -0400 Subject: [PATCH 01/25] chore: move to using Ruff (#71) Signed-off-by: Henry Schreiner --- .flake8 | 3 -- .pre-commit-config.yaml | 15 +++----- MANIFEST.in | 1 - plugin_test.py | 7 ++-- pyproject.toml | 38 +++++++++++++++++++ .../plugin.py | 16 ++++---- 6 files changed, 54 insertions(+), 26 deletions(-) delete mode 100644 .flake8 diff --git a/.flake8 b/.flake8 deleted file mode 100644 index b23915d..0000000 --- a/.flake8 +++ /dev/null @@ -1,3 +0,0 @@ -[flake8] -ignore = E203, E231, E501, E722, W503, B950 -select = C,E,F,W,B,B9,I diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index df86f85..c8fcc59 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v3.1.0 + rev: "v4.4.0" hooks: - id: check-added-large-files - id: check-case-conflict @@ -12,17 +12,14 @@ repos: - id: mixed-line-ending - id: requirements-txt-fixer - id: trailing-whitespace - - id: fix-encoding-pragma - repo: https://github.com/mgedmin/check-manifest - rev: "0.42" + rev: "0.49" hooks: - id: check-manifest -- repo: https://github.com/PyCQA/flake8 - rev: 3.8.3 +- repo: https://github.com/charliermarsh/ruff-pre-commit + rev: "v0.0.262" hooks: - - id: flake8 - additional_dependencies: - - flake8-bugbear - - flake8-import-order + - id: ruff + args: ["--fix", "--show-fixes"] diff --git a/MANIFEST.in b/MANIFEST.in index d07d8e6..ee937c8 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,7 +1,6 @@ include *.py include *.txt include *.yaml -include .flake8 include .pre-commit-config.yaml include CHANGELOG.md include LICENSE diff --git a/plugin_test.py b/plugin_test.py index 7e489ff..a580e9e 100644 --- a/plugin_test.py +++ b/plugin_test.py @@ -1,10 +1,9 @@ -# -*- coding: utf-8 -*- -import os +from __future__ import annotations -from packaging import version +import os import pytest - +from packaging import version pytest_plugins = "pytester" diff --git a/pyproject.toml b/pyproject.toml index 69c327f..7e3ba1e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -49,3 +49,41 @@ changelog = "https://github.com/pytest-dev/pytest-github-actions-annotate-failur [project.entry-points.pytest11] pytest_github_actions_annotate_failures = "pytest_github_actions_annotate_failures.plugin" + + +[tool.ruff] +select = [ + "E", "F", "W", # flake8 + "B", # flake8-bugbear + "I", # isort + "ARG", # flake8-unused-arguments + "C4", # flake8-comprehensions + "EM", # flake8-errmsg + "ICN", # flake8-import-conventions + "ISC", # flake8-implicit-str-concat + "G", # flake8-logging-format + "PGH", # pygrep-hooks + "PIE", # flake8-pie + "PL", # pylint + "PT", # flake8-pytest-style + "RET", # flake8-return + "RUF", # Ruff-specific + "SIM", # flake8-simplify + "UP", # pyupgrade + "YTT", # flake8-2020 + "EXE", # flake8-executable +] +extend-ignore = [ + "PLR", # Design related pylint codes + "E501", # Line too long + "PT004", # Use underscore for non-returning fixture (use usefixture instead) +] +target-version = "py37" +unfixable = [ + "T20", # Removes print statements + "F841", # Removes unused variables +] +isort.required-imports = ["from __future__ import annotations"] + +[tool.ruff.per-file-ignores] +"tests/**" = ["T20"] diff --git a/pytest_github_actions_annotate_failures/plugin.py b/pytest_github_actions_annotate_failures/plugin.py index de61ee9..8cf1e62 100644 --- a/pytest_github_actions_annotate_failures/plugin.py +++ b/pytest_github_actions_annotate_failures/plugin.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- from __future__ import annotations @@ -7,9 +6,8 @@ from collections import OrderedDict from typing import TYPE_CHECKING -from _pytest._code.code import ExceptionRepr - import pytest +from _pytest._code.code import ExceptionRepr if TYPE_CHECKING: from _pytest.nodes import Item @@ -26,7 +24,7 @@ @pytest.hookimpl(tryfirst=True, hookwrapper=True) -def pytest_runtest_makereport(item: Item, call): +def pytest_runtest_makereport(item: Item, call): # noqa: ARG001 # execute all other hooks to obtain the report object outcome = yield report: CollectReport = outcome.get_result() @@ -93,13 +91,13 @@ def _error_workflow_command(filesystempath, lineno, longrepr): if lineno is not None: details_dict["line"] = lineno - details = ",".join("{}={}".format(k, v) for k, v in details_dict.items()) + details = ",".join(f"{k}={v}" for k, v in details_dict.items()) if longrepr is None: - return "\n::error {}".format(details) - else: - longrepr = _escape(longrepr) - return "\n::error {}::{}".format(details, longrepr) + return f"\n::error {details}" + + longrepr = _escape(longrepr) + return f"\n::error {details}::{longrepr}" def _escape(s): From b58e3d038f7bf170629b7d320b8bf77a59a05174 Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Fri, 1 Mar 2024 13:42:08 -0500 Subject: [PATCH 02/25] chore: ruff moved to astral-sh (#75) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index c8fcc59..159aa53 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -18,7 +18,7 @@ repos: hooks: - id: check-manifest -- repo: https://github.com/charliermarsh/ruff-pre-commit +- repo: https://github.com/astral-sh/ruff-pre-commit rev: "v0.0.262" hooks: - id: ruff From 2ce469fc144cc16d219ef70290443df9e98e4b75 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 1 Mar 2024 18:44:52 +0000 Subject: [PATCH 03/25] build(deps): bump actions/checkout from 3 to 4 (#79) Bumps [actions/checkout](https://github.com/actions/checkout) from 3 to 4. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v3...v4) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Sorin Sbarnea --- .github/workflows/deploy.yml | 2 +- .github/workflows/format.yml | 2 +- .github/workflows/test.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index d7fc2a1..4da9cfe 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -10,7 +10,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Set up Python uses: actions/setup-python@v4 diff --git a/.github/workflows/format.yml b/.github/workflows/format.yml index 3cdd8c0..b0c96c3 100644 --- a/.github/workflows/format.yml +++ b/.github/workflows/format.yml @@ -11,7 +11,7 @@ jobs: name: Pre-commit checks runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: actions/setup-python@v4 with: python-version: '3.10' diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 2ba83a7..6dfee60 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -27,7 +27,7 @@ jobs: name: ${{ matrix.os }}, Python ${{ matrix.python-version }} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v4 From f0bb8d69328f4b94c11ea91797d75b5089dbb8ae Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Wed, 15 May 2024 02:08:04 -0400 Subject: [PATCH 04/25] ci: fix by adding limit (#84) * ci: fix by adding limit * ci: expand matrix * Update test.yml * Update test.yml --- .github/workflows/test.yml | 12 ++++-------- tox.ini | 9 +++++---- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 6dfee60..fd91825 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -17,12 +17,8 @@ jobs: - '3.8' - '3.9' - '3.10' - include: - - os: ubuntu-22.04 - python-version: '3.7' - - os: windows-latest - python-version: '3.7' - + - '3.11' + - '3.12' runs-on: ${{ matrix.os }} name: ${{ matrix.os }}, Python ${{ matrix.python-version }} @@ -44,7 +40,7 @@ jobs: - name: Run tests with PyTest 4 run: tox - if: ${{ matrix.python-version != '3.10' }} + if: "!startsWith(matrix.python-version, '3.1')" env: PLATFORM: ${{ matrix.os }} PYTEST_MAJOR_VERSION: 4 @@ -52,7 +48,7 @@ jobs: - name: Run tests with PyTest 5 run: tox - if: ${{ matrix.python-version != '3.10' }} + if: "!startsWith(matrix.python-version, '3.1')" env: PLATFORM: ${{ matrix.os }} PYTEST_MAJOR_VERSION: 5 diff --git a/tox.ini b/tox.ini index a22edf4..4eb5c52 100644 --- a/tox.ini +++ b/tox.ini @@ -1,8 +1,7 @@ [tox] envlist = - py27-pytest4-{linux,windows} - py{36,37,38,39}-pytest{4,5,6,7}-{linux,windows} - py{310}-pytest{6,7}-{linux,windows} + py{37,38,39}-pytest{4,5,6,7}-{linux,windows} + py{310,311,312}-pytest{6,7}-{linux,windows} pkg [gh-actions] @@ -11,6 +10,8 @@ python = 3.8: py38 3.9: py39 3.10: py310 + 3.11: py311 + 3.12: py312 [gh-actions:env] PLATFORM = @@ -29,7 +30,7 @@ deps = pytest4: pytest>=4.0.0,<5.0.0 pytest5: pytest>=5.0.0,<6.0.0 pytest6: pytest>=6.0.0,<7.0.0 - pytest7: pytest>=7.0.0,<8.0.0 + pytest7: pytest>=7.0.0,<7.4.0 commands = {envpython} -m pytest From 0ac6d0e6f7a28fc51a3c8fdc179eaf66547c8b22 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 15 May 2024 02:12:26 -0400 Subject: [PATCH 05/25] build(deps): bump pre-commit/action from 3.0.0 to 3.0.1 (#83) Bumps [pre-commit/action](https://github.com/pre-commit/action) from 3.0.0 to 3.0.1. - [Release notes](https://github.com/pre-commit/action/releases) - [Commits](https://github.com/pre-commit/action/compare/v3.0.0...v3.0.1) --- updated-dependencies: - dependency-name: pre-commit/action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/format.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/format.yml b/.github/workflows/format.yml index b0c96c3..0471f17 100644 --- a/.github/workflows/format.yml +++ b/.github/workflows/format.yml @@ -15,4 +15,4 @@ jobs: - uses: actions/setup-python@v4 with: python-version: '3.10' - - uses: pre-commit/action@v3.0.0 + - uses: pre-commit/action@v3.0.1 From 835844257e5b3c3e6a9086f7bc7b5f82ee463a43 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 15 May 2024 06:16:30 +0000 Subject: [PATCH 06/25] build(deps): bump actions/setup-python from 4 to 5 (#82) Bumps [actions/setup-python](https://github.com/actions/setup-python) from 4 to 5. - [Release notes](https://github.com/actions/setup-python/releases) - [Commits](https://github.com/actions/setup-python/compare/v4...v5) --- updated-dependencies: - dependency-name: actions/setup-python dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/deploy.yml | 2 +- .github/workflows/format.yml | 2 +- .github/workflows/test.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 4da9cfe..f966a09 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -13,7 +13,7 @@ jobs: uses: actions/checkout@v4 - name: Set up Python - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: '3.11' diff --git a/.github/workflows/format.yml b/.github/workflows/format.yml index 0471f17..3886257 100644 --- a/.github/workflows/format.yml +++ b/.github/workflows/format.yml @@ -12,7 +12,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 with: python-version: '3.10' - uses: pre-commit/action@v3.0.1 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index fd91825..bffe4f0 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -26,7 +26,7 @@ jobs: - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} From d6add6430dc82b31281ef1a604cade5b0f05b08b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edgar=20Ram=C3=ADrez=20Mondrag=C3=B3n?= <16805946+edgarrmondragon@users.noreply.github.com> Date: Mon, 21 Oct 2024 23:26:24 -0600 Subject: [PATCH 07/25] Drop support for pytest<6 (#86) --- .github/workflows/test.yml | 19 +++---------------- CHANGELOG.md | 6 ++++++ pyproject.toml | 2 +- tox.ini | 7 +------ 4 files changed, 11 insertions(+), 23 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index bffe4f0..cf750c5 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -7,6 +7,9 @@ on: - main pull_request: +env: + FORCE_COLOR: "1" + jobs: test: strategy: @@ -38,22 +41,6 @@ jobs: - name: Test packaging run: tox -e pkg - - name: Run tests with PyTest 4 - run: tox - if: "!startsWith(matrix.python-version, '3.1')" - env: - PLATFORM: ${{ matrix.os }} - PYTEST_MAJOR_VERSION: 4 - PYTEST_PLUGINS: pytest_github_actions_annotate_failures - - - name: Run tests with PyTest 5 - run: tox - if: "!startsWith(matrix.python-version, '3.1')" - env: - PLATFORM: ${{ matrix.os }} - PYTEST_MAJOR_VERSION: 5 - PYTEST_PLUGINS: pytest_github_actions_annotate_failures - - name: Run tests with PyTest 6 run: tox env: diff --git a/CHANGELOG.md b/CHANGELOG.md index 1ac4394..9ccd601 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## Unreleased + +### Incompatible changes + +- Require pytest 6+ #86 (thanks to @edgarrmondragon) + ## 0.2.0 (2023-05-04) ### Incompatible changes diff --git a/pyproject.toml b/pyproject.toml index 7e3ba1e..7bb532d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -39,7 +39,7 @@ classifiers = [ ] keywords = ["ansible", "testing", "molecule", "plugin"] dependencies = [ - "pytest>=4.0.0" + "pytest>=6.0.0" ] [project.urls] diff --git a/tox.ini b/tox.ini index 4eb5c52..0536448 100644 --- a/tox.ini +++ b/tox.ini @@ -1,7 +1,6 @@ [tox] envlist = - py{37,38,39}-pytest{4,5,6,7}-{linux,windows} - py{310,311,312}-pytest{6,7}-{linux,windows} + py{37,38,39,310,311,312}-pytest{6,7}-{linux,windows} pkg [gh-actions] @@ -19,16 +18,12 @@ PLATFORM = windows-latest: windows PYTEST_MAJOR_VERSION = - 4: pytest4 - 5: pytest5 6: pytest6 7: pytest7 [testenv] deps = -rrequirements.txt - pytest4: pytest>=4.0.0,<5.0.0 - pytest5: pytest>=5.0.0,<6.0.0 pytest6: pytest>=6.0.0,<7.0.0 pytest7: pytest>=7.0.0,<7.4.0 From 8646218145162323bb877cc845d204f53cce1058 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edgar=20Ram=C3=ADrez=20Mondrag=C3=B3n?= <16805946+edgarrmondragon@users.noreply.github.com> Date: Mon, 21 Oct 2024 23:30:09 -0600 Subject: [PATCH 08/25] Declare support for Python 3.12 in project metadata (#88) --- pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pyproject.toml b/pyproject.toml index 7bb532d..8361efe 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -30,6 +30,7 @@ classifiers = [ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3 :: Only", "Programming Language :: Python", "Topic :: System :: Systems Administration", From 8e001cad398092023caf32c381a104b92b717b25 Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Tue, 22 Oct 2024 11:12:28 -0400 Subject: [PATCH 09/25] ci: updates (#90) * ci: update the action and tox Signed-off-by: Henry Schreiner * ci: update pre-commits Signed-off-by: Henry Schreiner --------- Signed-off-by: Henry Schreiner --- .github/workflows/test.yml | 10 +++++----- .pre-commit-config.yaml | 9 ++------- pyproject.toml | 15 ++++----------- tox.ini | 10 ++++------ 4 files changed, 15 insertions(+), 29 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index cf750c5..2a04bdc 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -7,6 +7,10 @@ on: - main pull_request: +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + env: FORCE_COLOR: "1" @@ -34,9 +38,7 @@ jobs: python-version: ${{ matrix.python-version }} - name: Install test dependencies - run: | - python -m pip install --upgrade pip - pip install tox tox-gh-actions + run: pip install tox tox-gh-actions - name: Test packaging run: tox -e pkg @@ -44,14 +46,12 @@ jobs: - name: Run tests with PyTest 6 run: tox env: - PLATFORM: ${{ matrix.os }} PYTEST_MAJOR_VERSION: 6 PYTEST_PLUGINS: pytest_github_actions_annotate_failures - name: Run tests with PyTest 7 run: tox env: - PLATFORM: ${{ matrix.os }} PYTEST_MAJOR_VERSION: 7 PYTEST_PLUGINS: pytest_github_actions_annotate_failures diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 159aa53..091ecc2 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: "v4.4.0" + rev: "v5.0.0" hooks: - id: check-added-large-files - id: check-case-conflict @@ -13,13 +13,8 @@ repos: - id: requirements-txt-fixer - id: trailing-whitespace -- repo: https://github.com/mgedmin/check-manifest - rev: "0.49" - hooks: - - id: check-manifest - - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.0.262" + rev: "v0.7.0" hooks: - id: ruff args: ["--fix", "--show-fixes"] diff --git a/pyproject.toml b/pyproject.toml index 8361efe..2acae3e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -52,9 +52,8 @@ changelog = "https://github.com/pytest-dev/pytest-github-actions-annotate-failur pytest_github_actions_annotate_failures = "pytest_github_actions_annotate_failures.plugin" -[tool.ruff] -select = [ - "E", "F", "W", # flake8 +[tool.ruff.lint] +extend-select = [ "B", # flake8-bugbear "I", # isort "ARG", # flake8-unused-arguments @@ -74,17 +73,11 @@ select = [ "YTT", # flake8-2020 "EXE", # flake8-executable ] -extend-ignore = [ +ignore = [ "PLR", # Design related pylint codes - "E501", # Line too long "PT004", # Use underscore for non-returning fixture (use usefixture instead) ] -target-version = "py37" -unfixable = [ - "T20", # Removes print statements - "F841", # Removes unused variables -] isort.required-imports = ["from __future__ import annotations"] -[tool.ruff.per-file-ignores] +[tool.ruff.lint.per-file-ignores] "tests/**" = ["T20"] diff --git a/tox.ini b/tox.ini index 0536448..9fa1583 100644 --- a/tox.ini +++ b/tox.ini @@ -1,6 +1,6 @@ [tox] envlist = - py{37,38,39,310,311,312}-pytest{6,7}-{linux,windows} + py{37,38,39,310,311,312}-pytest{6,7,8} pkg [gh-actions] @@ -13,21 +13,19 @@ python = 3.12: py312 [gh-actions:env] -PLATFORM = - ubuntu-latest: linux - windows-latest: windows - PYTEST_MAJOR_VERSION = 6: pytest6 7: pytest7 + 8: pytest8 [testenv] deps = -rrequirements.txt pytest6: pytest>=6.0.0,<7.0.0 pytest7: pytest>=7.0.0,<7.4.0 + pytest8: pytest>=8.0.0,<9.0.0 -commands = {envpython} -m pytest +commands = {envpython} -m pytest {posargs} [testenv:pkg] skip_install = true From 801b644e4c1a2f8f046e565dc318d72c61a5e2e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edgar=20Ram=C3=ADrez=20Mondrag=C3=B3n?= <16805946+edgarrmondragon@users.noreply.github.com> Date: Tue, 22 Oct 2024 09:48:23 -0600 Subject: [PATCH 10/25] Annotate warnings (#68) * Annotate warnings - Refactor workflow command generation * Rename option to `--exclude-warning-annotations` * Suppress windows relpath exception --- .github/workflows/test.yml | 1 + README.md | 4 + plugin_test.py | 120 ++++++++++++++---- .../plugin.py | 100 ++++++++++++--- 4 files changed, 188 insertions(+), 37 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 2a04bdc..bfe49ea 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -17,6 +17,7 @@ env: jobs: test: strategy: + fail-fast: false matrix: os: [ubuntu-latest, windows-latest] python-version: diff --git a/README.md b/README.md index ae74bd8..25f4dae 100644 --- a/README.md +++ b/README.md @@ -36,5 +36,9 @@ If your test is running in a Docker container, you have to install this plugin a If your tests are run from a subdirectory of the git repository, you have to set the `PYTEST_RUN_PATH` environment variable to the path of that directory relative to the repository root in order for GitHub to identify the files with errors correctly. +### Warning annotations + +This plugin also supports warning annotations when used with Pytest 6.0+. To disable warning annotations, pass `--exclude-warning-annotations` to pytest. + ## Screenshot [![Image from Gyazo](https://i.gyazo.com/b578304465dd1b755ceb0e04692a57d9.png)](https://gyazo.com/b578304465dd1b755ceb0e04692a57d9) diff --git a/plugin_test.py b/plugin_test.py index a580e9e..3037fa7 100644 --- a/plugin_test.py +++ b/plugin_test.py @@ -5,19 +5,17 @@ import pytest from packaging import version +PYTEST_VERSION = version.parse(pytest.__version__) pytest_plugins = "pytester" -# result.stderr.no_fnmatch_line() is added to testdir on pytest 5.3.0 +# result.stderr.no_fnmatch_line() was added to testdir on pytest 5.3.0 # https://docs.pytest.org/en/stable/changelog.html#pytest-5-3-0-2019-11-19 -def no_fnmatch_line(result, pattern): - if version.parse(pytest.__version__) >= version.parse("5.3.0"): - result.stderr.no_fnmatch_line(pattern + "*",) - else: - assert pattern not in result.stderr.str() +def no_fnmatch_line(result: pytest.RunResult, pattern: str): + result.stderr.no_fnmatch_line(pattern + "*") -def test_annotation_succeed_no_output(testdir): +def test_annotation_succeed_no_output(testdir: pytest.Testdir): testdir.makepyfile( """ import pytest @@ -33,7 +31,7 @@ def test_success(): no_fnmatch_line(result, "::error file=test_annotation_succeed_no_output.py") -def test_annotation_pytest_error(testdir): +def test_annotation_pytest_error(testdir: pytest.Testdir): testdir.makepyfile( """ import pytest @@ -55,7 +53,7 @@ def test_error(): ) -def test_annotation_fail(testdir): +def test_annotation_fail(testdir: pytest.Testdir): testdir.makepyfile( """ import pytest @@ -68,11 +66,13 @@ def test_fail(): testdir.monkeypatch.setenv("GITHUB_ACTIONS", "true") result = testdir.runpytest_subprocess() result.stderr.fnmatch_lines( - ["::error file=test_annotation_fail.py,line=5::test_fail*assert 0*",] + [ + "::error file=test_annotation_fail.py,line=5::test_fail*assert 0*", + ] ) -def test_annotation_exception(testdir): +def test_annotation_exception(testdir: pytest.Testdir): testdir.makepyfile( """ import pytest @@ -86,11 +86,51 @@ def test_fail(): testdir.monkeypatch.setenv("GITHUB_ACTIONS", "true") result = testdir.runpytest_subprocess() result.stderr.fnmatch_lines( - ["::error file=test_annotation_exception.py,line=5::test_fail*oops*",] + [ + "::error file=test_annotation_exception.py,line=5::test_fail*oops*", + ] + ) + + +def test_annotation_warning(testdir: pytest.Testdir): + testdir.makepyfile( + """ + import warnings + import pytest + pytest_plugins = 'pytest_github_actions_annotate_failures' + + def test_warning(): + warnings.warn('beware', Warning) + assert 1 + """ ) + testdir.monkeypatch.setenv("GITHUB_ACTIONS", "true") + result = testdir.runpytest_subprocess() + result.stderr.fnmatch_lines( + [ + "::warning file=test_annotation_warning.py,line=6::beware", + ] + ) + + +def test_annotation_exclude_warnings(testdir: pytest.Testdir): + testdir.makepyfile( + """ + import warnings + import pytest + pytest_plugins = 'pytest_github_actions_annotate_failures' + + def test_warning(): + warnings.warn('beware', Warning) + assert 1 + """ + ) + testdir.monkeypatch.setenv("GITHUB_ACTIONS", "true") + result = testdir.runpytest_subprocess("--exclude-warning-annotations") + assert not result.stderr.lines -def test_annotation_third_party_exception(testdir): +def test_annotation_third_party_exception(testdir: pytest.Testdir): testdir.makepyfile( my_module=""" def fn(): @@ -111,11 +151,43 @@ def test_fail(): testdir.monkeypatch.setenv("GITHUB_ACTIONS", "true") result = testdir.runpytest_subprocess() result.stderr.fnmatch_lines( - ["::error file=test_annotation_third_party_exception.py,line=6::test_fail*oops*",] + [ + "::error file=test_annotation_third_party_exception.py,line=6::test_fail*oops*", + ] + ) + + +def test_annotation_third_party_warning(testdir: pytest.Testdir): + testdir.makepyfile( + my_module=""" + import warnings + + def fn(): + warnings.warn('beware', Warning) + """ + ) + + testdir.makepyfile( + """ + import pytest + from my_module import fn + pytest_plugins = 'pytest_github_actions_annotate_failures' + + def test_warning(): + fn() + """ + ) + testdir.monkeypatch.setenv("GITHUB_ACTIONS", "true") + result = testdir.runpytest_subprocess() + result.stderr.fnmatch_lines( + # ["::warning file=test_annotation_third_party_warning.py,line=6::beware",] + [ + "::warning file=my_module.py,line=4::beware", + ] ) -def test_annotation_fail_disabled_outside_workflow(testdir): +def test_annotation_fail_disabled_outside_workflow(testdir: pytest.Testdir): testdir.makepyfile( """ import pytest @@ -132,7 +204,7 @@ def test_fail(): ) -def test_annotation_fail_cwd(testdir): +def test_annotation_fail_cwd(testdir: pytest.Testdir): testdir.makepyfile( """ import pytest @@ -148,11 +220,13 @@ def test_fail(): testdir.makefile(".ini", pytest="[pytest]\ntestpaths=..") result = testdir.runpytest_subprocess("--rootdir=foo") result.stderr.fnmatch_lines( - ["::error file=test_annotation_fail_cwd.py,line=5::test_fail*assert 0*",] + [ + "::error file=test_annotation_fail_cwd.py,line=5::test_fail*assert 0*", + ] ) -def test_annotation_fail_runpath(testdir): +def test_annotation_fail_runpath(testdir: pytest.Testdir): testdir.makepyfile( """ import pytest @@ -166,11 +240,13 @@ def test_fail(): testdir.monkeypatch.setenv("PYTEST_RUN_PATH", "some_path") result = testdir.runpytest_subprocess() result.stderr.fnmatch_lines( - ["::error file=some_path/test_annotation_fail_runpath.py,line=5::test_fail*assert 0*",] + [ + "::error file=some_path/test_annotation_fail_runpath.py,line=5::test_fail*assert 0*", + ] ) -def test_annotation_long(testdir): +def test_annotation_long(testdir: pytest.Testdir): testdir.makepyfile( """ import pytest @@ -202,7 +278,7 @@ def test_fail(): no_fnmatch_line(result, "::*assert x += 1*") -def test_class_method(testdir): +def test_class_method(testdir: pytest.Testdir): testdir.makepyfile( """ import pytest @@ -224,7 +300,7 @@ def test_method(self): no_fnmatch_line(result, "::*x = 1*") -def test_annotation_param(testdir): +def test_annotation_param(testdir: pytest.Testdir): testdir.makepyfile( """ import pytest diff --git a/pytest_github_actions_annotate_failures/plugin.py b/pytest_github_actions_annotate_failures/plugin.py index 8cf1e62..0c364ea 100644 --- a/pytest_github_actions_annotate_failures/plugin.py +++ b/pytest_github_actions_annotate_failures/plugin.py @@ -1,13 +1,14 @@ from __future__ import annotations +import contextlib import os import sys -from collections import OrderedDict from typing import TYPE_CHECKING import pytest from _pytest._code.code import ExceptionRepr +from packaging import version if TYPE_CHECKING: from _pytest.nodes import Item @@ -23,6 +24,9 @@ # https://github.com/pytest-dev/pytest/blob/master/src/_pytest/terminal.py +PYTEST_VERSION = version.parse(pytest.__version__) + + @pytest.hookimpl(tryfirst=True, hookwrapper=True) def pytest_runtest_makereport(item: Item, call): # noqa: ARG001 # execute all other hooks to obtain the report object @@ -79,25 +83,91 @@ def pytest_runtest_makereport(item: Item, call): # noqa: ARG001 elif isinstance(report.longrepr, str): longrepr += "\n\n" + report.longrepr - print( - _error_workflow_command(filesystempath, lineno, longrepr), file=sys.stderr + workflow_command = _build_workflow_command( + "error", + filesystempath, + lineno, + message=longrepr, ) + print(workflow_command, file=sys.stderr) -def _error_workflow_command(filesystempath, lineno, longrepr): - # Build collection of arguments. Ordering is strict for easy testing - details_dict = OrderedDict() - details_dict["file"] = filesystempath - if lineno is not None: - details_dict["line"] = lineno - - details = ",".join(f"{k}={v}" for k, v in details_dict.items()) +class _AnnotateWarnings: + def pytest_warning_recorded(self, warning_message, when, nodeid, location): # noqa: ARG002 + # enable only in a workflow of GitHub Actions + # ref: https://help.github.com/en/actions/configuring-and-managing-workflows/using-environment-variables#default-environment-variables + if os.environ.get("GITHUB_ACTIONS") != "true": + return - if longrepr is None: - return f"\n::error {details}" + filesystempath = warning_message.filename + workspace = os.environ.get("GITHUB_WORKFLOW") - longrepr = _escape(longrepr) - return f"\n::error {details}::{longrepr}" + if workspace: + try: + rel_path = os.path.relpath(filesystempath, workspace) + except ValueError: + # os.path.relpath() will raise ValueError on Windows + # when full_path and workspace have different mount points. + rel_path = filesystempath + if not rel_path.startswith(".."): + filesystempath = rel_path + else: + with contextlib.suppress(ValueError): + filesystempath = os.path.relpath(filesystempath) + + workflow_command = _build_workflow_command( + "warning", + filesystempath, + warning_message.lineno, + message=warning_message.message.args[0], + ) + print(workflow_command, file=sys.stderr) + + +def pytest_addoption(parser): + group = parser.getgroup("pytest_github_actions_annotate_failures") + group.addoption( + "--exclude-warning-annotations", + action="store_true", + default=False, + help="Annotate failures in GitHub Actions.", + ) + +def pytest_configure(config): + if not config.option.exclude_warning_annotations: + config.pluginmanager.register(_AnnotateWarnings(), "annotate_warnings") + + +def _build_workflow_command( + command_name, + file, + line, + end_line=None, + column=None, + end_column=None, + title=None, + message=None, +): + """Build a command to annotate a workflow.""" + result = f"::{command_name} " + + entries = [ + ("file", file), + ("line", line), + ("endLine", end_line), + ("col", column), + ("endColumn", end_column), + ("title", title), + ] + + result = result + ",".join( + f"{k}={v}" for k, v in entries if v is not None + ) + + if message is not None: + result = result + "::" + _escape(message) + + return result def _escape(s): From 6d4526eef53a82f0e56fd32b9e5a4457c2580efa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edgar=20Ram=C3=ADrez=20Mondrag=C3=B3n?= <16805946+edgarrmondragon@users.noreply.github.com> Date: Tue, 22 Oct 2024 15:16:10 -0600 Subject: [PATCH 11/25] Drop support for Python 3.7 (#87) --- .github/workflows/test.yml | 1 - CHANGELOG.md | 1 + README.md | 2 +- pyproject.toml | 3 +-- tox.ini | 3 +-- 5 files changed, 4 insertions(+), 6 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index bfe49ea..5c7fd55 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -21,7 +21,6 @@ jobs: matrix: os: [ubuntu-latest, windows-latest] python-version: - - '3.7' - '3.8' - '3.9' - '3.10' diff --git a/CHANGELOG.md b/CHANGELOG.md index 9ccd601..abcb1d1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ ### Incompatible changes +- Require python 3.8+ #87 (thanks to @edgarrmondragon) - Require pytest 6+ #86 (thanks to @edgarrmondragon) ## 0.2.0 (2023-05-04) diff --git a/README.md b/README.md index 25f4dae..e60d585 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ jobs: - uses: actions/setup-python@v4 with: - python-version: 3.7 + python-version: 3.8 - name: Install dependencies run: | diff --git a/pyproject.toml b/pyproject.toml index 2acae3e..31ce272 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -8,7 +8,7 @@ build-backend = "setuptools.build_meta" [project] # https://peps.python.org/pep-0621/#readme -requires-python = ">=3.7" +requires-python = ">=3.8" version = "0.2.0" name = "pytest-github-actions-annotate-failures" description = "pytest plugin to annotate failed tests with a workflow command for GitHub Actions" @@ -25,7 +25,6 @@ classifiers = [ "License :: OSI Approved :: MIT License", "Framework :: Pytest", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", diff --git a/tox.ini b/tox.ini index 9fa1583..4c1b823 100644 --- a/tox.ini +++ b/tox.ini @@ -1,11 +1,10 @@ [tox] envlist = - py{37,38,39,310,311,312}-pytest{6,7,8} + py{38,39,310,311,312}-pytest{6,7,8} pkg [gh-actions] python = - 3.7: py37 3.8: py38 3.9: py39 3.10: py310 From 55b2d6dd7fefc17466f710b6a776267c24e5af74 Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Tue, 22 Oct 2024 17:34:41 -0400 Subject: [PATCH 12/25] tests: use extra for tests (#92) Signed-off-by: Henry Schreiner --- pyproject.toml | 3 +++ requirements.txt | 1 - tox.ini | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) delete mode 100644 requirements.txt diff --git a/pyproject.toml b/pyproject.toml index 31ce272..a4c5cb6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -50,6 +50,9 @@ changelog = "https://github.com/pytest-dev/pytest-github-actions-annotate-failur [project.entry-points.pytest11] pytest_github_actions_annotate_failures = "pytest_github_actions_annotate_failures.plugin" +[project.optional-dependencies] +test = ["packaging"] + [tool.ruff.lint] extend-select = [ diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index 84fa678..0000000 --- a/requirements.txt +++ /dev/null @@ -1 +0,0 @@ -packaging==20.4 diff --git a/tox.ini b/tox.ini index 4c1b823..3e51181 100644 --- a/tox.ini +++ b/tox.ini @@ -18,8 +18,8 @@ PYTEST_MAJOR_VERSION = 8: pytest8 [testenv] +extras = test deps = - -rrequirements.txt pytest6: pytest>=6.0.0,<7.0.0 pytest7: pytest>=7.0.0,<7.4.0 pytest8: pytest>=8.0.0,<9.0.0 From 500c53ccec6ae039dd9f823ad9e70457e777648c Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Tue, 22 Oct 2024 17:41:48 -0400 Subject: [PATCH 13/25] ci: speed up testing (#93) * ci: speed up testing Signed-off-by: Henry Schreiner * chore: remove pkg job with faster/better check in CI already * Update .github/workflows/test.yml --------- Signed-off-by: Henry Schreiner --- .github/workflows/deploy.yml | 27 ++++++++++++++------------- .github/workflows/test.yml | 16 ++++++++++------ tox.ini | 15 --------------- 3 files changed, 24 insertions(+), 34 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index f966a09..229b86e 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -1,30 +1,31 @@ name: deploy on: + workflow_dispatch: + pull_request: push: + branches: + - main tags: - v* jobs: - deploy: + dist: runs-on: ubuntu-latest steps: - - name: Checkout - uses: actions/checkout@v4 + - uses: actions/checkout@v4 + - uses: hynek/build-and-inspect-python-package@v2 - - name: Set up Python - uses: actions/setup-python@v5 + deploy: + runs-on: ubuntu-latest + if: startsWith(github.ref, 'refs/tags/v') + steps: + - uses: actions/download-artifact@v4 with: - python-version: '3.11' - - - name: Install dependencies for build - run: pip install --upgrade setuptools build - - - name: Build - run: python -m build + name: Packages + path: dist - name: Publish package uses: pypa/gh-action-pypi-publish@release/v1 with: - user: __token__ password: ${{ secrets.pypi_password }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 5c7fd55..22c5441 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -37,11 +37,10 @@ jobs: with: python-version: ${{ matrix.python-version }} - - name: Install test dependencies - run: pip install tox tox-gh-actions + - uses: astral-sh/setup-uv@v3 - - name: Test packaging - run: tox -e pkg + - name: Install tox + run: uv tool install --with tox-gh-actions --with tox-uv tox - name: Run tests with PyTest 6 run: tox @@ -57,7 +56,12 @@ jobs: post-test: name: All tests passed + if: always() + needs: [test] runs-on: ubuntu-latest - needs: test + timeout-minutes: 2 steps: - - run: echo ok + - name: Decide whether the needed jobs succeeded or failed + uses: re-actors/alls-green@release/v1 + with: + jobs: ${{ toJSON(needs) }} diff --git a/tox.ini b/tox.ini index 3e51181..877d362 100644 --- a/tox.ini +++ b/tox.ini @@ -1,7 +1,6 @@ [tox] envlist = py{38,39,310,311,312}-pytest{6,7,8} - pkg [gh-actions] python = @@ -25,17 +24,3 @@ deps = pytest8: pytest>=8.0.0,<9.0.0 commands = {envpython} -m pytest {posargs} - -[testenv:pkg] -skip_install = true -deps = - twine - build -commands = - {envpython} -c 'import os.path, shutil, sys; \ - dist_dir = os.path.join("{toxinidir}", "dist"); \ - os.path.isdir(dist_dir) or sys.exit(0); \ - print("Removing \{!s\} contents...".format(dist_dir), file=sys.stderr); \ - shutil.rmtree(dist_dir)' - {envpython} -m build --outdir {toxinidir}/dist/ {toxinidir} - {envpython} -m twine check --strict dist/* From 6e66cd895fe05cd09be8bad58f5d79110a20385f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 Nov 2024 00:45:13 +0000 Subject: [PATCH 14/25] build(deps): bump astral-sh/setup-uv from 3 to 4 (#94) --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 22c5441..c570d28 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -37,7 +37,7 @@ jobs: with: python-version: ${{ matrix.python-version }} - - uses: astral-sh/setup-uv@v3 + - uses: astral-sh/setup-uv@v4 - name: Install tox run: uv tool install --with tox-gh-actions --with tox-uv tox From ba478fcb701d003cc76dbcfc3f0ccb4b39df3135 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 23 Dec 2024 00:21:32 +0000 Subject: [PATCH 15/25] build(deps): bump astral-sh/setup-uv from 4 to 5 (#95) --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index c570d28..97916b1 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -37,7 +37,7 @@ jobs: with: python-version: ${{ matrix.python-version }} - - uses: astral-sh/setup-uv@v4 + - uses: astral-sh/setup-uv@v5 - name: Install tox run: uv tool install --with tox-gh-actions --with tox-uv tox From e4336fbceb92e1673967b1f1bd9ca50ac947d7ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edgar=20Ram=C3=ADrez=20Mondrag=C3=B3n?= <16805946+edgarrmondragon@users.noreply.github.com> Date: Fri, 17 Jan 2025 13:23:35 -0600 Subject: [PATCH 16/25] Bump Ruff and use formatter (#96) --- .pre-commit-config.yaml | 3 ++- plugin_test.py | 4 +++- pyproject.toml | 1 - pytest_github_actions_annotate_failures/plugin.py | 6 ++---- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 091ecc2..eb8015c 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -14,7 +14,8 @@ repos: - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.7.0" + rev: "v0.9.2" hooks: - id: ruff args: ["--fix", "--show-fixes"] + - id: ruff-format diff --git a/plugin_test.py b/plugin_test.py index 3037fa7..b827269 100644 --- a/plugin_test.py +++ b/plugin_test.py @@ -49,7 +49,9 @@ def test_error(): result = testdir.runpytest_subprocess() result.stderr.re_match_lines( - [r"::error file=test_annotation_pytest_error\.py,line=8::test_error.*",] + [ + r"::error file=test_annotation_pytest_error\.py,line=8::test_error.*", + ] ) diff --git a/pyproject.toml b/pyproject.toml index a4c5cb6..70e582c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -77,7 +77,6 @@ extend-select = [ ] ignore = [ "PLR", # Design related pylint codes - "PT004", # Use underscore for non-returning fixture (use usefixture instead) ] isort.required-imports = ["from __future__ import annotations"] diff --git a/pytest_github_actions_annotate_failures/plugin.py b/pytest_github_actions_annotate_failures/plugin.py index 0c364ea..2c29fad 100644 --- a/pytest_github_actions_annotate_failures/plugin.py +++ b/pytest_github_actions_annotate_failures/plugin.py @@ -1,4 +1,3 @@ - from __future__ import annotations import contextlib @@ -133,6 +132,7 @@ def pytest_addoption(parser): help="Annotate failures in GitHub Actions.", ) + def pytest_configure(config): if not config.option.exclude_warning_annotations: config.pluginmanager.register(_AnnotateWarnings(), "annotate_warnings") @@ -160,9 +160,7 @@ def _build_workflow_command( ("title", title), ] - result = result + ",".join( - f"{k}={v}" for k, v in entries if v is not None - ) + result = result + ",".join(f"{k}={v}" for k, v in entries if v is not None) if message is not None: result = result + "::" + _escape(message) From fd623c13147eb6b48a87f1c44ae69c15ae976be8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edgar=20Ram=C3=ADrez=20Mondrag=C3=B3n?= <16805946+edgarrmondragon@users.noreply.github.com> Date: Fri, 17 Jan 2025 13:28:14 -0600 Subject: [PATCH 17/25] fix: support Pytest 7.4+ (#97) Co-authored-by: Henry Schreiner --- .github/workflows/test.yml | 6 ++ plugin_test.py | 2 +- .../plugin.py | 74 ++++++++++--------- tox.ini | 2 +- 4 files changed, 48 insertions(+), 36 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 97916b1..d5d4310 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -54,6 +54,12 @@ jobs: PYTEST_MAJOR_VERSION: 7 PYTEST_PLUGINS: pytest_github_actions_annotate_failures + - name: Run tests with PyTest 8 + run: tox + env: + PYTEST_MAJOR_VERSION: 8 + PYTEST_PLUGINS: pytest_github_actions_annotate_failures + post-test: name: All tests passed if: always() diff --git a/plugin_test.py b/plugin_test.py index b827269..1b32b6c 100644 --- a/plugin_test.py +++ b/plugin_test.py @@ -223,7 +223,7 @@ def test_fail(): result = testdir.runpytest_subprocess("--rootdir=foo") result.stderr.fnmatch_lines( [ - "::error file=test_annotation_fail_cwd.py,line=5::test_fail*assert 0*", + "::error file=test_annotation_fail_cwd0/test_annotation_fail_cwd.py,line=5::test_fail*assert 0*", ] ) diff --git a/pytest_github_actions_annotate_failures/plugin.py b/pytest_github_actions_annotate_failures/plugin.py index 2c29fad..3f58b95 100644 --- a/pytest_github_actions_annotate_failures/plugin.py +++ b/pytest_github_actions_annotate_failures/plugin.py @@ -6,7 +6,7 @@ from typing import TYPE_CHECKING import pytest -from _pytest._code.code import ExceptionRepr +from _pytest._code.code import ExceptionRepr, ReprEntry from packaging import version if TYPE_CHECKING: @@ -38,32 +38,12 @@ def pytest_runtest_makereport(item: Item, call): # noqa: ARG001 return if report.when == "call" and report.failed: - # collect information to be annotated filesystempath, lineno, _ = report.location - runpath = os.environ.get("PYTEST_RUN_PATH") - if runpath: - filesystempath = os.path.join(runpath, filesystempath) - - # try to convert to absolute path in GitHub Actions - workspace = os.environ.get("GITHUB_WORKSPACE") - if workspace: - full_path = os.path.abspath(filesystempath) - try: - rel_path = os.path.relpath(full_path, workspace) - except ValueError: - # os.path.relpath() will raise ValueError on Windows - # when full_path and workspace have different mount points. - # https://github.com/utgwkk/pytest-github-actions-annotate-failures/issues/20 - rel_path = filesystempath - if not rel_path.startswith(".."): - filesystempath = rel_path - if lineno is not None: # 0-index to 1-index lineno += 1 - # get the name of the current failed test, with parametrize info longrepr = report.head_line or item.name # get the error message and line number from the actual error @@ -71,26 +51,52 @@ def pytest_runtest_makereport(item: Item, call): # noqa: ARG001 if report.longrepr.reprcrash is not None: longrepr += "\n\n" + report.longrepr.reprcrash.message tb_entries = report.longrepr.reprtraceback.reprentries - if len(tb_entries) > 1 and tb_entries[0].reprfileloc is not None: + if tb_entries: + entry = tb_entries[0] # Handle third-party exceptions - lineno = tb_entries[0].reprfileloc.lineno + if isinstance(entry, ReprEntry) and entry.reprfileloc is not None: + lineno = entry.reprfileloc.lineno + filesystempath = entry.reprfileloc.path + elif report.longrepr.reprcrash is not None: lineno = report.longrepr.reprcrash.lineno elif isinstance(report.longrepr, tuple): - _, lineno, message = report.longrepr + filesystempath, lineno, message = report.longrepr longrepr += "\n\n" + message elif isinstance(report.longrepr, str): longrepr += "\n\n" + report.longrepr workflow_command = _build_workflow_command( "error", - filesystempath, + compute_path(filesystempath), lineno, message=longrepr, ) print(workflow_command, file=sys.stderr) +def compute_path(filesystempath: str) -> str: + """Extract and process location information from the report.""" + runpath = os.environ.get("PYTEST_RUN_PATH") + if runpath: + filesystempath = os.path.join(runpath, filesystempath) + + # try to convert to absolute path in GitHub Actions + workspace = os.environ.get("GITHUB_WORKSPACE") + if workspace: + full_path = os.path.abspath(filesystempath) + try: + rel_path = os.path.relpath(full_path, workspace) + except ValueError: + # os.path.relpath() will raise ValueError on Windows + # when full_path and workspace have different mount points. + rel_path = filesystempath + if not rel_path.startswith(".."): + filesystempath = rel_path + + return filesystempath + + class _AnnotateWarnings: def pytest_warning_recorded(self, warning_message, when, nodeid, location): # noqa: ARG002 # enable only in a workflow of GitHub Actions @@ -139,14 +145,14 @@ def pytest_configure(config): def _build_workflow_command( - command_name, - file, - line, - end_line=None, - column=None, - end_column=None, - title=None, - message=None, + command_name: str, + file: str, + line: int, + end_line: int | None = None, + column: int | None = None, + end_column: int | None = None, + title: str | None = None, + message: str | None = None, ): """Build a command to annotate a workflow.""" result = f"::{command_name} " @@ -168,5 +174,5 @@ def _build_workflow_command( return result -def _escape(s): +def _escape(s: str) -> str: return s.replace("%", "%25").replace("\r", "%0D").replace("\n", "%0A") diff --git a/tox.ini b/tox.ini index 877d362..11016c2 100644 --- a/tox.ini +++ b/tox.ini @@ -20,7 +20,7 @@ PYTEST_MAJOR_VERSION = extras = test deps = pytest6: pytest>=6.0.0,<7.0.0 - pytest7: pytest>=7.0.0,<7.4.0 + pytest7: pytest>=7.0.0,<8.0.0 pytest8: pytest>=8.0.0,<9.0.0 commands = {envpython} -m pytest {posargs} From b18bbb5148762b3c31e6f9462a8e457c5b28a5c3 Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Fri, 17 Jan 2025 14:38:11 -0500 Subject: [PATCH 18/25] ci: add 3.13 (#89) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * ci: add 3.13 * Update tox.ini * Update pyproject.toml * Update test.yml * Update test.yml --------- Co-authored-by: Edgar Ramírez Mondragón <16805946+edgarrmondragon@users.noreply.github.com> --- .github/workflows/test.yml | 11 +++++++---- pyproject.toml | 1 + tox.ini | 3 ++- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index d5d4310..b0fbd82 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -26,6 +26,7 @@ jobs: - '3.10' - '3.11' - '3.12' + - '3.13' runs-on: ${{ matrix.os }} name: ${{ matrix.os }}, Python ${{ matrix.python-version }} @@ -42,22 +43,24 @@ jobs: - name: Install tox run: uv tool install --with tox-gh-actions --with tox-uv tox - - name: Run tests with PyTest 6 + - name: Run tests with PyTest 8 run: tox env: - PYTEST_MAJOR_VERSION: 6 + PYTEST_MAJOR_VERSION: 8 PYTEST_PLUGINS: pytest_github_actions_annotate_failures - name: Run tests with PyTest 7 run: tox + if: runner.os != 'Windows' env: PYTEST_MAJOR_VERSION: 7 PYTEST_PLUGINS: pytest_github_actions_annotate_failures - - name: Run tests with PyTest 8 + - name: Run tests with PyTest 6 run: tox + if: runner.os != 'Windows' env: - PYTEST_MAJOR_VERSION: 8 + PYTEST_MAJOR_VERSION: 6 PYTEST_PLUGINS: pytest_github_actions_annotate_failures post-test: diff --git a/pyproject.toml b/pyproject.toml index 70e582c..3458c6d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -30,6 +30,7 @@ classifiers = [ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", "Programming Language :: Python :: 3 :: Only", "Programming Language :: Python", "Topic :: System :: Systems Administration", diff --git a/tox.ini b/tox.ini index 11016c2..bc948ac 100644 --- a/tox.ini +++ b/tox.ini @@ -1,6 +1,6 @@ [tox] envlist = - py{38,39,310,311,312}-pytest{6,7,8} + py{38,39,310,311,312,313}-pytest{6,7,8} [gh-actions] python = @@ -9,6 +9,7 @@ python = 3.10: py310 3.11: py311 3.12: py312 + 3.13: py313 [gh-actions:env] PYTEST_MAJOR_VERSION = From 5f93cf9f53cb973821f2fc3a2abbd2fd75280ea8 Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Fri, 17 Jan 2025 15:13:44 -0500 Subject: [PATCH 19/25] chore: use dependency-groups (#99) Signed-off-by: Henry Schreiner --- pyproject.toml | 3 ++- tox.ini | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 3458c6d..02e6e27 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -51,7 +51,8 @@ changelog = "https://github.com/pytest-dev/pytest-github-actions-annotate-failur [project.entry-points.pytest11] pytest_github_actions_annotate_failures = "pytest_github_actions_annotate_failures.plugin" -[project.optional-dependencies] +[dependency-groups] +dev = [{ include-group = "test"}] test = ["packaging"] diff --git a/tox.ini b/tox.ini index bc948ac..f743182 100644 --- a/tox.ini +++ b/tox.ini @@ -18,7 +18,8 @@ PYTEST_MAJOR_VERSION = 8: pytest8 [testenv] -extras = test +min_version = 4.22.0 +groups = test deps = pytest6: pytest>=6.0.0,<7.0.0 pytest7: pytest>=7.0.0,<8.0.0 From c3c29e94cb150cca9b913d8af41538aacde55b84 Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Fri, 17 Jan 2025 16:27:52 -0500 Subject: [PATCH 20/25] ci: add github attestations (#100) Signed-off-by: Henry Schreiner --- .github/workflows/deploy.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 229b86e..a57dcb6 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -19,12 +19,20 @@ jobs: deploy: runs-on: ubuntu-latest if: startsWith(github.ref, 'refs/tags/v') + permissions: + attestations: write + steps: - uses: actions/download-artifact@v4 with: name: Packages path: dist + - name: Generate artifact attestation for sdist and wheel + uses: actions/attest-build-provenance@v2 + with: + subject-path: "dist/*" + - name: Publish package uses: pypa/gh-action-pypi-publish@release/v1 with: From 5da3a466611d782772dbb32cdf934b9c0edb7edc Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Fri, 17 Jan 2025 16:42:24 -0500 Subject: [PATCH 21/25] chore: prepare for 0.3 (#98) * chore: prepare for 0.3 * Update CHANGELOG.md * Update CHANGELOG.md --- CHANGELOG.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index abcb1d1..4a04a57 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,8 +4,14 @@ ### Incompatible changes -- Require python 3.8+ #87 (thanks to @edgarrmondragon) +- Test on Python 3.13 #89 +- Support pytest 7.4+ #97 (thanks to @edgarrmondragon) +- Require Python 3.8+ #87 (thanks to @edgarrmondragon) - Require pytest 6+ #86 (thanks to @edgarrmondragon) +- Speed up CI and testing #93 +- Use Ruff formatter #96 +- Use dependency-groups for tests #99 +- Add GitHub Attestations #100 ## 0.2.0 (2023-05-04) From f5a1662d6d1a33b877376cd0cf74173a12a980de Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Fri, 17 Jan 2025 17:13:48 -0500 Subject: [PATCH 22/25] chore: release 0.3 (#101) * chore: release 0.3 * Update pyproject.toml * Update CHANGELOG.md --- CHANGELOG.md | 4 +++- pyproject.toml | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4a04a57..187567a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,9 @@ ## Unreleased -### Incompatible changes +Nothing yet. + +## 0.3.0 (2025-01-17) - Test on Python 3.13 #89 - Support pytest 7.4+ #97 (thanks to @edgarrmondragon) diff --git a/pyproject.toml b/pyproject.toml index 02e6e27..291c086 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -9,7 +9,7 @@ build-backend = "setuptools.build_meta" [project] # https://peps.python.org/pep-0621/#readme requires-python = ">=3.8" -version = "0.2.0" +version = "0.3.0" name = "pytest-github-actions-annotate-failures" description = "pytest plugin to annotate failed tests with a workflow command for GitHub Actions" readme = "README.md" From dfe556ccc7db703e5e33c6ab94d433847b57bfba Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Fri, 17 Jan 2025 17:23:33 -0500 Subject: [PATCH 23/25] ci: missing needs in deploy (#102) Signed-off-by: Henry Schreiner --- .github/workflows/deploy.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index a57dcb6..c971b61 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -17,6 +17,7 @@ jobs: - uses: hynek/build-and-inspect-python-package@v2 deploy: + needs: [dist] runs-on: ubuntu-latest if: startsWith(github.ref, 'refs/tags/v') permissions: From 739d5d436ebcc4255b515641334b55b49348c6c0 Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Fri, 17 Jan 2025 17:29:05 -0500 Subject: [PATCH 24/25] ci: token permissions (#103) Signed-off-by: Henry Schreiner --- .github/workflows/deploy.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index c971b61..a368436 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -21,6 +21,7 @@ jobs: runs-on: ubuntu-latest if: startsWith(github.ref, 'refs/tags/v') permissions: + token: write attestations: write steps: From f07eea3600b8132286c57f3ec6e4d40da6d80ece Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Fri, 17 Jan 2025 17:38:28 -0500 Subject: [PATCH 25/25] ci: id-token, not token (#104) Signed-off-by: Henry Schreiner --- .github/workflows/deploy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index a368436..d194fab 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -21,7 +21,7 @@ jobs: runs-on: ubuntu-latest if: startsWith(github.ref, 'refs/tags/v') permissions: - token: write + id-token: write attestations: write steps: