Compare commits

...
12 Commits
Author SHA1 Message Date
brian 4f6f33f36e Merge pull request 'Drop types-redis in favor of redis inline types' (#51) from cursor/drop-types-redis into main
Release on merge to main / release (push) Successful in 5s
Test Python Package / unit-tests (push) Successful in 12s
Code Quality Pipeline / code-quality (push) Successful in 23s
Build CI Image / build-and-push (push) Successful in 1m3s
Test Python Package / integration-tests (push) Successful in 57s
Test Python Package / coverage-report (push) Successful in 10s
Reviewed-on: https://gitea.lille-vemmelund.dk/LilleVemmelund/python-repositories/pulls/51
2026-07-10 19:28:20 +02:00
Brian Bjarke JensenandCursor 10d43ce198 Drop types-redis in favor of redis inline types.
PR Title Check / check-title (pull_request) Successful in 7s
Test Python Package / unit-tests (pull_request) Successful in 12s
Test Python Package / integration-tests (pull_request) Successful in 25s
Test Python Package / coverage-report (pull_request) Successful in 11s
Code Quality Pipeline / code-quality (pull_request) Successful in 47s
The outdated redis 4.6 stubs conflicted with redis 6+ py.typed annotations used at runtime.

Co-authored-by: Cursor <[email protected]>
2026-07-10 19:24:17 +02:00
CI Bot 4f7b67203a chore: release v2.0.4 [skip ci] 2026-07-10 12:47:15 +00:00
brian a27e9e5763 Merge pull request '[fix] Include optional dependencies in security audit' (#50) from cursor/security-audit-all-extras into main
Test Python Package / unit-tests (push) Successful in 10s
Release on merge to main / release (push) Successful in 14s
Code Quality Pipeline / code-quality (push) Successful in 21s
Test Python Package / integration-tests (push) Successful in 20s
Test Python Package / coverage-report (push) Successful in 8s
Reviewed-on: https://gitea.lille-vemmelund.dk/LilleVemmelund/python-repositories/pulls/50
2026-07-10 14:47:01 +02:00
Brian Bjarke JensenandCursor fd0045d3e0 Include optional dependencies in security audit.
PR Title Check / check-title (pull_request) Successful in 5s
Test Python Package / unit-tests (pull_request) Successful in 12s
Code Quality Pipeline / code-quality (pull_request) Successful in 21s
Test Python Package / integration-tests (pull_request) Successful in 19s
Test Python Package / coverage-report (pull_request) Successful in 8s
Sync all extras before safety check so redis and minio vulnerabilities are scanned.

Co-authored-by: Cursor <[email protected]>
2026-07-10 14:44:35 +02:00
brian 515f4bbeae Merge pull request 'revert 707f11f578f007c7152582ea524b66dacea50111' (#49) from brian-patch-1 into main
Release on merge to main / release (push) Successful in 5s
Test Python Package / unit-tests (push) Successful in 10s
Code Quality Pipeline / code-quality (push) Successful in 20s
Test Python Package / integration-tests (push) Successful in 19s
Test Python Package / coverage-report (push) Successful in 7s
Build CI Image / build-and-push (push) Successful in 1m32s
Reviewed-on: https://gitea.lille-vemmelund.dk/LilleVemmelund/python-repositories/pulls/49
2026-07-10 14:42:24 +02:00
brian ef31fb4b4e revert 707f11f578
revert chore: release v2.0.4 [skip ci]
2026-07-10 14:42:09 +02:00
CI Bot 707f11f578 chore: release v2.0.4 [skip ci] 2026-07-10 12:36:58 +00:00
brian b1d34f8f0f Merge pull request '[patch] Unify dev tooling via uv so pre-commit, CI, and the update bot stay aligned' (#48) from chore/align-dev-tooling-via-uv into main
Test Python Package / unit-tests (push) Successful in 13s
Code Quality Pipeline / code-quality (push) Successful in 21s
Test Python Package / integration-tests (push) Successful in 20s
Test Python Package / coverage-report (push) Successful in 8s
Build CI Image / build-and-push (push) Successful in 58s
Release on merge to main / release (push) Failing after 9s
Reviewed-on: https://gitea.lille-vemmelund.dk/LilleVemmelund/python-repositories/pulls/48
2026-07-10 14:36:44 +02:00
Brian Bjarke JensenandCursor 565879dd52 Unify dev tooling via uv so pre-commit, CI, and the update bot stay aligned.
Test Python Package / unit-tests (pull_request) Successful in 12s
Code Quality Pipeline / code-quality (pull_request) Successful in 19s
PR Title Check / check-title (pull_request) Successful in 31s
Test Python Package / integration-tests (pull_request) Successful in 23s
Test Python Package / coverage-report (pull_request) Successful in 10s
Route Python hooks through uv run with versions pinned in uv.lock, add explicit
Ruff settings, and extend the dependency bot to run pre-commit autoupdate.

Co-authored-by: Cursor <[email protected]>
2026-07-10 14:29:22 +02:00
brian 0d0f430f6f Merge pull request 'Fix automated package publishing in release workflow' (#47) from fix/release-workflow-publish into main
Release on merge to main / release (push) Successful in 5s
Test Python Package / unit-tests (push) Successful in 12s
Code Quality Pipeline / code-quality (push) Successful in 23s
Test Python Package / integration-tests (push) Successful in 19s
Test Python Package / coverage-report (push) Successful in 8s
Reviewed-on: https://gitea.lille-vemmelund.dk/LilleVemmelund/python-repositories/pulls/47
2026-07-10 14:17:10 +02:00
Brian Bjarke JensenandCursor 5ac40b1ba5 Publish packages from the release workflow so automated releases reach the registry.
Release commits use [skip ci], which prevents publish.yml from running on tag push.

Co-authored-by: Cursor <[email protected]>
2026-07-10 14:15:04 +02:00
24 changed files with 119 additions and 97 deletions
@@ -14,12 +14,38 @@ jobs:
with:
token: ${{ secrets.CI_RUNNER_TOKEN }}
- name: Sync dependencies
env:
UV_LINK_MODE: copy
UV_INDEX_GITEA_USERNAME: ci-bot
UV_INDEX_GITEA_PASSWORD: ${{ secrets.CI_RUNNER_TOKEN }}
run: uv sync --all-extras
- name: Upgrade dependencies
env:
UV_INDEX_GITEA_USERNAME: ci-bot
UV_INDEX_GITEA_PASSWORD: ${{ secrets.CI_RUNNER_TOKEN }}
run: uv lock --upgrade
- name: Update pre-commit hook revs
env:
UV_INDEX_GITEA_USERNAME: ci-bot
UV_INDEX_GITEA_PASSWORD: ${{ secrets.CI_RUNNER_TOKEN }}
run: uv run pre-commit autoupdate
- name: Sync upgraded dependencies
env:
UV_LINK_MODE: copy
UV_INDEX_GITEA_USERNAME: ci-bot
UV_INDEX_GITEA_PASSWORD: ${{ secrets.CI_RUNNER_TOKEN }}
run: uv sync --all-extras
- name: Smoke check
run: |
uv run ruff check .
uv run ruff format --check .
uv run mypy .
- name: Commit and push changes
env:
API_URL: ${{ vars.API_URL }}
+20
View File
@@ -74,3 +74,23 @@ jobs:
-H "Authorization: token ${CI_RUNNER_TOKEN}" \
-H "Content-Type: application/json" \
-d "$PAYLOAD"
# Publish here instead of relying on publish.yml tag trigger: release commits use
# [skip ci], which suppresses tag-push workflows, and Gitea does not emit release
# events for releases created by the CI bot account.
- name: Build package
if: steps.meta.outputs.bump != 'skip'
env:
UV_LINK_MODE: copy
UV_INDEX_GITEA_USERNAME: ci-bot
UV_INDEX_GITEA_PASSWORD: ${{ secrets.CI_RUNNER_TOKEN }}
run: |
uv sync --no-dev --frozen
uv build
- name: Publish to Gitea Package Registry
if: steps.meta.outputs.bump != 'skip'
env:
UV_PUBLISH_TOKEN: ${{ secrets.CI_RUNNER_TOKEN }}
UV_PUBLISH_URL: ${{ vars.REPOSITORY_URL }}
run: uv publish
+1 -1
View File
@@ -17,7 +17,7 @@ jobs:
UV_LINK_MODE: copy
UV_INDEX_GITEA_USERNAME: ci-bot
UV_INDEX_GITEA_PASSWORD: ${{ secrets.CI_RUNNER_TOKEN }}
run: uv sync --frozen
run: uv sync --all-extras --frozen
- name: Run safety check
run: uv run safety check
+19 -17
View File
@@ -11,28 +11,30 @@ repos:
- id: name-tests-test
- id: check-merge-conflict
# Python linting and formatting with Ruff
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.12.8
# Python tooling via uv (versions pinned in uv.lock)
- repo: local
hooks:
- id: ruff-check
args: [--fix]
name: ruff check
entry: uv run ruff check --fix
language: system
types: [python]
- id: ruff-format
# Static type checking with mypy
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.8.0
hooks:
name: ruff format
entry: uv run ruff format
language: system
types: [python]
- id: mypy
additional_dependencies:
- types-redis
# Python syntax modernization with pyupgrade
- repo: https://github.com/asottile/pyupgrade
rev: v3.20.0
hooks:
name: mypy
entry: uv run mypy .
language: system
types: [python]
pass_filenames: false
- id: pyupgrade
args: ["--py312-plus"]
name: pyupgrade
entry: uv run pyupgrade --py312-plus
language: system
types: [python]
# Formatting for Markdown, JSON, and YAML with Prettier
- repo: https://github.com/pre-commit/mirrors-prettier
+2 -2
View File
@@ -198,8 +198,8 @@ Releases are automated when a pull request is merged to `main`. CI reads the **m
1. Open a PR targeting `main` (see [`.gitea/PULL_REQUEST_TEMPLATE.md`](.gitea/PULL_REQUEST_TEMPLATE.md)).
2. If the PR changes files under `python_repositories/`, the title **must** start with a version bump prefix (enforced by CI).
3. On merge, [`release.yml`](.gitea/workflows/release.yml) bumps [`pyproject.toml`](pyproject.toml) and syncs [`uv.lock`](uv.lock), commits, tags `vX.Y.Z`, creates a Gitea release with auto-generated notes, and pushes the tag.
4. [`publish.yml`](.gitea/workflows/publish.yml) builds and publishes the package to the Gitea Package Registry.
3. On merge, [`release.yml`](.gitea/workflows/release.yml) bumps [`pyproject.toml`](pyproject.toml) and syncs [`uv.lock`](uv.lock), commits, tags `vX.Y.Z`, creates a Gitea release with auto-generated notes, pushes the tag, and publishes the package to the Gitea Package Registry.
4. [`publish.yml`](.gitea/workflows/publish.yml) handles manual `v*.*.*` tag pushes only (automated releases publish from `release.yml` because release commits use `[skip ci]`, which suppresses tag-push workflows).
Docs-, CI-, and test-only PRs do not need a prefix and will not trigger a release.
+17 -6
View File
@@ -1,6 +1,6 @@
[project]
name = "python-repositories"
version = "2.0.3"
version = "2.0.4"
description = "Various python repository interfaces exposed as a python package."
authors = [
{ name = "Brian Bjarke Jensen", email = "[email protected]" }
@@ -60,6 +60,18 @@ name = "gitea"
url = "https://gitea.lille-vemmelund.dk/api/packages/brian/pypi/simple/"
explicit = true
[tool.ruff]
line-length = 88
target-version = "py312"
[tool.ruff.lint]
extend-select = ["I"]
[tool.ruff.lint.isort]
known-first-party = ["python_repositories", "tests"]
combine-as-imports = true
force-sort-within-sections = true
[tool.mypy]
python_version = "3.12"
warn_return_any = true # nudge to use stricter types
@@ -87,13 +99,12 @@ ignore_missing_imports = true
[dependency-groups]
dev = [
"mypy>=1.17.1",
"pre-commit>=4.3.0",
"mypy>=2.1.0",
"pre-commit>=4.6.0",
"pytest>=8.4.1",
"pytest-cov>=7.0.0",
"pyupgrade>=3.20.0",
"ruff>=0.12.11",
"pyupgrade>=3.21.2",
"ruff>=0.15.20",
"safety>=3.6.0",
"testcontainers>=4.13.0",
"types-redis>=4.6.0.20241004",
]
@@ -2,8 +2,8 @@
from __future__ import annotations
import time
from abc import abstractmethod
import time
from typing import Self
import structlog
@@ -1,6 +1,7 @@
"""Definition of MinioAdapter class."""
from __future__ import annotations
from io import BytesIO
from python_repositories.adapters.connection_aware_adapter import (
@@ -1,6 +1,7 @@
"""Definition of RedisAdapter class."""
from __future__ import annotations
from collections.abc import Iterator
from typing import Any, cast
+1 -1
View File
@@ -2,8 +2,8 @@
from __future__ import annotations
import os
from dataclasses import dataclass
import os
from python_utils import check_env
+1 -1
View File
@@ -2,8 +2,8 @@
from __future__ import annotations
import os
from dataclasses import dataclass
import os
from python_utils import check_env
@@ -1,7 +1,7 @@
"""Definition of JsonRepositoryInterface abstract base class."""
from collections.abc import Iterator
from abc import ABC, abstractmethod
from collections.abc import Iterator
from typing import Any
+9 -3
View File
@@ -11,15 +11,16 @@ set -euo pipefail
BRANCH="${BRANCH:-renovate/auto-deps-update}"
BASE_BRANCH="${BASE_BRANCH:-main}"
LOCKFILE="${LOCKFILE:-uv.lock}"
PRE_COMMIT_CONFIG="${PRE_COMMIT_CONFIG:-.pre-commit-config.yaml}"
if git diff --quiet "$LOCKFILE"; then
if git diff --quiet "$LOCKFILE" && git diff --quiet "$PRE_COMMIT_CONFIG"; then
echo "No dependency updates available."
exit 0
fi
git config user.name "CI Bot"
git config user.email "[email protected]"
git add "$LOCKFILE"
git add "$LOCKFILE" "$PRE_COMMIT_CONFIG"
git commit -m "chore(deps): update dependencies [automated]"
git remote set-url origin "https://x-access-token:${CI_RUNNER_TOKEN}@${GITHUB_SERVER_URL#https://}/${GITHUB_REPOSITORY}.git"
@@ -48,7 +49,12 @@ print(
json.dumps(
{
"title": "chore(deps): update dependencies",
"body": "This PR was created automatically to update dependencies.",
"body": (
"This PR was created automatically to update dependencies.\n\n"
"- `uv.lock`: upgraded Python dependencies\n"
"- `.pre-commit-config.yaml`: updated remote hook revs via "
"`pre-commit autoupdate`"
),
"head": os.environ["BRANCH"],
"base": os.environ["BASE_BRANCH"],
}
+2 -2
View File
@@ -1,13 +1,13 @@
"""Integration tests configuration."""
import logging
from collections.abc import Generator
import logging
from typing import Any, cast
from minio import Minio
import pytest
import redis
import structlog
from minio import Minio
from testcontainers.core.container import DockerContainer
from testcontainers.core.waiting_utils import WaitStrategy, WaitStrategyTarget
from testcontainers.minio import MinioContainer
+1 -1
View File
@@ -5,8 +5,8 @@ from io import BytesIO
import os
import random
import pytest
from minio import Minio
import pytest
from python_repositories.examples.artifact_object_repository import (
ArtifactObjectRepository,
+2 -2
View File
@@ -2,13 +2,13 @@
from collections.abc import Generator
from dataclasses import replace
from io import BytesIO
import logging
import random
from io import BytesIO
from unittest.mock import MagicMock
import pytest
from minio import Minio, S3Error
import pytest
from urllib3.response import BaseHTTPResponse
from python_repositories.adapters.minio_adapter import MinioAdapter
+2 -2
View File
@@ -3,12 +3,12 @@
from __future__ import annotations
import builtins
from collections.abc import Callable, Mapping, Sequence
import importlib
import os
from pathlib import Path
import subprocess
import sys
from collections.abc import Callable, Mapping, Sequence
from pathlib import Path
from types import ModuleType
from unittest.mock import patch
+1 -1
View File
@@ -4,9 +4,9 @@ from __future__ import annotations
from unittest.mock import MagicMock
from minio import Minio
import pytest
import redis
from minio import Minio
from python_repositories.adapters.minio_adapter import MinioAdapter
from python_repositories.adapters.redis_adapter import RedisAdapter
@@ -1,6 +1,7 @@
"""Unit tests for ConnectionAwareInterface."""
import pytest
from python_repositories.interfaces.connection_aware_interface import (
ConnectionAwareInterface,
)
@@ -3,6 +3,7 @@
from __future__ import annotations
import pytest
from python_repositories.interfaces.context_aware_interface import ContextAwareInterface
@@ -3,6 +3,7 @@
from typing import Any
import pytest
from python_repositories.interfaces.json_repository_interface import (
JsonRepositoryInterface,
)
+1 -1
View File
@@ -5,8 +5,8 @@ from __future__ import annotations
from dataclasses import replace
from unittest.mock import MagicMock
import pytest
from minio import Minio, S3Error
import pytest
from urllib3.response import BaseHTTPResponse
from python_repositories.adapters.minio_adapter import MinioAdapter
@@ -3,6 +3,7 @@
from io import BytesIO
import pytest
from python_repositories.interfaces.object_repository_interface import (
ObjectRepositoryInterface,
)
Generated
+6 -55
View File
@@ -1,5 +1,5 @@
version = 1
revision = 2
revision = 3
requires-python = ">=3.12"
resolution-markers = [
"python_full_version >= '3.15'",
@@ -1056,7 +1056,7 @@ wheels = [
[[package]]
name = "python-repositories"
version = "2.0.3"
version = "2.0.4"
source = { editable = "." }
dependencies = [
{ name = "python-dotenv" },
@@ -1082,7 +1082,6 @@ dev = [
{ name = "ruff" },
{ name = "safety" },
{ name = "testcontainers" },
{ name = "types-redis" },
]
[package.metadata]
@@ -1097,15 +1096,14 @@ provides-extras = ["redis", "minio"]
[package.metadata.requires-dev]
dev = [
{ name = "mypy", specifier = ">=1.17.1" },
{ name = "pre-commit", specifier = ">=4.3.0" },
{ name = "mypy", specifier = ">=2.1.0" },
{ name = "pre-commit", specifier = ">=4.6.0" },
{ name = "pytest", specifier = ">=8.4.1" },
{ name = "pytest-cov", specifier = ">=7.0.0" },
{ name = "pyupgrade", specifier = ">=3.20.0" },
{ name = "ruff", specifier = ">=0.12.11" },
{ name = "pyupgrade", specifier = ">=3.21.2" },
{ name = "ruff", specifier = ">=0.15.20" },
{ name = "safety", specifier = ">=3.6.0" },
{ name = "testcontainers", specifier = ">=4.13.0" },
{ name = "types-redis", specifier = ">=4.6.0.20241004" },
]
[[package]]
@@ -1495,53 +1493,6 @@ wheels = [
{ url = "https://proxpi.lille-vemmelund.dk/index/typer/typer-0.25.1-py3-none-any.whl", hash = "sha256:75caa44ed46a03fb2dab8808753ffacdbfea88495e74c85a28c5eefcf5f39c89" },
]
[[package]]
name = "types-cffi"
version = "2.0.0.20260518"
source = { registry = "https://proxpi.lille-vemmelund.dk/index/" }
dependencies = [
{ name = "types-setuptools" },
]
sdist = { url = "https://proxpi.lille-vemmelund.dk/index/types-cffi/types_cffi-2.0.0.20260518.tar.gz", hash = "sha256:f9707e66c13454789a58f8843d1ded4a66f1e9c8b10bd24d5eb5e0f25c0c5472" }
wheels = [
{ url = "https://proxpi.lille-vemmelund.dk/index/types-cffi/types_cffi-2.0.0.20260518-py3-none-any.whl", hash = "sha256:5b68a215a95d0eac4203b58e766ff7fe40c2e091b1fa1a9e54111f04cc560084" },
]
[[package]]
name = "types-pyopenssl"
version = "24.1.0.20240722"
source = { registry = "https://proxpi.lille-vemmelund.dk/index/" }
dependencies = [
{ name = "cryptography" },
{ name = "types-cffi" },
]
sdist = { url = "https://proxpi.lille-vemmelund.dk/index/types-pyopenssl/types-pyOpenSSL-24.1.0.20240722.tar.gz", hash = "sha256:47913b4678a01d879f503a12044468221ed8576263c1540dcb0484ca21b08c39" }
wheels = [
{ url = "https://proxpi.lille-vemmelund.dk/index/types-pyopenssl/types_pyOpenSSL-24.1.0.20240722-py3-none-any.whl", hash = "sha256:6a7a5d2ec042537934cfb4c9d4deb0e16c4c6250b09358df1f083682fe6fda54" },
]
[[package]]
name = "types-redis"
version = "4.6.0.20241004"
source = { registry = "https://proxpi.lille-vemmelund.dk/index/" }
dependencies = [
{ name = "cryptography" },
{ name = "types-pyopenssl" },
]
sdist = { url = "https://proxpi.lille-vemmelund.dk/index/types-redis/types-redis-4.6.0.20241004.tar.gz", hash = "sha256:5f17d2b3f9091ab75384153bfa276619ffa1cf6a38da60e10d5e6749cc5b902e" }
wheels = [
{ url = "https://proxpi.lille-vemmelund.dk/index/types-redis/types_redis-4.6.0.20241004-py3-none-any.whl", hash = "sha256:ef5da68cb827e5f606c8f9c0b49eeee4c2669d6d97122f301d3a55dc6a63f6ed" },
]
[[package]]
name = "types-setuptools"
version = "82.0.0.20260518"
source = { registry = "https://proxpi.lille-vemmelund.dk/index/" }
sdist = { url = "https://proxpi.lille-vemmelund.dk/index/types-setuptools/types_setuptools-82.0.0.20260518.tar.gz", hash = "sha256:3b743cfe63d0981ea4c15b90710fc1ed41e3464a537d51e705be514e891c1d07" }
wheels = [
{ url = "https://proxpi.lille-vemmelund.dk/index/types-setuptools/types_setuptools-82.0.0.20260518-py3-none-any.whl", hash = "sha256:31c04a62b57a653a5021caf191be0f10f70df890f813b51f02bab3969d300f20" },
]
[[package]]
name = "typing-extensions"
version = "4.16.0"