From: Michael Tremer Date: Tue, 15 Jul 2025 11:09:26 +0000 (+0000) Subject: api: builds: Add endpoints to fetch bugs and finish a build X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7302e71e16225b1fdd28bf9b1ac15bae694114cb;p=pbs.git api: builds: Add endpoints to fetch bugs and finish a build Signed-off-by: Michael Tremer --- diff --git a/src/api/builds.py b/src/api/builds.py index 3e7194cd..dd7a265a 100644 --- a/src/api/builds.py +++ b/src/api/builds.py @@ -19,15 +19,21 @@ ############################################################################### import fastapi +import pydantic from uuid import UUID from . import apiv1 +from . import auth from . import backend # Import types +from ..bugtracker import Bug from ..builds import Build +from ..users import User +# Import errors +from ..errors import NoSuchDistroError # Create a new router for all builds endpoints router = fastapi.APIRouter( @@ -39,15 +45,89 @@ async def get_build_by_uuid(uuid: UUID) -> Build | None: """ Fetches a build by its UUID """ - return await backend.builds.get_by_uuid(uuid) + build = await backend.builds.get_by_uuid(uuid) -@router.get("/{uuid}") -async def get(build: Build = fastapi.Depends(get_build_by_uuid)) -> Build: # Raise 404 if the build could not be found if not build: raise fastapi.HTTPException(404, "Build not found") return build +class CreateBuildRequest(pydantic.BaseModel): + # Upload + upload: UUID + + # Repository + repo: str | None = None + + # Architectures + arches: list[str] = [] + + # Disable test builds? + disable_test_builds: bool = False + +@router.post("") +async def post( + request: CreateBuildRequest, current_user: User = fastapi.Depends(auth.get_current_user), + ) -> Build: + """ + Creates a new (scratch) build + """ + # Fetch the upload + upload = await backend.uploads.get_by_uuid(request.upload) + if not upload: + raise fastapi.HTTPException(422, "Could not find upload %s" % request.upload) + + # Check if the user has permissions + if not upload.has_perm(current_user): + raise fastapi.HTTPException(403, "Permission denied to access the upload") + + async with backend.db as session: + # Import the package + try: + package = await backend.packages.create(upload) + + # Fail if no matching distribution + except NoSuchDistroError as e: + raise fastapi.HTTPException(422, "Could not find distro: %s" % e) from e + + try: + # Fetch the repo + # XXX DUMMY + repo = await current_user.get_repo(package.distro, None) + assert repo, "NO REPO" + + # Create a new build + build = await backend.builds.create( + repo, package, owner=current_user, disable_test_builds=request.disable_test_builds, + ) + + # If anything went wrong, we will delete the package + except Exception as e: + await package.delete(current_user) + + raise e + + # Delete the upload + await upload.delete() + + # XXX Launch the build (should be a background task) + + + return build + +@router.get("/{uuid}") +async def get(build: Build = fastapi.Depends(get_build_by_uuid)) -> Build: + return build + +# +# Bugs +# + +@router.get("/{uuid}/bugs") +async def get_bugs(build: Build = fastapi.Depends(get_build_by_uuid)) -> list[Bug]: + # Return all bugs + return await build.get_bugs() + # Add everything to the APIv1 apiv1.include_router(router)