feat(release): publish verified source tags
This commit is contained in:
@@ -18,6 +18,7 @@ from govoplan_release import (
|
||||
prepare_repositories,
|
||||
push_repositories,
|
||||
sync_repositories,
|
||||
tag_repositories,
|
||||
)
|
||||
from govoplan_release.model import to_jsonable
|
||||
from govoplan_release.workspace import DEFAULT_WORKSPACE_ROOT, META_ROOT
|
||||
@@ -35,6 +36,7 @@ class CatalogCandidateRequest(BaseModel):
|
||||
sequence: int | None = None
|
||||
public_base_url: str = "https://govoplan.add-ideas.de"
|
||||
repository_base: str = "git+ssh://git@git.add-ideas.de/add-ideas"
|
||||
source_remote: str = "origin"
|
||||
check_public: bool = True
|
||||
|
||||
|
||||
@@ -48,6 +50,7 @@ class PublishCandidateRequest(BaseModel):
|
||||
tag: bool = False
|
||||
push: bool = False
|
||||
remote: str = "origin"
|
||||
source_remote: str = "origin"
|
||||
branch: str | None = None
|
||||
tag_name: str | None = None
|
||||
npm: str = "npm"
|
||||
@@ -77,6 +80,16 @@ class RepositoryPrepareRequest(BaseModel):
|
||||
confirm: str = ""
|
||||
|
||||
|
||||
class RepositoryTagRequest(BaseModel):
|
||||
repos: list[str] = Field(default_factory=list)
|
||||
repo_versions: dict[str, str] = Field(default_factory=dict)
|
||||
remote: str = "origin"
|
||||
message: str | None = None
|
||||
apply: bool = False # noqa: A003 - API field mirrors CLI.
|
||||
push: bool = False
|
||||
confirm: str = ""
|
||||
|
||||
|
||||
def create_app(*, workspace_root: Path = DEFAULT_WORKSPACE_ROOT, token: str | None = None) -> FastAPI:
|
||||
app = FastAPI(title="GovOPlaN Release Console", version="0.1.0")
|
||||
app.state.workspace_root = workspace_root
|
||||
@@ -203,19 +216,23 @@ def create_app(*, workspace_root: Path = DEFAULT_WORKSPACE_ROOT, token: str | No
|
||||
signing_keys = tuple(request.signing_keys or default_signing_keys())
|
||||
if not signing_keys:
|
||||
raise HTTPException(status_code=400, detail="No signing key supplied and default release key was not found")
|
||||
candidate = build_selective_catalog_candidate(
|
||||
repo_versions=repo_versions,
|
||||
channel=request.channel,
|
||||
workspace_root=app.state.workspace_root,
|
||||
output_dir=request.output_dir,
|
||||
base_catalog=request.base_catalog,
|
||||
signing_keys=signing_keys,
|
||||
public_base_url=request.public_base_url,
|
||||
repository_base=request.repository_base,
|
||||
expires_days=request.expires_days,
|
||||
sequence=request.sequence,
|
||||
check_public=request.check_public,
|
||||
)
|
||||
try:
|
||||
candidate = build_selective_catalog_candidate(
|
||||
repo_versions=repo_versions,
|
||||
channel=request.channel,
|
||||
workspace_root=app.state.workspace_root,
|
||||
output_dir=request.output_dir,
|
||||
base_catalog=request.base_catalog,
|
||||
signing_keys=signing_keys,
|
||||
public_base_url=request.public_base_url,
|
||||
repository_base=request.repository_base,
|
||||
source_remote=request.source_remote,
|
||||
expires_days=request.expires_days,
|
||||
sequence=request.sequence,
|
||||
check_public=request.check_public,
|
||||
)
|
||||
except ValueError as exc:
|
||||
raise HTTPException(status_code=409, detail=str(exc)) from exc
|
||||
return to_jsonable(candidate)
|
||||
|
||||
@app.post("/api/catalog-candidates/publish")
|
||||
@@ -235,6 +252,7 @@ def create_app(*, workspace_root: Path = DEFAULT_WORKSPACE_ROOT, token: str | No
|
||||
tag=request.tag,
|
||||
push=request.push,
|
||||
remote=request.remote,
|
||||
source_remote=request.source_remote,
|
||||
branch=request.branch,
|
||||
tag_name=request.tag_name,
|
||||
npm=request.npm,
|
||||
@@ -278,6 +296,26 @@ def create_app(*, workspace_root: Path = DEFAULT_WORKSPACE_ROOT, token: str | No
|
||||
)
|
||||
return to_jsonable(result)
|
||||
|
||||
@app.post("/api/repositories/tag")
|
||||
def repository_tag(request: RepositoryTagRequest) -> dict[str, object]:
|
||||
repos = tuple(dict.fromkeys(repo.strip() for repo in request.repos if repo.strip()))
|
||||
if not repos:
|
||||
raise HTTPException(status_code=400, detail="At least one repository must be selected")
|
||||
if request.apply and request.push and request.confirm != "PUBLISH":
|
||||
raise HTTPException(status_code=400, detail="Release tag publication requires confirm=PUBLISH")
|
||||
if request.apply and not request.push and request.confirm != "TAG":
|
||||
raise HTTPException(status_code=400, detail="Release tag creation requires confirm=TAG")
|
||||
result = tag_repositories(
|
||||
repos=repos,
|
||||
repo_versions=request.repo_versions,
|
||||
message=request.message,
|
||||
workspace_root=app.state.workspace_root,
|
||||
remote=request.remote,
|
||||
apply=request.apply,
|
||||
push=request.push,
|
||||
)
|
||||
return to_jsonable(result)
|
||||
|
||||
return app
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user