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
This commit is contained in:
114
docs/flow.mermaid
Normal file
114
docs/flow.mermaid
Normal file
@@ -0,0 +1,114 @@
|
||||
%% 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
|
||||
Reference in New Issue
Block a user