98 lines
3.1 KiB
Python
98 lines
3.1 KiB
Python
"""Bitbucket webhook handler"""
|
|
|
|
from fastapi import HTTPException
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
from sqlalchemy import select
|
|
|
|
from app.models import Repository, PullRequest, Review
|
|
from app.models.pull_request import PRStatusEnum
|
|
from app.models.review import ReviewStatusEnum
|
|
from app.schemas.webhook import BitbucketWebhook
|
|
|
|
|
|
async def handle_bitbucket_webhook(
|
|
webhook_data: BitbucketWebhook,
|
|
db: AsyncSession
|
|
) -> dict:
|
|
"""Handle Bitbucket webhook"""
|
|
|
|
# Find repository by URL
|
|
repo_url = webhook_data.repository.get("links", {}).get("html", {}).get("href", "")
|
|
result = await db.execute(
|
|
select(Repository).where(Repository.url == repo_url)
|
|
)
|
|
repository = result.scalar_one_or_none()
|
|
|
|
if not repository:
|
|
raise HTTPException(status_code=404, detail="Repository not found")
|
|
|
|
# Check if repository is active
|
|
if not repository.is_active:
|
|
return {"message": "Repository is not active"}
|
|
|
|
# Get PR state
|
|
pr_state = webhook_data.pullrequest.state.lower()
|
|
|
|
# Handle PR events
|
|
if pr_state in ["open", "opened"]:
|
|
# Create or update PR
|
|
result = await db.execute(
|
|
select(PullRequest).where(
|
|
PullRequest.repository_id == repository.id,
|
|
PullRequest.pr_number == webhook_data.pullrequest.id
|
|
)
|
|
)
|
|
pr = result.scalar_one_or_none()
|
|
|
|
if not pr:
|
|
pr = PullRequest(
|
|
repository_id=repository.id,
|
|
pr_number=webhook_data.pullrequest.id,
|
|
title=webhook_data.pullrequest.title,
|
|
author=webhook_data.pullrequest.author.get("display_name", ""),
|
|
source_branch=webhook_data.pullrequest.source.get("branch", {}).get("name", ""),
|
|
target_branch=webhook_data.pullrequest.destination.get("branch", {}).get("name", ""),
|
|
url=webhook_data.pullrequest.links.get("html", {}).get("href", ""),
|
|
status=PRStatusEnum.OPEN
|
|
)
|
|
db.add(pr)
|
|
await db.commit()
|
|
await db.refresh(pr)
|
|
else:
|
|
pr.title = webhook_data.pullrequest.title
|
|
pr.status = PRStatusEnum.OPEN
|
|
await db.commit()
|
|
|
|
# Create review
|
|
review = Review(
|
|
pull_request_id=pr.id,
|
|
status=ReviewStatusEnum.PENDING
|
|
)
|
|
db.add(review)
|
|
await db.commit()
|
|
await db.refresh(review)
|
|
|
|
return {
|
|
"message": "Review created",
|
|
"review_id": review.id,
|
|
"pr_id": pr.id
|
|
}
|
|
|
|
elif pr_state in ["closed", "merged", "declined"]:
|
|
# Mark PR as closed
|
|
result = await db.execute(
|
|
select(PullRequest).where(
|
|
PullRequest.repository_id == repository.id,
|
|
PullRequest.pr_number == webhook_data.pullrequest.id
|
|
)
|
|
)
|
|
pr = result.scalar_one_or_none()
|
|
if pr:
|
|
pr.status = PRStatusEnum.CLOSED
|
|
await db.commit()
|
|
|
|
return {"message": "PR closed"}
|
|
|
|
return {"message": "Event not handled"}
|
|
|