This is an automated email from the ASF dual-hosted git repository.

arm pushed a commit to branch atr_tagging
in repository https://gitbox.apache.org/repos/asf/tooling-trusted-releases.git

commit 999e4e27ba87f111d89c4ee82ccb035e8dc51345
Author: Alastair McFarlane <[email protected]>
AuthorDate: Wed Jan 21 16:41:54 2026 +0000

    #475 - add tagging field to release policy
---
 .pre-commit-config.yaml                         |  6 +++---
 atr/get/projects.py                             |  3 +++
 atr/models/sql.py                               |  9 +++++++++
 atr/shared/projects.py                          |  5 +++++
 atr/storage/writers/policy.py                   |  4 ++++
 migrations/versions/0041_2026.01.21_44cdc6b9.py | 27 +++++++++++++++++++++++++
 pyproject.toml                                  |  1 +
 uv.lock                                         | 12 ++++++-----
 8 files changed, 59 insertions(+), 8 deletions(-)

diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 4a71a40..ae5c551 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -84,7 +84,7 @@ repos:
 #        - --profile=jinja
 #        - --reformat
 - repo: https://github.com/thibaudcolas/pre-commit-stylelint
-  rev: v16.26.1
+  rev: v17.0.0
   hooks:
     - id: stylelint
       additional_dependencies: ['[email protected]', 
'[email protected]']
@@ -92,7 +92,7 @@ repos:
       types_or: ['css']
       args: ['--fix', '--allow-empty-input']
 - repo: https://github.com/woodruffw/zizmor-pre-commit
-  rev: v1.21.0
+  rev: v1.22.0
   hooks:
     - id: zizmor
       args: [--min-severity, low]
@@ -101,7 +101,7 @@ repos:
   hooks:
     - id: pip-audit
 - repo: https://github.com/oxc-project/mirrors-oxlint
-  rev: v1.39.0
+  rev: v1.41.0
   hooks:
     - id: oxlint
       name: lint JS files with Oxlint
diff --git a/atr/get/projects.py b/atr/get/projects.py
index 1b44c94..47858fe 100644
--- a/atr/get/projects.py
+++ b/atr/get/projects.py
@@ -19,6 +19,7 @@ from __future__ import annotations
 
 import asfquart.base as base
 import htpy
+import yaml
 
 import atr.blueprints.get as get
 import atr.config as config
@@ -320,6 +321,7 @@ def _render_compose_form(project: sql.Project) -> 
htm.Element:
         htm.h3(".mb-0")["Release policy - Compose options"]
     ]
 
+    atr_tag_yaml = yaml.dump(project.policy_atr_file_tagging_spec)
     with card.block(htm.div, classes=".card-body") as card_body:
         form.render_block(
             card_body,
@@ -335,6 +337,7 @@ def _render_compose_form(project: sql.Project) -> 
htm.Element:
                 "binary_artifact_paths": 
"\n".join(project.policy_binary_artifact_paths),
                 "github_repository_name": 
project.policy_github_repository_name or "",
                 "github_compose_workflow_path": 
"\n".join(project.policy_github_compose_workflow_path),
+                "atr_file_tagging_spec": atr_tag_yaml,
                 "strict_checking": project.policy_strict_checking,
             },
             form_classes=".atr-canary.py-4.px-5",
diff --git a/atr/models/sql.py b/atr/models/sql.py
index 3e71d2d..b87601e 100644
--- a/atr/models/sql.py
+++ b/atr/models/sql.py
@@ -743,6 +743,12 @@ Thanks,
             return []
         return policy.github_compose_workflow_path or []
 
+    @property
+    def policy_atr_file_tagging_spec(self) -> dict[str, Any]:
+        if (policy := self.release_policy) is None:
+            return {}
+        return policy.atr_file_tagging_spec or {}
+
     @property
     def policy_github_vote_workflow_path(self) -> list[str]:
         if (policy := self.release_policy) is None:
@@ -1082,6 +1088,9 @@ class ReleasePolicy(sqlmodel.SQLModel, table=True):
     github_compose_workflow_path: list[str] = sqlmodel.Field(
         default_factory=list, sa_column=sqlalchemy.Column(sqlalchemy.JSON, 
nullable=False)
     )
+    atr_file_tagging_spec: dict[str, Any] = sqlmodel.Field(
+        default_factory=dict, sa_column=sqlalchemy.Column(sqlalchemy.JSON, 
nullable=False)
+    )
     github_vote_workflow_path: list[str] = sqlmodel.Field(
         default_factory=list, sa_column=sqlalchemy.Column(sqlalchemy.JSON, 
nullable=False)
     )
diff --git a/atr/shared/projects.py b/atr/shared/projects.py
index 7eabf73..8f57c53 100644
--- a/atr/shared/projects.py
+++ b/atr/shared/projects.py
@@ -141,6 +141,11 @@ class ComposePolicyForm(form.Form):
         "The full paths to the GitHub workflows to use for the release, 
including the .github/workflows/ prefix.",
         widget=form.Widget.TEXTAREA,
     )
+    atr_file_tagging_spec: str = form.label(
+        "Tagging spec",
+        "Spec for which files should be tagged for release in specific 
distribution types, YAML format",
+        widget=form.Widget.TEXTAREA,
+    )
     strict_checking: form.Bool = form.label(
         "Strict checking",
         "If enabled, then the release cannot be voted upon unless all checks 
pass.",
diff --git a/atr/storage/writers/policy.py b/atr/storage/writers/policy.py
index b7f79c1..b52ffaa 100644
--- a/atr/storage/writers/policy.py
+++ b/atr/storage/writers/policy.py
@@ -20,6 +20,8 @@ from __future__ import annotations
 
 from typing import TYPE_CHECKING
 
+import yaml
+
 import atr.db as db
 import atr.models as models
 import atr.storage as storage
@@ -95,6 +97,7 @@ class CommitteeMember(CommitteeParticipant):
         project_name = form.project_name
         _, release_policy = await self.__get_or_create_policy(project_name)
 
+        atr_tags_dict = yaml.safe_load(form.atr_file_tagging_spec) or {}
         release_policy.source_artifact_paths = 
_split_lines(form.source_artifact_paths)
         release_policy.license_check_mode = form.license_check_mode  # 
pyright: ignore[reportAttributeAccessIssue]
         release_policy.source_excludes_lightweight = 
_split_lines_verbatim(form.source_excludes_lightweight)
@@ -102,6 +105,7 @@ class CommitteeMember(CommitteeParticipant):
         release_policy.binary_artifact_paths = 
_split_lines(form.binary_artifact_paths)
         release_policy.github_repository_name = 
form.github_repository_name.strip()
         release_policy.github_compose_workflow_path = 
_split_lines(form.github_compose_workflow_path)
+        release_policy.atr_file_tagging_spec = atr_tags_dict
         release_policy.strict_checking = form.strict_checking
 
         await self.__commit_and_log(project_name)
diff --git a/migrations/versions/0041_2026.01.21_44cdc6b9.py 
b/migrations/versions/0041_2026.01.21_44cdc6b9.py
new file mode 100644
index 0000000..e4d7dcd
--- /dev/null
+++ b/migrations/versions/0041_2026.01.21_44cdc6b9.py
@@ -0,0 +1,27 @@
+"""Add ATR tagging spec policy
+
+Revision ID: 0041_2026.01.21_44cdc6b9
+Revises: 0040_2026.01.15_31d91cc5
+Create Date: 2026-01-21 15:52:13.681523+00:00
+"""
+
+from collections.abc import Sequence
+
+import sqlalchemy as sa
+from alembic import op
+
+# Revision identifiers, used by Alembic
+revision: str = "0041_2026.01.21_44cdc6b9"
+down_revision: str | None = "0040_2026.01.15_31d91cc5"
+branch_labels: str | Sequence[str] | None = None
+depends_on: str | Sequence[str] | None = None
+
+
+def upgrade() -> None:
+    with op.batch_alter_table("releasepolicy", schema=None) as batch_op:
+        batch_op.add_column(sa.Column("atr_file_tagging_spec", sa.JSON(), 
nullable=False, server_default="{}"))
+
+
+def downgrade() -> None:
+    with op.batch_alter_table("releasepolicy", schema=None) as batch_op:
+        batch_op.drop_column("atr_file_tagging_spec")
diff --git a/pyproject.toml b/pyproject.toml
index 7d42d65..1afa9fa 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -42,6 +42,7 @@ dependencies = [
   # "pynacl>=1.5.0",
   "python-decouple~=3.8",
   "python-gnupg~=0.5",
+  "pyyaml>=6.0.3",
   "quart-schema[pydantic]~=0.21",
   "quart-wtforms~=1.0.3",
   "rich~=14.0.0",
diff --git a/uv.lock b/uv.lock
index c270089..ede5018 100644
--- a/uv.lock
+++ b/uv.lock
@@ -3,7 +3,7 @@ revision = 3
 requires-python = "==3.13.*"
 
 [options]
-exclude-newer = "2026-01-16T20:26:29Z"
+exclude-newer = "2026-01-21T16:41:48Z"
 
 [[package]]
 name = "aiofiles"
@@ -178,7 +178,7 @@ wheels = [
 [[package]]
 name = "asfquart"
 version = "0.1.13"
-source = { git = 
"https://github.com/apache/infrastructure-asfquart.git?rev=main#a00d184c94912959d5ceaa9bbfd27976e63874ac";
 }
+source = { git = 
"https://github.com/apache/infrastructure-asfquart.git?rev=main#f43799f2d40ec023e2547dcdd895ae7a504205e1";
 }
 dependencies = [
     { name = "aiohttp" },
     { name = "asfpy" },
@@ -1222,11 +1222,11 @@ wheels = [
 
 [[package]]
 name = "pycparser"
-version = "2.23"
+version = "3.0"
 source = { registry = "https://pypi.org/simple"; }
-sdist = { url = 
"https://files.pythonhosted.org/packages/fe/cf/d2d3b9f5699fb1e4615c8e32ff220203e43b248e1dfcc6736ad9057731ca/pycparser-2.23.tar.gz";,
 hash = 
"sha256:78816d4f24add8f10a06d6f05b4d424ad9e96cfebf68a4ddc99c65c0720d00c2", size 
= 173734, upload-time = "2025-09-09T13:23:47.91Z" }
+sdist = { url = 
"https://files.pythonhosted.org/packages/1b/7d/92392ff7815c21062bea51aa7b87d45576f649f16458d78b7cf94b9ab2e6/pycparser-3.0.tar.gz";,
 hash = 
"sha256:600f49d217304a5902ac3c37e1281c9fe94e4d0489de643a9504c5cdfdfc6b29", size 
= 103492, upload-time = "2026-01-21T14:26:51.89Z" }
 wheels = [
-    { url = 
"https://files.pythonhosted.org/packages/a0/e3/59cd50310fc9b59512193629e1984c1f95e5c8ae6e5d8c69532ccc65a7fe/pycparser-2.23-py3-none-any.whl";,
 hash = 
"sha256:e5c6e8d3fbad53479cab09ac03729e0a9faf2bee3db8208a550daf5af81a5934", size 
= 118140, upload-time = "2025-09-09T13:23:46.651Z" },
+    { url = 
"https://files.pythonhosted.org/packages/0c/c3/44f3fbbfa403ea2a7c779186dc20772604442dde72947e7d01069cbe98e3/pycparser-3.0-py3-none-any.whl";,
 hash = 
"sha256:b727414169a36b7d524c1c3e31839a521725078d7b2ff038656844266160a992", size 
= 48172, upload-time = "2026-01-21T14:26:50.693Z" },
 ]
 
 [[package]]
@@ -1838,6 +1838,7 @@ dependencies = [
     { name = "pyjwt" },
     { name = "python-decouple" },
     { name = "python-gnupg" },
+    { name = "pyyaml" },
     { name = "quart-schema", extra = ["pydantic"] },
     { name = "quart-wtforms" },
     { name = "rich" },
@@ -1897,6 +1898,7 @@ requires-dist = [
     { name = "pyjwt", specifier = ">=2.10.1,<3.0.0" },
     { name = "python-decouple", specifier = "~=3.8" },
     { name = "python-gnupg", specifier = "~=0.5" },
+    { name = "pyyaml", specifier = ">=6.0.3" },
     { name = "quart-schema", extras = ["pydantic"], specifier = "~=0.21" },
     { name = "quart-wtforms", specifier = "~=1.0.3" },
     { name = "rich", specifier = "~=14.0.0" },


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to