Files
billo-release-agent/docs/flow.mermaid
Yaojia Wang dee48dca2b feat: local git checkout for PR code review with real diff
- Add git_local.py: fetch, checkout PR branch, generate git diff against
  target, restore branch after review
- Update fetch_pr_details to use local git diff when REPOS_BASE_DIR is set,
  with fallback to AzDo iteration API
- Update run_code_review to restore repo to target branch after review
- Refine Claude review prompt to only comment on diff changes, not
  pre-existing code
- Update README: WSL venv gotcha, local git checkout flow, flow diagram
2026-03-25 20:45:33 +01:00

115 lines
5.0 KiB
Plaintext

%% 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<br/>Extract PR info, ticket ID"]
FETCH["fetch_pr_details<br/>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<br/>(file list only)"]
AZDO_DIFF --> ROUTE
ROUTE{"route_after_fetch"}
FETCH -- "already merged" --> CALC_VER
ROUTE -- "active_no_ticket" --> AUTO_TICKET["auto_create_ticket<br/>Claude CLI generates<br/>Jira ticket content"]
AUTO_TICKET --> JIRA_CR
ROUTE -- "active_with_ticket" --> JIRA_CR["move_jira_code_review<br/>Jira: Code Review status"]
JIRA_CR --> CODE_REVIEW["run_code_review<br/>Claude Code CLI<br/>(cwd = PR branch)"]
CODE_REVIEW --> RESTORE["restore_branch<br/>git checkout develop"]
RESTORE --> EVAL{"evaluate_review"}
EVAL -- "approve" --> INTERRUPT_MERGE["interrupt_confirm_merge<br/>Slack: Merge? / Cancel?"]
EVAL -- "request_changes" --> NOTIFY_RC["notify_request_changes<br/>Slack notification"]
NOTIFY_RC --> END_RC((END))
INTERRUPT_MERGE --> MERGE["merge_pr_node<br/>AzDo: complete PR"]
MERGE --> JIRA_STAGE["move_jira_ready_for_stage<br/>Jira: Ready for Stage"]
JIRA_STAGE --> JIRA_LINK["add_jira_pr_link<br/>Jira: add PR link"]
JIRA_LINK --> CALC_VER
CALC_VER["calculate_version<br/>Semantic versioning"]
CALC_VER --> UPDATE_STAGING["update_staging<br/>PostgreSQL: staging_releases"]
UPDATE_STAGING --> CI_TRIGGER["trigger_ci_build<br/>AzDo: queue build"]
CI_TRIGGER --> CI_POLL["poll_ci_build<br/>Poll until complete"]
CI_POLL --> CI_NOTIFY["notify_ci_result<br/>Slack notification"]
CI_NOTIFY --> END_PR((END))
end
subgraph RELEASE_GRAPH["Release Graph"]
LOAD["load_staging<br/>Load current staging release"]
LOAD --> INT_REL["interrupt_confirm_release<br/>Slack: Create release? / Cancel?"]
INT_REL --> CREATE_PR["create_release_pr<br/>AzDo: create release PR<br/>develop -> main"]
CREATE_PR --> INT_MERGE_REL["interrupt_confirm_merge_release<br/>Slack: Merge release? / Cancel?"]
INT_MERGE_REL --> MERGE_REL["merge_release_pr<br/>AzDo: complete release PR"]
MERGE_REL --> CI_MAIN["trigger_ci_build_main<br/>AzDo: queue build on main"]
CI_MAIN --> CI_POLL_MAIN["poll_ci_build_main<br/>Poll until complete"]
CI_POLL_MAIN --> CI_ROUTE{"route_ci_result"}
CI_ROUTE -- "ci_failed" --> CI_FAIL["notify_ci_failure<br/>Slack notification"]
CI_FAIL --> END_FAIL((END))
CI_ROUTE -- "ci_passed" --> CD_WAIT["wait_for_cd_release<br/>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<br/>Slack: Approve Sandbox? / Skip?"]
INT_SANDBOX --> EXEC_SANDBOX["execute_sandbox_approval<br/>AzDo: approve stage"]
EXEC_SANDBOX --> POLL_APPROVALS
APPROVAL_ROUTE -- "prod_pending" --> INT_PROD["interrupt_prod_approval<br/>Slack: Approve Prod? / Skip?"]
INT_PROD --> EXEC_PROD["execute_prod_approval<br/>AzDo: approve stage"]
EXEC_PROD --> POLL_APPROVALS
APPROVAL_ROUTE -- "all_deployed" --> DONE["move_tickets_to_done<br/>Jira: Done status"]
DONE --> SLACK_NOTIFY["send_release_notification<br/>Slack: release notes"]
SLACK_NOTIFY --> ARCHIVE["archive_release<br/>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