%% Billo Release Agent - Full Flow
%% Two main graphs: PR Completed and Release
graph TD
subgraph ENTRY["Entry Points"]
WEBHOOK["POST /webhooks/azdo"]
POLLER["PR Poller (every 5 min)"]
MANUAL["POST /manual/pr/{id}"]
end
WEBHOOK --> PARSE
POLLER --> PARSE
MANUAL --> PARSE
subgraph PR_GRAPH["PR Completed Graph"]
PARSE["parse_webhook
Extract PR info, ticket ID"]
FETCH["fetch_pr_details
AzDo API: get PR status"]
PARSE --> FETCH
subgraph LOCAL_GIT["Local Git (when REPOS_BASE_DIR set)"]
GIT_FETCH["git fetch origin"]
GIT_CHECKOUT["git checkout PR-branch"]
GIT_PULL["git pull origin PR-branch"]
GIT_DIFF["git diff origin/develop...HEAD"]
GIT_FETCH --> GIT_CHECKOUT --> GIT_PULL --> GIT_DIFF
end
FETCH -- "active PR + local repo" --> GIT_FETCH
GIT_DIFF --> ROUTE
FETCH -- "no local repo" --> AZDO_DIFF["AzDo iteration API
(file list only)"]
AZDO_DIFF --> ROUTE
ROUTE{"route_after_fetch"}
FETCH -- "already merged" --> CALC_VER
ROUTE -- "active_no_ticket" --> AUTO_TICKET["auto_create_ticket
Claude CLI generates
Jira ticket content"]
AUTO_TICKET --> JIRA_CR
ROUTE -- "active_with_ticket" --> JIRA_CR["move_jira_code_review
Jira: Code Review status"]
JIRA_CR --> CODE_REVIEW["run_code_review
Claude Code CLI
(cwd = PR branch)"]
CODE_REVIEW --> RESTORE["restore_branch
git checkout develop"]
RESTORE --> EVAL{"evaluate_review"}
EVAL -- "approve" --> INTERRUPT_MERGE["interrupt_confirm_merge
Slack: Merge? / Cancel?"]
EVAL -- "request_changes" --> NOTIFY_RC["notify_request_changes
Slack notification"]
NOTIFY_RC --> END_RC((END))
INTERRUPT_MERGE --> MERGE["merge_pr_node
AzDo: complete PR"]
MERGE --> JIRA_STAGE["move_jira_ready_for_stage
Jira: Ready for Stage"]
JIRA_STAGE --> JIRA_LINK["add_jira_pr_link
Jira: add PR link"]
JIRA_LINK --> CALC_VER
CALC_VER["calculate_version
Semantic versioning"]
CALC_VER --> UPDATE_STAGING["update_staging
PostgreSQL: staging_releases"]
UPDATE_STAGING --> CI_TRIGGER["trigger_ci_build
AzDo: queue build"]
CI_TRIGGER --> CI_POLL["poll_ci_build
Poll until complete"]
CI_POLL --> CI_NOTIFY["notify_ci_result
Slack notification"]
CI_NOTIFY --> END_PR((END))
end
subgraph RELEASE_GRAPH["Release Graph"]
LOAD["load_staging
Load current staging release"]
LOAD --> INT_REL["interrupt_confirm_release
Slack: Create release? / Cancel?"]
INT_REL --> CREATE_PR["create_release_pr
AzDo: create release PR
develop -> main"]
CREATE_PR --> INT_MERGE_REL["interrupt_confirm_merge_release
Slack: Merge release? / Cancel?"]
INT_MERGE_REL --> MERGE_REL["merge_release_pr
AzDo: complete release PR"]
MERGE_REL --> CI_MAIN["trigger_ci_build_main
AzDo: queue build on main"]
CI_MAIN --> CI_POLL_MAIN["poll_ci_build_main
Poll until complete"]
CI_POLL_MAIN --> CI_ROUTE{"route_ci_result"}
CI_ROUTE -- "ci_failed" --> CI_FAIL["notify_ci_failure
Slack notification"]
CI_FAIL --> END_FAIL((END))
CI_ROUTE -- "ci_passed" --> CD_WAIT["wait_for_cd_release
Wait for CD pipeline"]
CD_WAIT --> POLL_APPROVALS["poll_release_approvals"]
POLL_APPROVALS --> APPROVAL_ROUTE{"route_approval_stage"}
APPROVAL_ROUTE -- "sandbox_pending" --> INT_SANDBOX["interrupt_sandbox_approval
Slack: Approve Sandbox? / Skip?"]
INT_SANDBOX --> EXEC_SANDBOX["execute_sandbox_approval
AzDo: approve stage"]
EXEC_SANDBOX --> POLL_APPROVALS
APPROVAL_ROUTE -- "prod_pending" --> INT_PROD["interrupt_prod_approval
Slack: Approve Prod? / Skip?"]
INT_PROD --> EXEC_PROD["execute_prod_approval
AzDo: approve stage"]
EXEC_PROD --> POLL_APPROVALS
APPROVAL_ROUTE -- "all_deployed" --> DONE["move_tickets_to_done
Jira: Done status"]
DONE --> SLACK_NOTIFY["send_release_notification
Slack: release notes"]
SLACK_NOTIFY --> ARCHIVE["archive_release
PostgreSQL: archived_releases"]
ARCHIVE --> END_REL((END))
end
MANUAL_REL["POST /manual/release"] --> LOAD
style ENTRY fill:#e8f4fd,stroke:#2196F3
style PR_GRAPH fill:#f9f9f9,stroke:#666
style RELEASE_GRAPH fill:#f9f9f9,stroke:#666
style LOCAL_GIT fill:#e8f5e9,stroke:#4CAF50
style INTERRUPT_MERGE fill:#fff3e0,stroke:#FF9800
style INT_REL fill:#fff3e0,stroke:#FF9800
style INT_MERGE_REL fill:#fff3e0,stroke:#FF9800
style INT_SANDBOX fill:#fff3e0,stroke:#FF9800
style INT_PROD fill:#fff3e0,stroke:#FF9800
style NOTIFY_RC fill:#ffebee,stroke:#f44336
style CI_FAIL fill:#ffebee,stroke:#f44336
style END_RC fill:#ccc,stroke:#666
style END_PR fill:#ccc,stroke:#666
style END_FAIL fill:#ccc,stroke:#666
style END_REL fill:#c8e6c9,stroke:#4CAF50