Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 72 additions & 0 deletions .github/workflows/opencode-review.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4518,6 +4518,73 @@ jobs:
return 0
}

approve_previously_reviewed_merge_update_after_model_exhaustion() {
local parents first_parent second_parent reviews_json approved_parent_count body

if [ -z "${OPENCODE_SOURCE_WORKDIR:-}" ] || [ ! -d "$OPENCODE_SOURCE_WORKDIR/.git" ]; then
return 1
fi
if ! parents="$(git -C "$OPENCODE_SOURCE_WORKDIR" show -s --format='%P' "$HEAD_SHA" 2>/dev/null)"; then
return 1
fi
# shellcheck disable=SC2086
set -- $parents
if [ "$#" -ne 2 ]; then
return 1
fi
first_parent="$1"
second_parent="$2"

if [ -z "${PR_BASE_SHA:-}" ]; then
return 1
fi
if [ "$second_parent" != "$PR_BASE_SHA" ]; then
if ! git -C "$OPENCODE_SOURCE_WORKDIR" merge-base --is-ancestor "$second_parent" "$PR_BASE_SHA" 2>/dev/null; then
return 1
fi
fi

if ! reviews_json="$(gh api -X GET "repos/${GH_REPOSITORY}/pulls/${PR_NUMBER}/reviews" --paginate | jq -s 'add')"; then
return 1
fi
approved_parent_count="$(
jq -r --arg sha "$first_parent" '
[
.[]
| select(.commit_id == $sha)
| select(.user.login == "opencode-agent[bot]" or .user.login == "opencode-agent")
| select(.state == "APPROVED")
]
Comment thread
seonghobae marked this conversation as resolved.
| length
' <<<"$reviews_json"
)"
if [ "${approved_parent_count:-0}" -lt 1 ]; then
return 1
fi

body="$(printf '%s\n' \
"## Pull request overview" \
"" \
"OpenCode 모델 풀이 현재 merge-update head에서 usable control block을 만들지 못했지만, 중앙 리뷰 게이트가 이전 승인과 현재 head evidence를 함께 확인했습니다." \
"" \
"## Approval evidence" \
"" \
"- Result: APPROVE" \
"- Reason: 현재 head는 이미 OpenCode가 승인한 PR parent \`${first_parent}\`와 base parent \`${second_parent}\`를 결합한 2-parent merge update입니다." \
"- Prior review: OpenCode approval exists on first parent \`${first_parent}\`." \
"- Base evidence: second parent is the current base SHA or an ancestor of it." \
"- Peer GitHub Checks: completed without failures before this fallback approval." \
"- Human review threads: unresolved blocking threads were not present." \
"- Model outcome: model_pool=${OPENCODE_MODEL_POOL_OUTCOME:-unknown}; selected_model=${OPENCODE_MODEL_POOL_MODEL:-none}." \
"- Head SHA: \`${HEAD_SHA}\`" \
"- Workflow run: ${RUN_ID}" \
"- Workflow attempt: ${RUN_ATTEMPT}" \
"" \
"이 fallback은 이미 승인된 PR head를 최신 base에 병합한 merge-update commit에만 적용됩니다. 이전 승인 없는 source changes, single-parent commits, stale base parents, failed checks, unresolved human threads에는 적용되지 않습니다.")"
create_pull_review "APPROVE" "$body"
return 0
}

request_changes_for_merge_conflict_if_present() {
local pr_json merge_state mergeable base_ref head_ref body change_graph

Expand Down Expand Up @@ -4690,6 +4757,11 @@ jobs:
exit 0
fi

if approve_previously_reviewed_merge_update_after_model_exhaustion; then
echo "::endgroup::"
exit 0
fi

request_changes_after_model_exhaustion \
"$pending_checks_file" \
"$failed_checks_file" \
Expand Down
6 changes: 6 additions & 0 deletions tests/test_opencode_agent_contract.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,12 @@ def test_workflow_provisions_sandbox_tool_and_reviewer_agent():
assert "changed_file_is_low_risk_review_fallback" in workflow
assert "production source 또는 package manifest 변경이 없습니다" in workflow
assert "Source, workflow, config, package, migration, generated artifact 변경은 모델 기반 review 없이 승인하지 않습니다" in workflow
assert "approve_previously_reviewed_merge_update_after_model_exhaustion" in workflow
assert "2-parent merge update" in workflow
assert "Prior review: OpenCode approval exists on first parent" in workflow
assert 'reviews" --paginate | jq -s' in workflow
assert 'select(.state == "APPROVED")' in workflow
assert "이 fallback은 이미 승인된 PR head를 최신 base에 병합한 merge-update commit에만 적용됩니다" in workflow
assert 'timeout-minutes: 310' in workflow
assert 'OPENCODE_MODEL_ATTEMPTS: "3"' in workflow
assert 'OPENCODE_RUN_TIMEOUT_SECONDS: "900"' in workflow
Expand Down
Loading