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 6df80fe0138e7db4df84511b1af3a564e13e45dc 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]
