feat: initial commit — Billo Release Agent (LangGraph)

LangGraph-based release automation agent with:
- PR discovery (webhook + polling)
- AI code review via Claude Code CLI (subscription-based)
- Auto-create Jira tickets for PRs without ticket ID
- Jira ticket lifecycle management (code review -> staging -> done)
- CI/CD pipeline trigger, polling, and approval gates
- Slack interactive messages with approval buttons
- Per-repo semantic versioning
- PostgreSQL persistence (threads, staging, releases)
- FastAPI API (webhooks, approvals, status, manual triggers)
- Docker Compose deployment

1069 tests, 95%+ coverage.
This commit is contained in:
Yaojia Wang
2026-03-24 17:38:23 +01:00
commit f5c2733cfb
104 changed files with 19721 additions and 0 deletions

View File

@@ -0,0 +1,9 @@
{
"id": "approval-uuid-123",
"status": "approved",
"approver": {
"id": "user-uuid-456",
"displayName": "Release Bot"
},
"comments": "Approved via release agent"
}

View File

@@ -0,0 +1,9 @@
{
"id": 1001,
"buildNumber": "20240115.1",
"status": "completed",
"result": "succeeded",
"queueTime": "2024-01-15T10:00:00Z",
"startTime": "2024-01-15T10:01:00Z",
"finishTime": "2024-01-15T10:10:00Z"
}

View File

@@ -0,0 +1,8 @@
{
"pullRequestId": 99,
"title": "Release v1.2.0",
"status": "active",
"sourceRefName": "refs/heads/release/v1.2.0",
"targetRefName": "refs/heads/main",
"url": "https://dev.azure.com/my-org/my-project/_apis/git/repositories/my-repo/pullRequests/99"
}

View File

@@ -0,0 +1,8 @@
{
"pullRequestId": 42,
"status": "completed",
"title": "Fix the auth bug",
"completionOptions": {
"mergeStrategy": "squash"
}
}

View File

@@ -0,0 +1,15 @@
{
"value": [
{
"id": 10,
"name": "Release Pipeline",
"folder": "\\"
},
{
"id": 20,
"name": "Build Pipeline",
"folder": "\\"
}
],
"count": 2
}

View File

@@ -0,0 +1,16 @@
{
"pullRequestId": 42,
"title": "Fix the auth bug",
"status": "active",
"sourceRefName": "refs/heads/bug/ALLPOST-999_fix-auth",
"targetRefName": "refs/heads/main",
"url": "https://dev.azure.com/my-org/my-project/_apis/git/repositories/my-repo/pullRequests/42",
"repository": {
"id": "repo-uuid-123",
"name": "my-repo",
"remoteUrl": "https://dev.azure.com/my-org/my-project/_git/my-repo"
},
"lastMergeSourceCommit": {
"commitId": "abc123def456"
}
}

View File

@@ -0,0 +1,11 @@
diff --git a/src/auth.py b/src/auth.py
index 1234567..abcdefg 100644
--- a/src/auth.py
+++ b/src/auth.py
@@ -10,6 +10,10 @@ class AuthService:
def authenticate(self, token: str) -> bool:
- return token == "hardcoded"
+ return self._validate_token(token)
+
+ def _validate_token(self, token: str) -> bool:
+ return len(token) > 0 and token.startswith("Bearer ")

View File

@@ -0,0 +1,11 @@
{
"id": 1001,
"buildNumber": "20240115.1",
"status": "notStarted",
"queueTime": "2024-01-15T10:00:00Z",
"definition": {
"id": 10,
"name": "Release Pipeline"
},
"sourceBranch": "refs/heads/main"
}

View File

@@ -0,0 +1,10 @@
{
"id": "12345",
"key": "ALLPOST-100",
"fields": {
"summary": "Fix the authentication bug",
"status": {
"name": "In Progress"
}
}
}

View File

@@ -0,0 +1,20 @@
{
"transitions": [
{
"id": "11",
"name": "To Do"
},
{
"id": "21",
"name": "In Progress"
},
{
"id": "31",
"name": "Done"
},
{
"id": "41",
"name": "Released"
}
]
}