gitops 1.6.3__tar.gz → 1.7.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. {gitops-1.6.3 → gitops-1.7.1}/.github/workflows/release-please.yaml +1 -1
  2. {gitops-1.6.3 → gitops-1.7.1}/.github/workflows/test.yml +2 -0
  3. {gitops-1.6.3 → gitops-1.7.1}/.release-please-manifest.json +1 -1
  4. {gitops-1.6.3 → gitops-1.7.1}/CHANGELOG.md +22 -0
  5. {gitops-1.6.3 → gitops-1.7.1}/Dockerfile +6 -0
  6. {gitops-1.6.3 → gitops-1.7.1}/PKG-INFO +13 -3
  7. {gitops-1.6.3 → gitops-1.7.1}/README.md +11 -1
  8. {gitops-1.6.3 → gitops-1.7.1}/gitops/__init__.py +1 -1
  9. {gitops-1.6.3 → gitops-1.7.1}/gitops/core.py +8 -2
  10. gitops-1.7.1/gitops_server/version.py +1 -0
  11. {gitops-1.6.3 → gitops-1.7.1}/pyproject.toml +5 -5
  12. gitops-1.7.1/renovate.json +6 -0
  13. {gitops-1.6.3 → gitops-1.7.1}/tests/test_core.py +109 -1
  14. {gitops-1.6.3 → gitops-1.7.1}/uv.lock +20 -9
  15. gitops-1.6.3/gitops_server/version.py +0 -1
  16. {gitops-1.6.3 → gitops-1.7.1}/.dockerignore +0 -0
  17. {gitops-1.6.3 → gitops-1.7.1}/.github/CODEOWNERS +0 -0
  18. {gitops-1.6.3 → gitops-1.7.1}/.gitignore +0 -0
  19. {gitops-1.6.3 → gitops-1.7.1}/.mise.toml +0 -0
  20. {gitops-1.6.3 → gitops-1.7.1}/.pre-commit-config.yaml +0 -0
  21. {gitops-1.6.3 → gitops-1.7.1}/CLAUDE.md +0 -0
  22. {gitops-1.6.3 → gitops-1.7.1}/LICENSE +0 -0
  23. {gitops-1.6.3 → gitops-1.7.1}/charts/gitops/.helmignore +0 -0
  24. {gitops-1.6.3 → gitops-1.7.1}/charts/gitops/CHANGELOG.md +0 -0
  25. {gitops-1.6.3 → gitops-1.7.1}/charts/gitops/Chart.yaml +0 -0
  26. {gitops-1.6.3 → gitops-1.7.1}/charts/gitops/README.md +0 -0
  27. {gitops-1.6.3 → gitops-1.7.1}/charts/gitops/templates/_helpers.tpl +0 -0
  28. {gitops-1.6.3 → gitops-1.7.1}/charts/gitops/templates/certificate.yml +0 -0
  29. {gitops-1.6.3 → gitops-1.7.1}/charts/gitops/templates/deployment.yml +0 -0
  30. {gitops-1.6.3 → gitops-1.7.1}/charts/gitops/templates/environment.yml +0 -0
  31. {gitops-1.6.3 → gitops-1.7.1}/charts/gitops/templates/ingress.yml +0 -0
  32. {gitops-1.6.3 → gitops-1.7.1}/charts/gitops/templates/issuer.yml +0 -0
  33. {gitops-1.6.3 → gitops-1.7.1}/charts/gitops/templates/pdb.yml +0 -0
  34. {gitops-1.6.3 → gitops-1.7.1}/charts/gitops/templates/secrets.yml +0 -0
  35. {gitops-1.6.3 → gitops-1.7.1}/charts/gitops/templates/service.yml +0 -0
  36. {gitops-1.6.3 → gitops-1.7.1}/charts/gitops/templates/serviceaccount.yaml +0 -0
  37. {gitops-1.6.3 → gitops-1.7.1}/charts/gitops/values.yaml +0 -0
  38. {gitops-1.6.3 → gitops-1.7.1}/docker-compose.yml +0 -0
  39. {gitops-1.6.3 → gitops-1.7.1}/docs/plans/2026-03-13-kms-encryption-design.md +0 -0
  40. {gitops-1.6.3 → gitops-1.7.1}/gitops/common/__init__.py +0 -0
  41. {gitops-1.6.3 → gitops-1.7.1}/gitops/common/app.py +0 -0
  42. {gitops-1.6.3 → gitops-1.7.1}/gitops/common/utils.py +0 -0
  43. {gitops-1.6.3 → gitops-1.7.1}/gitops/main.py +0 -0
  44. {gitops-1.6.3 → gitops-1.7.1}/gitops/py.typed +0 -0
  45. {gitops-1.6.3 → gitops-1.7.1}/gitops/settings.py +0 -0
  46. {gitops-1.6.3 → gitops-1.7.1}/gitops/shorthands.py +0 -0
  47. {gitops-1.6.3 → gitops-1.7.1}/gitops/utils/__init__.py +0 -0
  48. {gitops-1.6.3 → gitops-1.7.1}/gitops/utils/apps.py +0 -0
  49. {gitops-1.6.3 → gitops-1.7.1}/gitops/utils/async_runner.py +0 -0
  50. {gitops-1.6.3 → gitops-1.7.1}/gitops/utils/cli.py +0 -0
  51. {gitops-1.6.3 → gitops-1.7.1}/gitops/utils/exceptions.py +0 -0
  52. {gitops-1.6.3 → gitops-1.7.1}/gitops/utils/images.py +0 -0
  53. {gitops-1.6.3 → gitops-1.7.1}/gitops/utils/kube.py +0 -0
  54. {gitops-1.6.3 → gitops-1.7.1}/gitops/utils/tags.py +0 -0
  55. {gitops-1.6.3 → gitops-1.7.1}/gitops/utils/yaml.py +0 -0
  56. {gitops-1.6.3 → gitops-1.7.1}/gitops_server/CHANGELOG.md +0 -0
  57. {gitops-1.6.3 → gitops-1.7.1}/gitops_server/README.md +0 -0
  58. {gitops-1.6.3 → gitops-1.7.1}/gitops_server/__init__.py +0 -0
  59. {gitops-1.6.3 → gitops-1.7.1}/gitops_server/app.py +0 -0
  60. {gitops-1.6.3 → gitops-1.7.1}/gitops_server/main.py +0 -0
  61. {gitops-1.6.3 → gitops-1.7.1}/gitops_server/settings.py +0 -0
  62. {gitops-1.6.3 → gitops-1.7.1}/gitops_server/types.py +0 -0
  63. {gitops-1.6.3 → gitops-1.7.1}/gitops_server/utils/__init__.py +0 -0
  64. {gitops-1.6.3 → gitops-1.7.1}/gitops_server/utils/git.py +0 -0
  65. {gitops-1.6.3 → gitops-1.7.1}/gitops_server/utils/github.py +0 -0
  66. {gitops-1.6.3 → gitops-1.7.1}/gitops_server/utils/slack.py +0 -0
  67. {gitops-1.6.3 → gitops-1.7.1}/gitops_server/workers/__init__.py +0 -0
  68. {gitops-1.6.3 → gitops-1.7.1}/gitops_server/workers/deployer/__init__.py +0 -0
  69. {gitops-1.6.3 → gitops-1.7.1}/gitops_server/workers/deployer/deploy.py +0 -0
  70. {gitops-1.6.3 → gitops-1.7.1}/gitops_server/workers/deployer/hooks.py +0 -0
  71. {gitops-1.6.3 → gitops-1.7.1}/gitops_server/workers/deployer/semaphore_manager.py +0 -0
  72. {gitops-1.6.3 → gitops-1.7.1}/gitops_server/workers/deployer/worker.py +0 -0
  73. {gitops-1.6.3 → gitops-1.7.1}/release-please-config.json +0 -0
  74. {gitops-1.6.3 → gitops-1.7.1}/release.py +0 -0
  75. {gitops-1.6.3 → gitops-1.7.1}/ruff.toml +0 -0
  76. {gitops-1.6.3 → gitops-1.7.1}/secrets.example.env +0 -0
  77. {gitops-1.6.3 → gitops-1.7.1}/setup.cfg +0 -0
  78. {gitops-1.6.3 → gitops-1.7.1}/tests/__init__.py +0 -0
  79. {gitops-1.6.3 → gitops-1.7.1}/tests/conftest.py +0 -0
  80. {gitops-1.6.3 → gitops-1.7.1}/tests/sample_data.py +0 -0
  81. {gitops-1.6.3 → gitops-1.7.1}/tests/test_app.py +0 -0
  82. {gitops-1.6.3 → gitops-1.7.1}/tests/test_deploy.py +0 -0
  83. {gitops-1.6.3 → gitops-1.7.1}/tests/test_deploy_concurrent.py +0 -0
  84. {gitops-1.6.3 → gitops-1.7.1}/tests/test_git.py +0 -0
  85. {gitops-1.6.3 → gitops-1.7.1}/tests/test_gitops_server.py +0 -0
  86. {gitops-1.6.3 → gitops-1.7.1}/tests/test_utils.py +0 -0
  87. {gitops-1.6.3 → gitops-1.7.1}/tests/utils.py +0 -0
  88. {gitops-1.6.3 → gitops-1.7.1}/tests/webhook_sample_data.py +0 -0
@@ -59,7 +59,7 @@ jobs:
59
59
  shell: bash
60
60
 
61
61
  - name: Publish Pypi Package
62
- uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # ratchet:pypa/gh-action-pypi-publish@release/v1
62
+ uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # ratchet:pypa/gh-action-pypi-publish@release/v1
63
63
 
64
64
  publish_docker_image:
65
65
  name: Build and Push Docker Image
@@ -88,6 +88,8 @@ jobs:
88
88
  provenance: false
89
89
  platforms: linux/amd64,linux/arm64
90
90
  push: true
91
+ build-args: |
92
+ BUILD_KIND=test
91
93
  tags: |
92
94
  610829907584.dkr.ecr.ap-southeast-2.amazonaws.com/gitops:test-${{ env.GIT_SHORT_HASH }}
93
95
 
@@ -1,5 +1,5 @@
1
1
  {
2
- ".": "1.6.3",
2
+ ".": "1.7.1",
3
3
  "gitops_server": "0.15.1",
4
4
  "charts/gitops": "1.2.2"
5
5
  }
@@ -1,5 +1,27 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.7.1](https://github.com/uptick/gitops/compare/gitops-v1.7.0...gitops-v1.7.1) (2026-08-17)
4
+
5
+
6
+ ### Documentation
7
+
8
+ * install the CLI from GitHub over SSH ([754e387](https://github.com/uptick/gitops/commit/754e3871ebafa7baf8d76990dee9dfc8d45aa892))
9
+ * install the CLI from GitHub over SSH ([c76d41c](https://github.com/uptick/gitops/commit/c76d41cc3a274febded30bcc9661f8c6cefabd4a))
10
+
11
+ ## [1.7.0](https://github.com/uptick/gitops/compare/gitops-v1.6.3...gitops-v1.7.0) (2026-08-17)
12
+
13
+
14
+ ### Features
15
+
16
+ * **cli:** add skip-deploy to setenv and unsetenv ([285ac87](https://github.com/uptick/gitops/commit/285ac872f94eba77636262f30998bca86b1c0d90))
17
+ * **cli:** add skip-deploy to setenv and unsetenv ([de4ecd9](https://github.com/uptick/gitops/commit/de4ecd90dcbe8dea4e0e5ea6b7f93a05e36eae4b))
18
+
19
+
20
+ ### Bug Fixes
21
+
22
+ * **build:** keep test and release images on distinct digests ([48c1c75](https://github.com/uptick/gitops/commit/48c1c750da2cc7f5fc86b8c52beee9abf07805db))
23
+ * **build:** keep test and release images on distinct digests ([2c8bc3c](https://github.com/uptick/gitops/commit/2c8bc3cf1eeadf26a1127762c89bff60aa121db1))
24
+
3
25
  ## [1.6.3](https://github.com/uptick/gitops/compare/gitops-v1.6.2...gitops-v1.6.3) (2026-08-05)
4
26
 
5
27
 
@@ -66,4 +66,10 @@ ENV GIT_CRYPT_KEY_FILE=/app/cluster.key
66
66
  ENV PYTHONPATH="$PYTHONPATH:/app"
67
67
  ENV ACCESS_LOG=""
68
68
 
69
+ # Keeps test and release builds on distinct digests. They build from the same
70
+ # source and cache, so otherwise they dedupe into one manifest and a retention
71
+ # rule targeting test tags expires the release image too.
72
+ ARG BUILD_KIND=release
73
+ LABEL build-kind=$BUILD_KIND
74
+
69
75
  CMD ["uvicorn", "--host", "0.0.0.0", "--port", "8000", "gitops_server.main:app"]
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.4
1
+ Metadata-Version: 2.5
2
2
  Name: gitops
3
- Version: 1.6.3
3
+ Version: 1.7.1
4
4
  Summary: Manage multiple apps across one or more k8s clusters.
5
5
  Author-email: Jarek Głowacki <jarekwg@gmail.com>
6
6
  License-File: LICENSE
@@ -69,7 +69,17 @@ This is a git repository that you set up, where you list out all of your applica
69
69
 
70
70
  ## Gitops CLI Installation
71
71
 
72
- 1. Install the CLI tool with: `uv tool install gitops` and upgrade it with `uv tool upgrade gitops`.
72
+ 1. Install the CLI tool from GitHub over SSH, which needs an SSH key registered
73
+ with GitHub. Add `--verbose` to see what it is doing:
74
+
75
+ ```bash
76
+ uv tool install git+ssh://git@github.com/uptick/gitops
77
+ ```
78
+
79
+ Upgrade it with `uv tool upgrade gitops`.
80
+
81
+ Installing from PyPI (`uv tool install gitops`) still works, but we are
82
+ moving away from it — use the git install.
73
83
 
74
84
  2. Set up the environment variable `GITOPS_APPS_DIRECTORY` to invoke gitops from any directory.
75
85
 
@@ -37,7 +37,17 @@ This is a git repository that you set up, where you list out all of your applica
37
37
 
38
38
  ## Gitops CLI Installation
39
39
 
40
- 1. Install the CLI tool with: `uv tool install gitops` and upgrade it with `uv tool upgrade gitops`.
40
+ 1. Install the CLI tool from GitHub over SSH, which needs an SSH key registered
41
+ with GitHub. Add `--verbose` to see what it is doing:
42
+
43
+ ```bash
44
+ uv tool install git+ssh://git@github.com/uptick/gitops
45
+ ```
46
+
47
+ Upgrade it with `uv tool upgrade gitops`.
48
+
49
+ Installing from PyPI (`uv tool install gitops`) still works, but we are
50
+ moving away from it — use the git install.
41
51
 
42
52
  2. Set up the environment variable `GITOPS_APPS_DIRECTORY` to invoke gitops from any directory.
43
53
 
@@ -6,7 +6,7 @@ from gitops.utils.apps import App, get_app_details, get_apps # type: ignore[att
6
6
 
7
7
  from .utils.cli import success, warning
8
8
 
9
- __version__ = "1.6.3"
9
+ __version__ = "1.7.1"
10
10
 
11
11
 
12
12
  # Checking gitops version matches cluster repo version.
@@ -340,13 +340,14 @@ def _sort_envs(envs: dict[str, Any]) -> dict[str, Any]:
340
340
 
341
341
 
342
342
  @task
343
- def setenv(ctx: Any, filter: str, values: str, exclude: str = "", limit: int = 0) -> None:
343
+ def setenv(ctx: Any, filter: str, values: str, exclude: str = "", limit: int = 0, skip_deploy: bool = False) -> None:
344
344
  """Set one or more env vars on selected app(s).
345
345
 
346
346
  eg. inv setenv customer,sandbox BG_RUNNER=DRAMATIQ,BUMP=2
347
347
 
348
348
  NOTE: More broad-reaching environment changes should be made at the chart level.
349
349
  Provide `limit` to process only the first N matching apps.
350
+ Provide `skip_deploy` to skip deploying for non functional changes.
350
351
  """
351
352
  splitenvs = values.split(",") # pardon the pun.
352
353
  formatted_splitenvs = "\n".join(splitenvs)
@@ -380,18 +381,21 @@ def setenv(ctx: Any, filter: str, values: str, exclude: str = "", limit: int = 0
380
381
  commit_message = f"Set env var(s) '{values}' on {filter}"
381
382
  if exclude:
382
383
  commit_message += f" (except {exclude})"
384
+ if skip_deploy:
385
+ commit_message += " --skip-deploy"
383
386
  run(f'cd {get_apps_directory()}; git commit -am "{commit_message}."')
384
387
  print(success("Done!"))
385
388
 
386
389
 
387
390
  @task
388
- def unsetenv(ctx: Any, filter: str, values: str, exclude: str = "", limit: int = 0) -> None:
391
+ def unsetenv(ctx: Any, filter: str, values: str, exclude: str = "", limit: int = 0, skip_deploy: bool = False) -> None:
389
392
  """Unset one or more env vars on selected app(s).
390
393
 
391
394
  eg. inv unsetenv customer,sandbox BG_RUNNER,BUMP
392
395
 
393
396
  NOTE: More broad-reaching environment changes should be made at the chart level.
394
397
  Provide `limit` to process only the first N matching apps.
398
+ Provide `skip_deploy` to skip deploying for non functional changes.
395
399
  """
396
400
  splitenvs = values.split(",") # pardon the pun.
397
401
  formatted_splitenvs = "\n".join(splitenvs)
@@ -416,6 +420,8 @@ def unsetenv(ctx: Any, filter: str, values: str, exclude: str = "", limit: int =
416
420
  commit_message = f"Unset env var(s) '{values}' on {filter}"
417
421
  if exclude:
418
422
  commit_message += f" (except {exclude})"
423
+ if skip_deploy:
424
+ commit_message += " --skip-deploy"
419
425
  run(f'cd {get_apps_directory()}; git commit -am "{commit_message}."')
420
426
  print(success("Done!"))
421
427
 
@@ -0,0 +1 @@
1
+ __version__ = "1.7.1"
@@ -1,7 +1,7 @@
1
1
 
2
2
  [project]
3
3
  name = "gitops"
4
- version = "1.6.3"
4
+ version = "1.7.1"
5
5
  description = "Manage multiple apps across one or more k8s clusters."
6
6
  requires-python = ">=3.12"
7
7
  readme = "README.md"
@@ -45,16 +45,16 @@ server = [
45
45
  requires = ["hatchling"]
46
46
  build-backend = "hatchling.build"
47
47
 
48
- [tool.uv]
49
- dev-dependencies = [
50
- "pytest>=8.3.2",
48
+ [dependency-groups]
49
+ dev = [
50
+ "pytest>=9.0.3",
51
51
  "ruff>=0.6.3",
52
52
  "types-colorama>=0.4.15.20240311",
53
53
  "mypy>=1.15",
54
54
  "types-pyyaml>=6.0.12.20240808",
55
55
  "types-tabulate>=0.9.0.20240106",
56
56
  "boto3-stubs>=1.35.11",
57
- "pytest-asyncio>=0.24.0",
57
+ "pytest-asyncio>=1.0.0",
58
58
  "types-invoke>=2.0.0.10",
59
59
  ]
60
60
 
@@ -0,0 +1,6 @@
1
+ {
2
+ "$schema": "https://docs.renovatebot.com/renovate-schema.json",
3
+ "extends": [
4
+ "local>uptick/renovate-config"
5
+ ]
6
+ }
@@ -10,7 +10,11 @@ from gitops import core
10
10
 
11
11
  @fixture(autouse=True)
12
12
  def mock_invoke_run(monkeypatch):
13
- monkeypatch.setattr(core, "run", lambda cmd: None)
13
+ """Swallow shelled-out commands, recording them so tests can assert on the
14
+ commit messages the tasks build."""
15
+ commands = []
16
+ monkeypatch.setattr(core, "run", commands.append)
17
+ return commands
14
18
 
15
19
 
16
20
  @fixture(autouse=True)
@@ -48,6 +52,9 @@ class TestMixin:
48
52
  def deployment_yml_is_unchanged(self):
49
53
  return self.original_content == self.deployment_yml_path.read_text()
50
54
 
55
+ def commit_command(self, commands):
56
+ return next(cmd for cmd in commands if "git commit" in cmd)
57
+
51
58
 
52
59
  class TestSetEnv(TestMixin):
53
60
  def test_setenv_should_not_overwrite_if_there_is_existing_variable(
@@ -137,6 +144,36 @@ class TestSetEnv(TestMixin):
137
144
  """
138
145
  )
139
146
 
147
+ def test_setenv_marks_commit_to_skip_deploy(
148
+ self,
149
+ deployment_yml,
150
+ confirm_yes,
151
+ mock_invoke_run,
152
+ ):
153
+ deployment_yml(
154
+ """\
155
+ namespace: test
156
+ chart: test
157
+ """
158
+ )
159
+ core.setenv(MockContext(), filter="all", values="HELLO=WORLD", skip_deploy=True)
160
+ assert "--skip-deploy" in self.commit_command(mock_invoke_run)
161
+
162
+ def test_setenv_does_not_skip_deploy_by_default(
163
+ self,
164
+ deployment_yml,
165
+ confirm_yes,
166
+ mock_invoke_run,
167
+ ):
168
+ deployment_yml(
169
+ """\
170
+ namespace: test
171
+ chart: test
172
+ """
173
+ )
174
+ core.setenv(MockContext(), filter="all", values="HELLO=WORLD")
175
+ assert "--skip-deploy" not in self.commit_command(mock_invoke_run)
176
+
140
177
 
141
178
  class TestUnsetEnv(TestMixin):
142
179
  def test_unset_environment_variable_removes_matching_variables(
@@ -258,3 +295,74 @@ class TestUnsetEnv(TestMixin):
258
295
  chart: test
259
296
  """
260
297
  )
298
+
299
+ def test_unsetenv_marks_commit_to_skip_deploy(
300
+ self,
301
+ deployment_yml,
302
+ confirm_yes,
303
+ mock_invoke_run,
304
+ ):
305
+ deployment_yml(
306
+ """\
307
+ namespace: test
308
+ chart: test
309
+ environment:
310
+ HELLO: WORLD
311
+ """
312
+ )
313
+ core.unsetenv(MockContext(), filter="all", values="HELLO", skip_deploy=True)
314
+ assert "--skip-deploy" in self.commit_command(mock_invoke_run)
315
+
316
+ def test_unsetenv_does_not_skip_deploy_by_default(
317
+ self,
318
+ deployment_yml,
319
+ confirm_yes,
320
+ mock_invoke_run,
321
+ ):
322
+ deployment_yml(
323
+ """\
324
+ namespace: test
325
+ chart: test
326
+ environment:
327
+ HELLO: WORLD
328
+ """
329
+ )
330
+ core.unsetenv(MockContext(), filter="all", values="HELLO")
331
+ assert "--skip-deploy" not in self.commit_command(mock_invoke_run)
332
+
333
+
334
+ class TestBump(TestMixin):
335
+ """`image_tag` is passed explicitly throughout so bump never reaches for the
336
+ latest image in ECR."""
337
+
338
+ def test_bump_marks_commit_to_skip_deploy(
339
+ self,
340
+ deployment_yml,
341
+ confirm_yes,
342
+ mock_invoke_run,
343
+ ):
344
+ deployment_yml(
345
+ """\
346
+ namespace: test
347
+ chart: test
348
+ image: registry/uptick:old-abc123
349
+ """
350
+ )
351
+ core.bump(MockContext(), filter="all", image_tag="new-def456", skip_deploy=True)
352
+ assert "--skip-deploy" in self.commit_command(mock_invoke_run)
353
+
354
+ def test_bump_does_not_skip_deploy_by_default(
355
+ self,
356
+ deployment_yml,
357
+ confirm_yes,
358
+ mock_invoke_run,
359
+ ):
360
+ deployment_yml(
361
+ """\
362
+ namespace: test
363
+ chart: test
364
+ image: registry/uptick:old-abc123
365
+ """
366
+ )
367
+ core.bump(MockContext(), filter="all", image_tag="new-def456")
368
+ assert "--skip-deploy" not in self.commit_command(mock_invoke_run)
@@ -360,7 +360,7 @@ wheels = [
360
360
 
361
361
  [[package]]
362
362
  name = "gitops"
363
- version = "1.6.3"
363
+ version = "1.7.1"
364
364
  source = { editable = "." }
365
365
  dependencies = [
366
366
  { name = "boto3" },
@@ -435,8 +435,8 @@ provides-extras = ["server"]
435
435
  dev = [
436
436
  { name = "boto3-stubs", specifier = ">=1.35.11" },
437
437
  { name = "mypy", specifier = ">=1.15" },
438
- { name = "pytest", specifier = ">=8.3.2" },
439
- { name = "pytest-asyncio", specifier = ">=0.24.0" },
438
+ { name = "pytest", specifier = ">=9.0.3" },
439
+ { name = "pytest-asyncio", specifier = ">=1.0.0" },
440
440
  { name = "ruff", specifier = ">=0.6.3" },
441
441
  { name = "types-colorama", specifier = ">=0.4.15.20240311" },
442
442
  { name = "types-invoke", specifier = ">=2.0.0.10" },
@@ -1213,31 +1213,42 @@ wheels = [
1213
1213
  { url = "https://files.pythonhosted.org/packages/51/b2/b2b50d5ecf21acf870190ae5d093602d95f66c9c31f9d5de6062eb329ad1/pydantic_core-2.27.2-cp313-cp313-win_arm64.whl", hash = "sha256:ac4dbfd1691affb8f48c2c13241a2e3b60ff23247cbcf981759c768b6633cf8b", size = 1885186, upload-time = "2024-12-18T11:29:37.649Z" },
1214
1214
  ]
1215
1215
 
1216
+ [[package]]
1217
+ name = "pygments"
1218
+ version = "2.20.0"
1219
+ source = { registry = "https://pypi.org/simple" }
1220
+ sdist = { url = "https://files.pythonhosted.org/packages/c3/b2/bc9c9196916376152d655522fdcebac55e66de6603a76a02bca1b6414f6c/pygments-2.20.0.tar.gz", hash = "sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f", size = 4955991, upload-time = "2026-03-29T13:29:33.898Z" }
1221
+ wheels = [
1222
+ { url = "https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl", hash = "sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176", size = 1231151, upload-time = "2026-03-29T13:29:30.038Z" },
1223
+ ]
1224
+
1216
1225
  [[package]]
1217
1226
  name = "pytest"
1218
- version = "8.3.4"
1227
+ version = "9.1.1"
1219
1228
  source = { registry = "https://pypi.org/simple" }
1220
1229
  dependencies = [
1221
1230
  { name = "colorama", marker = "sys_platform == 'win32'" },
1222
1231
  { name = "iniconfig" },
1223
1232
  { name = "packaging" },
1224
1233
  { name = "pluggy" },
1234
+ { name = "pygments" },
1225
1235
  ]
1226
- sdist = { url = "https://files.pythonhosted.org/packages/05/35/30e0d83068951d90a01852cb1cef56e5d8a09d20c7f511634cc2f7e0372a/pytest-8.3.4.tar.gz", hash = "sha256:965370d062bce11e73868e0335abac31b4d3de0e82f4007408d242b4f8610761", size = 1445919, upload-time = "2024-12-01T12:54:25.98Z" }
1236
+ sdist = { url = "https://files.pythonhosted.org/packages/e4/47/b9efed96c114afcfa3c9d3fe98a76a1d14c74a9e266d397cf6eb64be5e01/pytest-9.1.1.tar.gz", hash = "sha256:1088fbde8f2b49d95a549a195707afa7a76a3ce9bcadc26b6d71f0ffda5fe313", size = 1636369, upload-time = "2026-06-19T10:58:32.857Z" }
1227
1237
  wheels = [
1228
- { url = "https://files.pythonhosted.org/packages/11/92/76a1c94d3afee238333bc0a42b82935dd8f9cf8ce9e336ff87ee14d9e1cf/pytest-8.3.4-py3-none-any.whl", hash = "sha256:50e16d954148559c9a74109af1eaf0c945ba2d8f30f0a3d3335edde19788b6f6", size = 343083, upload-time = "2024-12-01T12:54:19.735Z" },
1238
+ { url = "https://files.pythonhosted.org/packages/24/25/1de2678b631f5a49215c6c96fff41ba892b0a34df68d6d80292b1b48aa7f/pytest-9.1.1-py3-none-any.whl", hash = "sha256:37a86b45efb9a47a61a36449063e8e18d0cab3161329fc099eb21783169c4f0c", size = 386536, upload-time = "2026-06-19T10:58:31.347Z" },
1229
1239
  ]
1230
1240
 
1231
1241
  [[package]]
1232
1242
  name = "pytest-asyncio"
1233
- version = "0.25.2"
1243
+ version = "1.4.0"
1234
1244
  source = { registry = "https://pypi.org/simple" }
1235
1245
  dependencies = [
1236
1246
  { name = "pytest" },
1247
+ { name = "typing-extensions", marker = "python_full_version < '3.13'" },
1237
1248
  ]
1238
- sdist = { url = "https://files.pythonhosted.org/packages/72/df/adcc0d60f1053d74717d21d58c0048479e9cab51464ce0d2965b086bd0e2/pytest_asyncio-0.25.2.tar.gz", hash = "sha256:3f8ef9a98f45948ea91a0ed3dc4268b5326c0e7bce73892acc654df4262ad45f", size = 53950, upload-time = "2025-01-08T06:20:29.31Z" }
1249
+ sdist = { url = "https://files.pythonhosted.org/packages/43/7c/d36d04db312ecf4298932ef77e6e4a9e8ad017906e24e34f0b0c361a2473/pytest_asyncio-1.4.0.tar.gz", hash = "sha256:c6c0d2259945122819f171a32ecea2c349ead889ee28176caaf492143424be42", size = 58514, upload-time = "2026-05-26T09:56:04.083Z" }
1239
1250
  wheels = [
1240
- { url = "https://files.pythonhosted.org/packages/61/d8/defa05ae50dcd6019a95527200d3b3980043df5aa445d40cb0ef9f7f98ab/pytest_asyncio-0.25.2-py3-none-any.whl", hash = "sha256:0d0bb693f7b99da304a0634afc0a4b19e49d5e0de2d670f38dc4bfa5727c5075", size = 19400, upload-time = "2025-01-08T06:20:27.862Z" },
1251
+ { url = "https://files.pythonhosted.org/packages/03/e2/08a497ef684b88559c9cc5f4ad53a37e7b99e727094a86d6ea32536d5d3c/pytest_asyncio-1.4.0-py3-none-any.whl", hash = "sha256:933ca923a23075a87fb7070c0ec272a6848489824d887c85c812670932835aa1", size = 16930, upload-time = "2026-05-26T09:56:02.576Z" },
1241
1252
  ]
1242
1253
 
1243
1254
  [[package]]
@@ -1 +0,0 @@
1
- __version__ = "1.6.3"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes