%% 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