asf-tooling commented on issue #921:
URL: 
https://github.com/apache/tooling-trusted-releases/issues/921#issuecomment-4410014102

   <!-- gofannon-issue-triage-bot v2 -->
   
   **Automated triage** — analyzed at `main@2da7807a`
   
   **Type:** `discussion`  •  **Classification:** `no_action`  •  
**Confidence:** `medium`
   **Application domain(s):** `project_committee_management`, 
`web_api_infrastructure`, `shared_infrastructure`
   
   ### Summary
   This issue requests defining a unified YAML/JSON format for 
exporting/importing project metadata, cycles, and policy settings as a single 
document, enabling a programmatic API for bulk project configuration (issue 
#139). The underlying data models already exist (Project, ProjectCycle, 
ReleasePolicy) and partial APIs exist (PolicyGetResults, PolicyUpdateArgs, 
ProjectGetResults), but there is no unified schema combining all three into a 
single interchange format. No prior discussion has occurred, so a format design 
decision is needed before implementation.
   
   ### Where this lives in the code today
   
   #### `atr/models/api.py` — `PolicyGetResults` (lines 295-316)
   _currently does this_
   Existing API response model for policy data - partial coverage of what the 
unified format would include.
   
   ```python
   class PolicyGetResults(schema.Strict):
       endpoint: Literal["/policy/get"] = schema.alias("endpoint")
       project_key: safe.ProjectKey
       policy_announce_release_subject: str
       policy_announce_release_template: str
       policy_binary_artifact_paths: list[str]
       policy_github_compose_workflow_path: list[str]
       policy_github_finish_workflow_path: list[str]
       policy_github_repository_branch: str
       policy_github_repository_name: str
       policy_github_vote_workflow_path: list[str]
       policy_license_check_mode: sql.LicenseCheckMode
       policy_mailto_addresses: list[str]
       policy_manual_vote: bool
       policy_min_hours: int
       policy_vote_mode: sql.VoteMode = schema.example(sql.VoteMode.EMAIL)
       policy_preserve_download_files: bool
       policy_release_checklist: str
       policy_source_artifact_paths: list[str]
       policy_start_vote_subject: str
       policy_start_vote_template: str
       policy_vote_comment_template: str
   ```
   
   #### `atr/models/api.py` — `ProjectGetResults` (lines 290-292)
   _currently does this_
   Existing API response model for project metadata - another partial component 
of the unified format.
   
   ```python
   class ProjectGetResults(schema.Strict):
       endpoint: Literal["/project/get"] = schema.alias("endpoint")
       project: sql.Project
   ```
   
   #### `atr/models/api.py` — `PolicyUpdateArgs` (lines 319-342)
   _currently does this_
   Existing API request model for updating policy - the POST counterpart for 
policy settings.
   
   ```python
   class PolicyUpdateArgs(schema.Strict):
       project: safe.ProjectKey = schema.example("example")
       announce_release_subject: str | None = None
       announce_release_template: str | None = None
       binary_artifact_paths: list[str] | None = None
       file_tag_mappings: dict[str, list[str]] | None = None
       github_compose_workflow_path: list[str] | None = None
       github_finish_workflow_path: list[str] | None = None
       github_repository_branch: str | None = None
       github_repository_name: str | None = None
       github_vote_workflow_path: list[str] | None = None
       license_check_mode: sql.LicenseCheckMode | None = None
       mailto_addresses: list[pydantic.EmailStr] | None = None
       manual_vote: bool | None = None
       min_hours: int | None = None
       preserve_download_files: bool | None = None
       release_checklist: str | None = None
       source_artifact_paths: list[str] | None = None
       source_excludes_lightweight: list[str] | None = None
       source_excludes_rat: list[str] | None = None
       start_vote_subject: str | None = None
       start_vote_template: str | None = None
       vote_comment_template: str | None = None
       vote_mode: sql.VoteMode | None = None
   ```
   
   #### `atr/models/sql.py` — `Project` (lines 714-726)
   _extension point_
   Project model with version-scheme metadata fields from issue #912 - would be 
serialized as part of the unified format.
   
   ```python
   class Project(sqlmodel.SQLModel, table=True):
       key: str = sqlmodel.Field(primary_key=True, unique=True, 
**example("example"))
       name: str | None = sqlmodel.Field(default=None, **example("Apache 
Example"))
       status: ProjectStatus = sqlmodel.Field(default=ProjectStatus.ACTIVE, 
**example(ProjectStatus.ACTIVE))
       super_project_key: str | None = sqlmodel.Field(default=None, 
foreign_key="project.key")
       super_project: Optional["Project"] = sqlmodel.Relationship()
       description: str | None = sqlmodel.Field(default=None, 
**example("Example is a simple example project"))
       category: str | None = sqlmodel.Field(default=None, 
**example("data,storage"))
       programming_languages: str | None = sqlmodel.Field(default=None, 
**example("c,python"))
       version_method: VersionMethod = 
sqlmodel.Field(default=VersionMethod.SIMPLE, **example(VersionMethod.SIMPLE))
       version_pattern: str | None = sqlmodel.Field(default=None, 
**example(r"^\d+\.\d+\.\d+$"))
       cycle_match: str | None = sqlmodel.Field(default=None, 
**example(r"^(\d+)\.\d+\.\d+$"))
       branch_template: str | None = sqlmodel.Field(default=None, 
**example("release-{cycle}"))
   ```
   
   #### `atr/db/__init__.py` — `Session.project_cycle` (lines 432-447)
   _extension point_
   Query builder for ProjectCycle - the data source for cycle information that 
would be included in the unified format.
   
   ```python
       def project_cycle(
           self,
           cycle_key: Opt[str] = NOT_SET,
           project_key: Opt[str] = NOT_SET,
           cycle: Opt[str] = NOT_SET,
           _project: bool = False,
           _releases: bool = False,
       ) -> Query[sql.ProjectCycle]:
           query = sqlmodel.select(sql.ProjectCycle)
   
           if is_defined(cycle_key):
               query = query.where(sql.ProjectCycle.cycle_key == cycle_key)
           if is_defined(project_key):
               query = query.where(sql.ProjectCycle.project_key == project_key)
           if is_defined(cycle):
               query = query.where(sql.ProjectCycle.cycle == cycle)
   ```
   
   #### `migrations/versions/0074_2026.05.04_0d6e9554.py` — `upgrade` (lines 
22-35)
   _currently does this_
   Migration for issue #912 that added versioning and cycle metadata to the 
project model - infrastructure the unified format would expose.
   
   ```python
   def upgrade() -> None:
       # project: add version-scheme metadata. Existing rows default to 
"simple".
       with op.batch_alter_table("project", schema=None) as batch_op:
           batch_op.add_column(
               sa.Column(
                   "version_method",
                   sa.Enum("SIMPLE", "SEMVER", "CALVER", name="versionmethod"),
                   nullable=False,
                   server_default="SIMPLE",
               )
           )
           batch_op.add_column(sa.Column("version_pattern", sa.String(), 
nullable=True))
           batch_op.add_column(sa.Column("cycle_match", sa.String(), 
nullable=True))
           batch_op.add_column(sa.Column("branch_template", sa.String(), 
nullable=True))
   ```
   
   ### Where new code would go
   - `atr/models/api.py` — after symbol PolicyUpdateResults
     New Pydantic models for a unified project configuration schema (e.g., 
ProjectConfigGetResults, ProjectConfigUpdateArgs) that combines metadata, 
cycles, and policy into a single document.
   - `atr/api/__init__.py` — new endpoints
     New API endpoint handlers for GET /project/config and POST /project/config 
that serialize/deserialize the unified format.
   
   ### Proposed approach
   This issue requires a design decision before implementation. The unified 
format should combine three currently separate concerns into a single document: 
(1) project metadata (name, status, description, categories, languages, version 
method/pattern), (2) cycle definitions (cycle_key, lifecycle dates, LTS flag), 
and (3) policy settings (vote config, trusted publishing, license checks, 
templates). The existing partial APIs (PolicyGetResults, PolicyUpdateArgs, 
ProjectGetResults) show the shape of the data but are spread across multiple 
endpoints.
   
   Once the format is agreed upon (likely as a new Pydantic schema in 
atr/models/api.py), implementation would involve: creating a GET endpoint that 
assembles the full document from Project + ProjectCycle + ReleasePolicy, and a 
POST/PUT endpoint that can apply a full or partial configuration document to 
update all three models atomically. YAML support could be added via a 
content-type negotiation layer or a separate serialization step. This would 
enable issue #139 (likely programmatic/declarative project setup).
   
   ### Open questions
   - What is the scope of issue #139 that this format is meant to enable? (Bulk 
project bootstrap? Declarative config-as-code?)
   - Should the format be YAML-primary or JSON-primary with YAML as an 
alternative serialization?
   - Should the unified format be a single flat document or nested sections 
(metadata/cycles/policy)?
   - Should cycle definitions be inline in the project document or referenced 
separately?
   - Should the format support partial updates (like PolicyUpdateArgs with 
nullable fields) or require full documents?
   - What authorization level is needed for the new endpoint - committee member 
only, or should participants also read?
   - Is there an existing design document or RFC template where this format 
should be proposed?
   
   _The agent reviewed this issue and is not proposing patches in this run. 
Review the existing-code citations and open questions above before deciding 
next steps._
   
   ### Files examined
   - `atr/models/sql.py`
   - `atr/models/api.py`
   - `atr/db/__init__.py`
   - `migrations/versions/0074_2026.05.04_0d6e9554.py`
   - `migrations/versions/0076_2026.05.06_e5fa9b30.py`
   - `atr/storage/__init__.py`
   - `atr/shared/projects.py`
   - `atr/docs/database.md`
   
   ---
   *Draft from a triage agent. A human reviewer should validate before merging 
any change. The agent did not run tests or verify diffs apply.*


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


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

Reply via email to