From 330db2f8d00a68a6780c738227316fcd239cc018 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 31 May 2026 00:37:51 +0000 Subject: [PATCH 01/22] chore(deps): update all non-major dependencies --- .github/workflows/lock.yml | 2 +- .pre-commit-config.yaml | 4 ++-- requirements-lint.txt | 2 +- requirements-test.txt | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/lock.yml b/.github/workflows/lock.yml index 809c36a87..77a83b6a8 100644 --- a/.github/workflows/lock.yml +++ b/.github/workflows/lock.yml @@ -15,6 +15,6 @@ jobs: action: runs-on: ubuntu-latest steps: - - uses: dessant/lock-threads@v6.0.1 + - uses: dessant/lock-threads@v6.0.2 with: process-only: 'issues' diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index b0be8e1b2..289dcd92c 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -7,7 +7,7 @@ repos: hooks: - id: black - repo: https://github.com/commitizen-tools/commitizen - rev: v4.16.2 + rev: v4.16.3 hooks: - id: commitizen stages: [commit-msg] @@ -51,6 +51,6 @@ repos: - id: rst-directive-colons - id: rst-inline-touching-normal - repo: https://github.com/maxbrunet/pre-commit-renovate - rev: 43.150.0 + rev: 43.205.2 hooks: - id: renovate-config-validator diff --git a/requirements-lint.txt b/requirements-lint.txt index 9fefc4ee7..7379d0aa5 100644 --- a/requirements-lint.txt +++ b/requirements-lint.txt @@ -1,7 +1,7 @@ -r requirements.txt argcomplete==2.0.0 black==26.5.1 -commitizen==4.16.2 +commitizen==4.16.3 flake8==7.3.0 isort==8.0.1 mypy==1.20.2 diff --git a/requirements-test.txt b/requirements-test.txt index 185116805..d978c968b 100644 --- a/requirements-test.txt +++ b/requirements-test.txt @@ -1,7 +1,7 @@ -r requirements.txt anyio==4.13.0 build==1.5.0 -coverage==7.14.0 +coverage==7.14.1 pytest-console-scripts==1.4.1 pytest-cov==7.1.0 pytest-github-actions-annotate-failures==0.4.0 From 281532496c6d390c7cee7dade8511d9879cfd47d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 28 May 2026 06:01:28 +0000 Subject: [PATCH 02/22] chore(deps): update dependency mypy to v2 --- requirements-lint.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-lint.txt b/requirements-lint.txt index 7379d0aa5..0dc570ce7 100644 --- a/requirements-lint.txt +++ b/requirements-lint.txt @@ -4,7 +4,7 @@ black==26.5.1 commitizen==4.16.3 flake8==7.3.0 isort==8.0.1 -mypy==1.20.2 +mypy==2.1.0 pylint==4.0.5 pytest==9.0.3 responses==0.26.1 From 9a99749899d0372ce97156c0751563ec10b7f4ef Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 22 Jun 2026 01:05:12 +0000 Subject: [PATCH 03/22] chore(deps): update actions/checkout action to v7 --- .github/workflows/docs.yml | 4 ++-- .github/workflows/lint.yml | 2 +- .github/workflows/pre_commit.yml | 2 +- .github/workflows/release.yml | 2 +- .github/workflows/test.yml | 10 +++++----- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 899f8fabf..98020ab13 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -22,7 +22,7 @@ jobs: sphinx: runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@v6.0.2 + - uses: actions/checkout@v7.0.0 - name: Set up Python uses: actions/setup-python@v6.2.0 with: @@ -37,7 +37,7 @@ jobs: twine-check: runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@v6.0.2 + - uses: actions/checkout@v7.0.0 - name: Set up Python uses: actions/setup-python@v6.2.0 with: diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 7a0dd38dc..6bb5bbfbc 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -22,7 +22,7 @@ jobs: lint: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v6.0.2 + - uses: actions/checkout@v7.0.0 with: fetch-depth: 0 - uses: actions/setup-python@v6.2.0 diff --git a/.github/workflows/pre_commit.yml b/.github/workflows/pre_commit.yml index 993606750..0317ebdc1 100644 --- a/.github/workflows/pre_commit.yml +++ b/.github/workflows/pre_commit.yml @@ -29,7 +29,7 @@ jobs: pre_commit: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v6.0.2 + - uses: actions/checkout@v7.0.0 - uses: actions/setup-python@v6.2.0 with: python-version: "3.14" diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 01829b244..5b21fec24 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -14,7 +14,7 @@ jobs: id-token: write environment: pypi.org steps: - - uses: actions/checkout@v6.0.2 + - uses: actions/checkout@v7.0.0 with: fetch-depth: 0 token: ${{ secrets.RELEASE_GITHUB_TOKEN }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 4cd761ad6..016a0e993 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -46,7 +46,7 @@ jobs: version: "3.14" toxenv: py314,smoke steps: - - uses: actions/checkout@v6.0.2 + - uses: actions/checkout@v7.0.0 - name: Set up Python ${{ matrix.python.version }} uses: actions/setup-python@v6.2.0 with: @@ -65,7 +65,7 @@ jobs: matrix: toxenv: [api_func_v4, cli_func_v4] steps: - - uses: actions/checkout@v6.0.2 + - uses: actions/checkout@v7.0.0 - name: Set up Python uses: actions/setup-python@v6.2.0 with: @@ -87,7 +87,7 @@ jobs: coverage: runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@v6.0.2 + - uses: actions/checkout@v7.0.0 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v6.2.0 with: @@ -111,7 +111,7 @@ jobs: runs-on: ubuntu-latest name: Python wheel steps: - - uses: actions/checkout@v6.0.2 + - uses: actions/checkout@v7.0.0 - uses: actions/setup-python@v6.2.0 with: python-version: "3.14" @@ -129,7 +129,7 @@ jobs: runs-on: ubuntu-latest needs: [dist] steps: - - uses: actions/checkout@v6.0.2 + - uses: actions/checkout@v7.0.0 - name: Set up Python uses: actions/setup-python@v6.2.0 with: From c1c54f0b9b7be1fe51510e7cec0ec0a89c032d39 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 15 Jun 2026 00:43:19 +0000 Subject: [PATCH 04/22] chore(deps): update codecov/codecov-action action to v7 --- .github/workflows/test.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 016a0e993..8145d2667 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -77,7 +77,7 @@ jobs: TOXENV: ${{ matrix.toxenv }} run: tox -- --override-ini='log_cli=True' - name: Upload codecov coverage - uses: codecov/codecov-action@v6.0.1 + uses: codecov/codecov-action@v7.0.0 with: files: ./coverage.xml flags: ${{ matrix.toxenv }} @@ -100,7 +100,7 @@ jobs: TOXENV: cover run: tox - name: Upload codecov coverage - uses: codecov/codecov-action@v6.0.1 + uses: codecov/codecov-action@v7.0.0 with: files: ./coverage.xml flags: unit From 2dbe168e07887fec0000d62da8a45b1602c972d7 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 29 Jun 2026 12:33:24 +0000 Subject: [PATCH 05/22] chore(deps): update all non-major dependencies --- .github/workflows/docs.yml | 4 ++-- .github/workflows/lint.yml | 2 +- .github/workflows/pre_commit.yml | 2 +- .github/workflows/test.yml | 10 +++++----- .pre-commit-config.yaml | 6 +++--- requirements-lint.txt | 6 +++--- requirements-test.txt | 8 ++++---- 7 files changed, 19 insertions(+), 19 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 98020ab13..4baaea006 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -24,7 +24,7 @@ jobs: steps: - uses: actions/checkout@v7.0.0 - name: Set up Python - uses: actions/setup-python@v6.2.0 + uses: actions/setup-python@v6.3.0 with: python-version: "3.14" - name: Install dependencies @@ -39,7 +39,7 @@ jobs: steps: - uses: actions/checkout@v7.0.0 - name: Set up Python - uses: actions/setup-python@v6.2.0 + uses: actions/setup-python@v6.3.0 with: python-version: "3.14" - name: Install dependencies diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 6bb5bbfbc..7bc5db535 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -25,7 +25,7 @@ jobs: - uses: actions/checkout@v7.0.0 with: fetch-depth: 0 - - uses: actions/setup-python@v6.2.0 + - uses: actions/setup-python@v6.3.0 with: python-version: "3.14" - run: pip install --upgrade tox diff --git a/.github/workflows/pre_commit.yml b/.github/workflows/pre_commit.yml index 0317ebdc1..7f7634870 100644 --- a/.github/workflows/pre_commit.yml +++ b/.github/workflows/pre_commit.yml @@ -30,7 +30,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v7.0.0 - - uses: actions/setup-python@v6.2.0 + - uses: actions/setup-python@v6.3.0 with: python-version: "3.14" - name: install tox diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 8145d2667..68a223cb5 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -48,7 +48,7 @@ jobs: steps: - uses: actions/checkout@v7.0.0 - name: Set up Python ${{ matrix.python.version }} - uses: actions/setup-python@v6.2.0 + uses: actions/setup-python@v6.3.0 with: python-version: ${{ matrix.python.version }} - name: Install dependencies @@ -67,7 +67,7 @@ jobs: steps: - uses: actions/checkout@v7.0.0 - name: Set up Python - uses: actions/setup-python@v6.2.0 + uses: actions/setup-python@v6.3.0 with: python-version: "3.14" - name: Install dependencies @@ -89,7 +89,7 @@ jobs: steps: - uses: actions/checkout@v7.0.0 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v6.2.0 + uses: actions/setup-python@v6.3.0 with: python-version: "3.14" - name: Install dependencies @@ -112,7 +112,7 @@ jobs: name: Python wheel steps: - uses: actions/checkout@v7.0.0 - - uses: actions/setup-python@v6.2.0 + - uses: actions/setup-python@v6.3.0 with: python-version: "3.14" - name: Install dependencies @@ -131,7 +131,7 @@ jobs: steps: - uses: actions/checkout@v7.0.0 - name: Set up Python - uses: actions/setup-python@v6.2.0 + uses: actions/setup-python@v6.3.0 with: python-version: '3.14' - uses: actions/download-artifact@v8.0.1 diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 289dcd92c..9774d5008 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -7,7 +7,7 @@ repos: hooks: - id: black - repo: https://github.com/commitizen-tools/commitizen - rev: v4.16.3 + rev: v4.16.4 hooks: - id: commitizen stages: [commit-msg] @@ -20,7 +20,7 @@ repos: hooks: - id: isort - repo: https://github.com/pycqa/pylint - rev: v4.0.5 + rev: v4.0.6 hooks: - id: pylint additional_dependencies: @@ -51,6 +51,6 @@ repos: - id: rst-directive-colons - id: rst-inline-touching-normal - repo: https://github.com/maxbrunet/pre-commit-renovate - rev: 43.205.2 + rev: 43.247.0 hooks: - id: renovate-config-validator diff --git a/requirements-lint.txt b/requirements-lint.txt index 0dc570ce7..dcd97d44f 100644 --- a/requirements-lint.txt +++ b/requirements-lint.txt @@ -1,12 +1,12 @@ -r requirements.txt argcomplete==2.0.0 black==26.5.1 -commitizen==4.16.3 +commitizen==4.16.4 flake8==7.3.0 isort==8.0.1 mypy==2.1.0 -pylint==4.0.5 -pytest==9.0.3 +pylint==4.0.6 +pytest==9.1.1 responses==0.26.1 respx==0.23.1 types-PyYAML==6.0.12.20260518 diff --git a/requirements-test.txt b/requirements-test.txt index d978c968b..a7981a09a 100644 --- a/requirements-test.txt +++ b/requirements-test.txt @@ -1,11 +1,11 @@ -r requirements.txt -anyio==4.13.0 +anyio==4.14.1 build==1.5.0 -coverage==7.14.1 +coverage==7.14.3 pytest-console-scripts==1.4.1 pytest-cov==7.1.0 -pytest-github-actions-annotate-failures==0.4.0 -pytest==9.0.3 +pytest-github-actions-annotate-failures==0.4.2 +pytest==9.1.1 PyYaml==6.0.3 responses==0.26.1 respx==0.23.1 From 72134f5369cd4568a2374f25543071245375d26e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Laurent=20Rivi=C3=A8re?= Date: Wed, 1 Jul 2026 12:01:33 +0200 Subject: [PATCH 06/22] fix: typo --- gitlab/client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gitlab/client.py b/gitlab/client.py index ea3a0c209..e12efd321 100644 --- a/gitlab/client.py +++ b/gitlab/client.py @@ -793,7 +793,7 @@ def http_get( **kwargs: Extra options to send to the server (e.g. sudo) Returns: - A requests result object is streamed is True or the content type is + A requests result object if streamed is True or the content type is not json. The parsed json data otherwise. From 046fbac664e033a0a5a65417bfd229e91a1fd09f Mon Sep 17 00:00:00 2001 From: Marko Todoric Date: Sun, 5 Jul 2026 13:10:13 +0200 Subject: [PATCH 07/22] fix(client): retry fetching server version after an unknown result Previously, once `version()` failed to retrieve the server version and cached "unknown" for `_server_version`/`_server_revision`, all subsequent calls would short-circuit on the `is None` check and keep returning the cached "unknown" values forever, even if the server was reachable again. Now `version()` also retries when the cached value is "unknown". --- gitlab/client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gitlab/client.py b/gitlab/client.py index e12efd321..6e5672f2b 100644 --- a/gitlab/client.py +++ b/gitlab/client.py @@ -404,7 +404,7 @@ def version(self) -> tuple[str, str]: The server version and server revision. ('unknown', 'unknown') if the server doesn't perform as expected. """ - if self._server_version is None: + if self._server_version in (None, "unknown"): try: data = self.http_get("/version") if isinstance(data, dict): From 193c9630fc6cf4b512e969959cb23fa631d5fb52 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 6 Jul 2026 03:20:11 +0000 Subject: [PATCH 08/22] chore(deps): update pre-commit hook pre-commit/mirrors-mypy to v2 --- .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 9774d5008..03ab29588 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -32,7 +32,7 @@ repos: - requests-toolbelt==1.0.0 files: 'gitlab/' - repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.20.2 + rev: v2.1.0 hooks: - id: mypy args: [] From 1aae1db2b90544414ac6414fcacfc43350d4aaab Mon Sep 17 00:00:00 2001 From: Steve Traylen Date: Fri, 3 Jul 2026 12:17:04 +0200 Subject: [PATCH 09/22] chore(deps): update dependency argparse to v3 I checked with latest `argcomplete == 3.7.0` and certainly the completion in bash is working with a quick check. --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 45e8c36f8..511e6c366 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -41,7 +41,7 @@ license = {text = "LGPL-3.0-or-later"} dynamic = ["version"] [project.optional-dependencies] -autocompletion = ["argcomplete>=1.10.0,<3"] +autocompletion = ["argcomplete>=1.10.0,<4"] yaml = ["PyYaml>=6.0.1"] graphql = ["gql[httpx]>=3.5.0,<5"] From 4e32439deaa9516a48becf9a7fc9cdb7723207c6 Mon Sep 17 00:00:00 2001 From: Ben Brown Date: Fri, 29 May 2026 12:20:58 +0100 Subject: [PATCH 10/22] feat(client): additionally handle retries for request timeouts --- docs/api-usage-advanced.rst | 3 ++- gitlab/client.py | 10 +++++++--- tests/unit/test_gitlab_http_methods.py | 1 + 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/docs/api-usage-advanced.rst b/docs/api-usage-advanced.rst index d6514c7b3..d8ed4a1f1 100644 --- a/docs/api-usage-advanced.rst +++ b/docs/api-usage-advanced.rst @@ -147,7 +147,8 @@ python-gitlab can automatically retry in such case, when ``retry_transient_errors`` argument is set to ``True``. When enabled, HTTP error codes 500 (Internal Server Error), 502 (502 Bad Gateway), 503 (Service Unavailable), 504 (Gateway Timeout), and Cloudflare -errors (520-530) are retried. +errors (520-530) are retried. `requests.exceptions.Timeout` are also +handled. Additionally, HTTP error code 409 (Conflict) is retried if the reason is a diff --git a/gitlab/client.py b/gitlab/client.py index 6e5672f2b..f6fe89d84 100644 --- a/gitlab/client.py +++ b/gitlab/client.py @@ -60,7 +60,7 @@ class Gitlab: order_by: Set order_by globally user_agent: A custom user agent to use for making HTTP requests. retry_transient_errors: Whether to retry after 500, 502, 503, 504 - or 52x responses. Defaults to False. + or 52x responses, or after a request timeout. Defaults to False. keep_base_url: keep user-provided base URL for pagination if it differs from response headers @@ -665,7 +665,7 @@ def http_request( obey_rate_limit: Whether to obey 429 Too Many Request responses. Defaults to True. retry_transient_errors: Whether to retry after 500, 502, 503, 504 - or 52x responses. Defaults to False. + or 52x responses, or after a request timeout. Defaults to False. max_retries: Max retries after 429 or transient errors, set to -1 to retry forever. Defaults to 10. extra_headers: Add and override HTTP headers for the request. @@ -737,7 +737,11 @@ def http_request( stream=streamed, **opts, ) - except (requests.ConnectionError, requests.exceptions.ChunkedEncodingError): + except ( + requests.ConnectionError, + requests.exceptions.ChunkedEncodingError, + requests.exceptions.Timeout, + ): if retry.handle_retry(): continue raise diff --git a/tests/unit/test_gitlab_http_methods.py b/tests/unit/test_gitlab_http_methods.py index f85035fc2..00d96d0be 100644 --- a/tests/unit/test_gitlab_http_methods.py +++ b/tests/unit/test_gitlab_http_methods.py @@ -146,6 +146,7 @@ def test_http_request_extra_headers(gl): [ requests.ConnectionError("Connection aborted."), requests.exceptions.ChunkedEncodingError("Connection broken."), + requests.exceptions.Timeout("Request timed out."), ], ) def test_http_request_with_retry_on_method_for_transient_network_failures( From a9c5d17d3ab57d448be6dd5eac3b7ec9eb680261 Mon Sep 17 00:00:00 2001 From: "John L. Villalovos" Date: Thu, 9 Jul 2026 11:51:44 -0700 Subject: [PATCH 11/22] ci: run the pre-commit rst checks in the CI These were only being run when a modification happened to pre-commit --- .github/workflows/lint.yml | 2 ++ tox.ini | 10 +++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 7bc5db535..5d3c5f319 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -41,3 +41,5 @@ jobs: run: tox -e isort -- --check - name: Run pylint Python code static checker (https://github.com/PyCQA/pylint) run: tox -e pylint + - name: Run pre-commit rst checks (https://pre-commit.com/) + run: tox -e pre-commit-rst diff --git a/tox.ini b/tox.ini index 0ba295692..5e7c01076 100644 --- a/tox.ini +++ b/tox.ini @@ -146,9 +146,17 @@ commands = pytest tests/smoke {posargs} [testenv:pre-commit] skip_install = true -deps = -r requirements-precommit.txt +deps = -r {toxinidir}/requirements-precommit.txt commands = pre-commit run --all-files --show-diff-on-failure +[testenv:pre-commit-rst] +skip_install = true +deps = -r {toxinidir}/requirements-precommit.txt +commands = + pre-commit run rst-backticks --all-files --show-diff-on-failure + pre-commit run rst-directive-colons --all-files --show-diff-on-failure + pre-commit run rst-inline-touching-normal --all-files --show-diff-on-failure + [testenv:install] skip_install = true deps = -r{toxinidir}/requirements.txt From e57559e8c1bea1ba580074e83d21072d9b80d582 Mon Sep 17 00:00:00 2001 From: "John L. Villalovos" Date: Thu, 9 Jul 2026 11:49:13 -0700 Subject: [PATCH 12/22] docs: correct error with backticks --- docs/api-usage-advanced.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api-usage-advanced.rst b/docs/api-usage-advanced.rst index d8ed4a1f1..06c060455 100644 --- a/docs/api-usage-advanced.rst +++ b/docs/api-usage-advanced.rst @@ -147,7 +147,7 @@ python-gitlab can automatically retry in such case, when ``retry_transient_errors`` argument is set to ``True``. When enabled, HTTP error codes 500 (Internal Server Error), 502 (502 Bad Gateway), 503 (Service Unavailable), 504 (Gateway Timeout), and Cloudflare -errors (520-530) are retried. `requests.exceptions.Timeout` are also +errors (520-530) are retried. ``requests.exceptions.Timeout`` are also handled. Additionally, HTTP error code 409 (Conflict) is retried if the reason From 8734e41362aadedb4899b47fd01bee0ea43baf90 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 12 Jul 2026 07:40:01 +0000 Subject: [PATCH 13/22] chore(deps): update all non-major dependencies --- .github/workflows/release.yml | 4 ++-- .github/workflows/stale.yml | 2 +- .pre-commit-config.yaml | 4 ++-- requirements-lint.txt | 6 +++--- requirements-test.txt | 6 +++--- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 5b21fec24..3d8cbd704 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -21,7 +21,7 @@ jobs: - name: Python Semantic Release id: release - uses: python-semantic-release/python-semantic-release@v10.5.3 + uses: python-semantic-release/python-semantic-release@v10.6.1 with: github_token: ${{ secrets.RELEASE_GITHUB_TOKEN }} @@ -32,7 +32,7 @@ jobs: if: steps.release.outputs.released == 'true' - name: Publish package distributions to GitHub Releases - uses: python-semantic-release/publish-action@v10.5.3 + uses: python-semantic-release/publish-action@v10.6.1 if: steps.release.outputs.released == 'true' with: github_token: ${{ secrets.RELEASE_GITHUB_TOKEN }} diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index 8b03ec138..d219ed23d 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -17,7 +17,7 @@ jobs: stale: runs-on: ubuntu-latest steps: - - uses: actions/stale@v10.3.0 + - uses: actions/stale@v10.4.0 with: operations-per-run: 500 stale-issue-label: "stale" diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 03ab29588..d9a982bc6 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -32,7 +32,7 @@ repos: - requests-toolbelt==1.0.0 files: 'gitlab/' - repo: https://github.com/pre-commit/mirrors-mypy - rev: v2.1.0 + rev: v2.2.0 hooks: - id: mypy args: [] @@ -51,6 +51,6 @@ repos: - id: rst-directive-colons - id: rst-inline-touching-normal - repo: https://github.com/maxbrunet/pre-commit-renovate - rev: 43.247.0 + rev: 43.259.2 hooks: - id: renovate-config-validator diff --git a/requirements-lint.txt b/requirements-lint.txt index dcd97d44f..906f9b366 100644 --- a/requirements-lint.txt +++ b/requirements-lint.txt @@ -4,11 +4,11 @@ black==26.5.1 commitizen==4.16.4 flake8==7.3.0 isort==8.0.1 -mypy==2.1.0 +mypy==2.2.0 pylint==4.0.6 pytest==9.1.1 -responses==0.26.1 +responses==0.26.2 respx==0.23.1 types-PyYAML==6.0.12.20260518 -types-requests==2.33.0.20260518 +types-requests==2.33.0.20260712 types-setuptools==82.0.0.20260518 diff --git a/requirements-test.txt b/requirements-test.txt index a7981a09a..74191020a 100644 --- a/requirements-test.txt +++ b/requirements-test.txt @@ -1,13 +1,13 @@ -r requirements.txt anyio==4.14.1 -build==1.5.0 -coverage==7.14.3 +build==1.5.1 +coverage==7.15.0 pytest-console-scripts==1.4.1 pytest-cov==7.1.0 pytest-github-actions-annotate-failures==0.4.2 pytest==9.1.1 PyYaml==6.0.3 -responses==0.26.1 +responses==0.26.2 respx==0.23.1 trio==0.33.0 wheel==0.47.0 From 0d2afb878ea28038b229c7a14ddfdbe393f22e18 Mon Sep 17 00:00:00 2001 From: Adrian DC Date: Tue, 10 Mar 2026 10:39:26 +0100 Subject: [PATCH 14/22] feat(users): allow updating only a user's email, username or name Signed-off-by: Adrian DC --- gitlab/v4/objects/users.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/gitlab/v4/objects/users.py b/gitlab/v4/objects/users.py index be0e36529..3978b8aba 100644 --- a/gitlab/v4/objects/users.py +++ b/gitlab/v4/objects/users.py @@ -453,8 +453,10 @@ class UserManager(CRUDMixin[User]): ) ) _update_attrs = RequiredOptional( - required=("email", "username", "name"), optional=( + "email", + "username", + "name", "password", "skype", "linkedin", @@ -475,7 +477,7 @@ class UserManager(CRUDMixin[User]): "private_profile", "color_scheme_id", "theme_id", - ), + ) ) _types = {"confirm": types.LowercaseStringAttribute, "avatar": types.ImageAttribute} From 00e380267b2408f77a23fccfaa1d64ba0bc38cac Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 13 Jul 2026 23:10:50 +0000 Subject: [PATCH 15/22] chore(deps): update all non-major dependencies --- .pre-commit-config.yaml | 4 ++-- requirements-lint.txt | 2 +- requirements-test.txt | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index d9a982bc6..289f80a00 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -32,7 +32,7 @@ repos: - requests-toolbelt==1.0.0 files: 'gitlab/' - repo: https://github.com/pre-commit/mirrors-mypy - rev: v2.2.0 + rev: v2.3.0 hooks: - id: mypy args: [] @@ -51,6 +51,6 @@ repos: - id: rst-directive-colons - id: rst-inline-touching-normal - repo: https://github.com/maxbrunet/pre-commit-renovate - rev: 43.259.2 + rev: 43.261.4 hooks: - id: renovate-config-validator diff --git a/requirements-lint.txt b/requirements-lint.txt index 906f9b366..195b8b1c6 100644 --- a/requirements-lint.txt +++ b/requirements-lint.txt @@ -4,7 +4,7 @@ black==26.5.1 commitizen==4.16.4 flake8==7.3.0 isort==8.0.1 -mypy==2.2.0 +mypy==2.3.0 pylint==4.0.6 pytest==9.1.1 responses==0.26.2 diff --git a/requirements-test.txt b/requirements-test.txt index 74191020a..856c399ad 100644 --- a/requirements-test.txt +++ b/requirements-test.txt @@ -1,7 +1,7 @@ -r requirements.txt -anyio==4.14.1 +anyio==4.14.2 build==1.5.1 -coverage==7.15.0 +coverage==7.15.1 pytest-console-scripts==1.4.1 pytest-cov==7.1.0 pytest-github-actions-annotate-failures==0.4.2 From 39dc9902af1383ea5f4b5efb8c2e42ab71f2910f Mon Sep 17 00:00:00 2001 From: Kenan Cakir Date: Fri, 24 Jul 2026 20:28:10 +0200 Subject: [PATCH 16/22] feat(hooks): support custom webhook template on project hooks --- gitlab/v4/objects/hooks.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gitlab/v4/objects/hooks.py b/gitlab/v4/objects/hooks.py index f9ce553bb..2a4de1017 100644 --- a/gitlab/v4/objects/hooks.py +++ b/gitlab/v4/objects/hooks.py @@ -60,6 +60,7 @@ class ProjectHookManager(CRUDMixin[ProjectHook]): "wiki_page_events", "enable_ssl_verification", "token", + "custom_webhook_template", ), ) _update_attrs = RequiredOptional( @@ -76,6 +77,7 @@ class ProjectHookManager(CRUDMixin[ProjectHook]): "wiki_events", "enable_ssl_verification", "token", + "custom_webhook_template", ), ) From 57fd60c1c606b98b43ca3dcde48b1fa841635e76 Mon Sep 17 00:00:00 2001 From: "Zane.Geiger" Date: Thu, 25 Jun 2026 11:54:17 -0400 Subject: [PATCH 17/22] test(api): Ensure ProjectMergeRequestDiscussionNote.resolved can be updated successfully --- tests/functional/api/test_merge_requests.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/functional/api/test_merge_requests.py b/tests/functional/api/test_merge_requests.py index 8357a817d..f7a56721b 100644 --- a/tests/functional/api/test_merge_requests.py +++ b/tests/functional/api/test_merge_requests.py @@ -69,6 +69,13 @@ def test_merge_request_discussion(project): discussion = mr.discussions.get(discussion.id) assert discussion.attributes["notes"][-1]["body"] == "updated body" + note_from_get = discussion.notes.get(note.id) + note_from_get.resolved = True + note_from_get.save() + + discussion = mr.discussions.get(discussion.id) + assert discussion.attributes["notes"][-1]["resolved"] is True + note_from_get.delete() From b411e5a20a4370a7c1b6968c85251b57785a9d03 Mon Sep 17 00:00:00 2001 From: Zane Geiger Date: Wed, 17 Dec 2025 00:25:30 -0500 Subject: [PATCH 18/22] fix(api): Allow ProjectMergeRequestDiscussionNote.resolved to be updated --- gitlab/v4/objects/notes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gitlab/v4/objects/notes.py b/gitlab/v4/objects/notes.py index 3e83d9be1..c1ad21002 100644 --- a/gitlab/v4/objects/notes.py +++ b/gitlab/v4/objects/notes.py @@ -172,7 +172,7 @@ class ProjectMergeRequestDiscussionNoteManager( "discussion_id": "id", } _create_attrs = RequiredOptional(required=("body",), optional=("created_at",)) - _update_attrs = RequiredOptional(required=("body",)) + _update_attrs = RequiredOptional(exclusive=("body", "resolved")) class ProjectSnippetNote(SaveMixin, ObjectDeleteMixin, RESTObject): From 2ef6452b9471c1a421ac8addc06eb3b5052289e0 Mon Sep 17 00:00:00 2001 From: "Zane.Geiger" Date: Thu, 16 Jul 2026 14:46:48 -0400 Subject: [PATCH 19/22] docs(discussions): Add example of resolving a single project merge request discussion note --- docs/gl_objects/discussions.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/gl_objects/discussions.rst b/docs/gl_objects/discussions.rst index f64a98b3d..24f955b9f 100644 --- a/docs/gl_objects/discussions.rst +++ b/docs/gl_objects/discussions.rst @@ -75,6 +75,12 @@ You can get and update a single note using the ``*DiscussionNote`` resources:: last_note.body = 'Updated comment' last_note.save() +Resolve / unresolve a note:: + + last_note = discussion.notes.get(note_id) + last_note.resolved = True # True to resolve, False to unresolve + last_note.save() + Create a new discussion:: discussion = resource.discussions.create({'body': 'First comment of discussion'}) From ede7fd71430fb391d5b523facea480edbc51acf8 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 27 Jul 2026 03:27:16 +0000 Subject: [PATCH 20/22] chore(deps): update actions/setup-python action to v7 --- .github/workflows/docs.yml | 4 ++-- .github/workflows/lint.yml | 2 +- .github/workflows/pre_commit.yml | 2 +- .github/workflows/test.yml | 10 +++++----- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 4baaea006..f9c6df8fb 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -24,7 +24,7 @@ jobs: steps: - uses: actions/checkout@v7.0.0 - name: Set up Python - uses: actions/setup-python@v6.3.0 + uses: actions/setup-python@v7.0.0 with: python-version: "3.14" - name: Install dependencies @@ -39,7 +39,7 @@ jobs: steps: - uses: actions/checkout@v7.0.0 - name: Set up Python - uses: actions/setup-python@v6.3.0 + uses: actions/setup-python@v7.0.0 with: python-version: "3.14" - name: Install dependencies diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 5d3c5f319..03e063bdd 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -25,7 +25,7 @@ jobs: - uses: actions/checkout@v7.0.0 with: fetch-depth: 0 - - uses: actions/setup-python@v6.3.0 + - uses: actions/setup-python@v7.0.0 with: python-version: "3.14" - run: pip install --upgrade tox diff --git a/.github/workflows/pre_commit.yml b/.github/workflows/pre_commit.yml index 7f7634870..28e908522 100644 --- a/.github/workflows/pre_commit.yml +++ b/.github/workflows/pre_commit.yml @@ -30,7 +30,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v7.0.0 - - uses: actions/setup-python@v6.3.0 + - uses: actions/setup-python@v7.0.0 with: python-version: "3.14" - name: install tox diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 68a223cb5..fdbd70d20 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -48,7 +48,7 @@ jobs: steps: - uses: actions/checkout@v7.0.0 - name: Set up Python ${{ matrix.python.version }} - uses: actions/setup-python@v6.3.0 + uses: actions/setup-python@v7.0.0 with: python-version: ${{ matrix.python.version }} - name: Install dependencies @@ -67,7 +67,7 @@ jobs: steps: - uses: actions/checkout@v7.0.0 - name: Set up Python - uses: actions/setup-python@v6.3.0 + uses: actions/setup-python@v7.0.0 with: python-version: "3.14" - name: Install dependencies @@ -89,7 +89,7 @@ jobs: steps: - uses: actions/checkout@v7.0.0 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v6.3.0 + uses: actions/setup-python@v7.0.0 with: python-version: "3.14" - name: Install dependencies @@ -112,7 +112,7 @@ jobs: name: Python wheel steps: - uses: actions/checkout@v7.0.0 - - uses: actions/setup-python@v6.3.0 + - uses: actions/setup-python@v7.0.0 with: python-version: "3.14" - name: Install dependencies @@ -131,7 +131,7 @@ jobs: steps: - uses: actions/checkout@v7.0.0 - name: Set up Python - uses: actions/setup-python@v6.3.0 + uses: actions/setup-python@v7.0.0 with: python-version: '3.14' - uses: actions/download-artifact@v8.0.1 From 0e2347cc181214bd3d825eac3cc94239e6cd2ef5 Mon Sep 17 00:00:00 2001 From: setpill <37372069+setpill@users.noreply.github.com> Date: Mon, 20 Jul 2026 12:39:59 +0200 Subject: [PATCH 21/22] feat(api): add ListMixin to remaining *DiscussionNoteManagers --- gitlab/v4/objects/notes.py | 32 ++++---------------------------- 1 file changed, 4 insertions(+), 28 deletions(-) diff --git a/gitlab/v4/objects/notes.py b/gitlab/v4/objects/notes.py index c1ad21002..f838923e7 100644 --- a/gitlab/v4/objects/notes.py +++ b/gitlab/v4/objects/notes.py @@ -1,14 +1,5 @@ from gitlab.base import RESTObject -from gitlab.mixins import ( - CreateMixin, - CRUDMixin, - DeleteMixin, - GetMixin, - ObjectDeleteMixin, - RetrieveMixin, - SaveMixin, - UpdateMixin, -) +from gitlab.mixins import CRUDMixin, ObjectDeleteMixin, RetrieveMixin, SaveMixin from gitlab.types import RequiredOptional from .award_emojis import ( # noqa: F401 @@ -58,12 +49,7 @@ class GroupEpicDiscussionNote(SaveMixin, ObjectDeleteMixin, RESTObject): pass -class GroupEpicDiscussionNoteManager( - GetMixin[GroupEpicDiscussionNote], - CreateMixin[GroupEpicDiscussionNote], - UpdateMixin[GroupEpicDiscussionNote], - DeleteMixin[GroupEpicDiscussionNote], -): +class GroupEpicDiscussionNoteManager(CRUDMixin[GroupEpicDiscussionNote]): _path = "/groups/{group_id}/epics/{epic_id}/discussions/{discussion_id}/notes" _obj_cls = GroupEpicDiscussionNote _from_parent_attrs = { @@ -90,12 +76,7 @@ class ProjectCommitDiscussionNote(SaveMixin, ObjectDeleteMixin, RESTObject): pass -class ProjectCommitDiscussionNoteManager( - GetMixin[ProjectCommitDiscussionNote], - CreateMixin[ProjectCommitDiscussionNote], - UpdateMixin[ProjectCommitDiscussionNote], - DeleteMixin[ProjectCommitDiscussionNote], -): +class ProjectCommitDiscussionNoteManager(CRUDMixin[ProjectCommitDiscussionNote]): _path = ( "/projects/{project_id}/repository/commits/{commit_id}/" "discussions/{discussion_id}/notes" @@ -191,12 +172,7 @@ class ProjectSnippetDiscussionNote(SaveMixin, ObjectDeleteMixin, RESTObject): pass -class ProjectSnippetDiscussionNoteManager( - GetMixin[ProjectSnippetDiscussionNote], - CreateMixin[ProjectSnippetDiscussionNote], - UpdateMixin[ProjectSnippetDiscussionNote], - DeleteMixin[ProjectSnippetDiscussionNote], -): +class ProjectSnippetDiscussionNoteManager(CRUDMixin[ProjectSnippetDiscussionNote]): _path = ( "/projects/{project_id}/snippets/{snippet_id}/" "discussions/{discussion_id}/notes" From f899b5e682ea092c24d6ffe2940d86302dec2a75 Mon Sep 17 00:00:00 2001 From: semantic-release Date: Tue, 28 Jul 2026 02:04:00 +0000 Subject: [PATCH 22/22] chore: release v8.5.0 --- CHANGELOG.md | 46 ++++++++++++++++++++++++++++++++++++++++++++++ gitlab/_version.py | 2 +- 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 18b012cf6..13262ec35 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,52 @@ All versions below are listed in reverse chronological order. +## v8.5.0 (2026-07-28) + +### Bug Fixes + +- Typo + ([`72134f5`](https://github.com/python-gitlab/python-gitlab/commit/72134f5369cd4568a2374f25543071245375d26e)) + +- **api**: Allow ProjectMergeRequestDiscussionNote.resolved to be updated + ([`b411e5a`](https://github.com/python-gitlab/python-gitlab/commit/b411e5a20a4370a7c1b6968c85251b57785a9d03)) + +- **client**: Retry fetching server version after an unknown result + ([`046fbac`](https://github.com/python-gitlab/python-gitlab/commit/046fbac664e033a0a5a65417bfd229e91a1fd09f)) + +### Continuous Integration + +- Run the pre-commit rst checks in the CI + ([`a9c5d17`](https://github.com/python-gitlab/python-gitlab/commit/a9c5d17d3ab57d448be6dd5eac3b7ec9eb680261)) + +### Documentation + +- Correct error with backticks + ([`e57559e`](https://github.com/python-gitlab/python-gitlab/commit/e57559e8c1bea1ba580074e83d21072d9b80d582)) + +- **discussions**: Add example of resolving a single project merge request discussion note + ([`2ef6452`](https://github.com/python-gitlab/python-gitlab/commit/2ef6452b9471c1a421ac8addc06eb3b5052289e0)) + +### Features + +- **api**: Add ListMixin to remaining *DiscussionNoteManagers + ([`0e2347c`](https://github.com/python-gitlab/python-gitlab/commit/0e2347cc181214bd3d825eac3cc94239e6cd2ef5)) + +- **client**: Additionally handle retries for request timeouts + ([`4e32439`](https://github.com/python-gitlab/python-gitlab/commit/4e32439deaa9516a48becf9a7fc9cdb7723207c6)) + +- **hooks**: Support custom webhook template on project hooks + ([`39dc990`](https://github.com/python-gitlab/python-gitlab/commit/39dc9902af1383ea5f4b5efb8c2e42ab71f2910f)) + +- **users**: Allow updating only a user's email, username or name + ([`0d2afb8`](https://github.com/python-gitlab/python-gitlab/commit/0d2afb878ea28038b229c7a14ddfdbe393f22e18)) + +### Testing + +- **api**: Ensure ProjectMergeRequestDiscussionNote.resolved can be updated successfully + ([`57fd60c`](https://github.com/python-gitlab/python-gitlab/commit/57fd60c1c606b98b43ca3dcde48b1fa841635e76)) + + ## v8.4.0 (2026-05-28) ### Features diff --git a/gitlab/_version.py b/gitlab/_version.py index 57b49906f..e634f388a 100644 --- a/gitlab/_version.py +++ b/gitlab/_version.py @@ -3,4 +3,4 @@ __email__ = "gauvainpocentek@gmail.com" __license__ = "LGPL3" __title__ = "python-gitlab" -__version__ = "8.4.0" +__version__ = "8.5.0"