###############################################################################
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(
"""
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)