fix(opencode): bind coverage artifacts to workflow attempts - #812
fix(opencode): bind coverage artifacts to workflow attempts#812seonghobae wants to merge 58 commits into
Conversation
📝 WalkthroughWalkthrough커버리지 소스 아티팩트를 워크플로 실행 시도와 불변 ID로 연결했습니다. 현재 시도의 아티팩트가 없으면 이전 아티팩트를 사용하지 않고 재실행을 요구합니다. 새 CI는 정확한 소스와 품질 검사를 실행하며, 계약 테스트와 운영 문서를 추가했습니다. ChangesOpenCode 커버리지 아티팩트 재실행
Estimated code review effort: 3 (Moderate) | ~20 minutes Sequence Diagram(s)sequenceDiagram
participant Producer as coverage-source-tree
participant Artifacts as GitHub Actions artifact store
participant Consumer as coverage-evidence
participant Contract as rerun contract tests
Producer->>Artifacts: 실행 시도별 coverage source 업로드
Artifacts-->>Producer: immutable artifact-id 반환
Producer->>Consumer: coverage_source_artifact_id 전달
Consumer->>Artifacts: artifact-id로 source 다운로드
Artifacts-->>Consumer: 현재 시도 아티팩트 반환
Contract->>Consumer: 누락 아티팩트 및 credential-free 계약 검증
Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
|
Release blocker: current head @opencode-agent address Delete every trigger, materializer, repair, self-removing, encoded-patch, and branch-push workflow from the final tree. Implement the fix through ordinary reviewed commits directly in the authoritative central OpenCode workflow and permanent tests/docs/changelog only. The final contract must bind source evidence to the current workflow attempt without inventing a mutable fallback:
Preserve the permanent RED contract, then prove RED against protected main and GREEN after the ordinary source change. The final PR diff must contain no temporary workflow or trigger and must pass complete 100% production statement/branch/docstring coverage, compilation, all security/supply-chain checks, exact-head review, and independent approval. |
|
@jules Replace the temporary trigger/materializer/repair scope on exact live head Delete Implement only this exact contract in
Prove the permanent contract RED against the inherited source and GREEN after the direct repair. Run complete central tests, compilation, 100% production statement/branch/public-docstring evidence for any helper, actionlint/workflow syntax, every security and supply-chain gate, and |
seonghobae
left a comment
There was a problem hiding this comment.
Exact-head rerun-safety blocker on cae2d8f9e7c95e9044bb77468f6c1b132889a37b: the workflow binds the consumer to an immutable artifact-id, but it does not prove that the successful producer job actually ran in the current workflow attempt. GitHub explicitly supports failed-job-only and specific-job reruns while retaining the same workflow run identity, and run attempts are distinct. If upstream successful job outputs remain available to the rerun, coverage-evidence can receive the earlier producer's artifact ID; while the one-day artifact is still retained, that exact-ID download can succeed even though coverage-source-tree did not run in the current attempt. This contradicts this PR's stated contract that failed-jobs-only reruns must not reuse prior-attempt source evidence.
Fix test-first before merge. Add a permanent RED assertion that the producer records the literal attempt in a step output (for example coverage_source_run_attempt: ${{ steps.coverage_source_attempt.outputs.run_attempt }} where the step writes the current GITHUB_RUN_ATTEMPT), then make coverage-evidence compare that producer-attested value with its current ${{ github.run_attempt }} before artifact download and fail closed on empty or mismatched values with full-rerun/fresh-dispatch guidance. Keep the immutable artifact-ID download, one-day retention, and credential separation unchanged. Using a step-produced literal is important: a job output expression that directly re-evaluates github.run_attempt would not attest when the producer actually executed.
Also update doctoring/changelog to distinguish artifact immutability from current-attempt provenance and retain APA 7 primary-source references. GitHub's current rerun documentation confirms selective reruns and distinct attempts; actions/upload-artifact@v7 confirms artifact-id is immutable/unique but does not itself attest current-attempt execution.
|
@coderabbitai autofix Exact current head
|
|
The agent generated fixes only for
Lines 447–456 if: needs.coverage-source-tree.result != 'success'
run: |
echo "::error::Coverage source tree could not be materialized; see the coverage-source-tree job log for the exact target repository, base SHA, head SHA, and fetch or merge failure."
- exit 1
- name: Verify coverage source identity for current workflow attempt
id: coverage_source_identity
+ if: always()
continue-on-error: true
env:
COVERAGE_SOURCE_ARTIFACT_ID: ${{ needs.coverage-source-tree.outputs.coverage_source_artifact_id }}Lines 473–479 printf 'artifact_id=%s\n' "$artifact_id" >>"$GITHUB_OUTPUT"
- name: Download current-attempt materialized pull request merge tree
- if: steps.coverage_source_identity.outcome == 'success'
+ if: needs.coverage-source-tree.result == 'success' && steps.coverage_source_identity.outcome == 'success'
id: coverage_source_download
continue-on-error: true
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1Lines 482–488 path: ${{ runner.temp }}/opencode-coverage-artifact
- name: Report missing current-attempt coverage source
- if: steps.coverage_source_identity.outcome != 'success' || steps.coverage_source_download.outcome != 'success'
+ if: always() && (needs.coverage-source-tree.result != 'success' || steps.coverage_source_identity.outcome != 'success' || steps.coverage_source_download.outcome != 'success')
env:
GITHUB_RUN_ATTEMPT: ${{ github.run_attempt }}
run: | |
|
Implement the exact minimal workflow control-flow repair in comment |
|
/oc Refetch exact live head and abort unless it is |
|
/oc Fix only the fresh exact-head regression on First inspect the exact workflow step and intended recovery contract. Do not weaken fail-closed behavior merely to satisfy the assertion. If the current Use the observed CI failure as RED, then run the focused artifact-rerun contract to GREEN, full central suite with 100% statement/branch coverage, 100% public docstrings, compileall, and |
|
@opencode-agent Implement the minimal permanent GREEN repair directly on exact current head The exact-head quality failure is deterministic: run Modify only the existing permanent five-file slice as needed, with the production change limited to Required workflow behavior:
Run the focused contract first, then the complete exact-head quality suite, coverage, docstrings, compileall, |
|
/oc Refetch the live pull request and abort unless its exact head is |
|
@opencode-agent Repair exact current head In Preserve:
Run the focused five-test contract first, then the complete repository quality/security suite. Do not weaken the final fail-closed result, add a repair workflow, or open a stacked PR. |
|
/oc Refetch the exact live PR head and abort unless it is |
|
@opencode-agent address Fix exact head Implement the minimum canonical control-flow repair in
Run the five focused tests and complete exact-head suite. Do not create a temporary/self-modifying repair workflow or merely weaken the test. |
|
@opencode-agent Apply the minimal permanent GREEN repair directly on exact Draft head Current exact-head quality run Required behavior:
Keep Draft; do not approve, merge, release, alter reviewer credentials, or weaken branch protection. |
|
@coderabbitai autofix Apply only the existing exact-head blocker on |
|
The agent generated fixes only for
Lines 447–455 if: needs.coverage-source-tree.result != 'success'
run: |
echo "::error::Coverage source tree could not be materialized; see the coverage-source-tree job log for the exact target repository, base SHA, head SHA, and fetch or merge failure."
- exit 1
- name: Verify coverage source identity for current workflow attempt
+ if: always()
id: coverage_source_identity
continue-on-error: true
env:Lines 473–479 printf 'artifact_id=%s\n' "$artifact_id" >>"$GITHUB_OUTPUT"
- name: Download current-attempt materialized pull request merge tree
- if: steps.coverage_source_identity.outcome == 'success'
+ if: needs.coverage-source-tree.result == 'success' && steps.coverage_source_identity.outcome == 'success'
id: coverage_source_download
continue-on-error: true
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1Lines 482–488 path: ${{ runner.temp }}/opencode-coverage-artifact
- name: Report missing current-attempt coverage source
- if: steps.coverage_source_identity.outcome != 'success' || steps.coverage_source_download.outcome != 'success'
+ if: always() && (needs.coverage-source-tree.result != 'success' || steps.coverage_source_identity.outcome != 'success' || steps.coverage_source_download.outcome != 'success')
env:
GITHUB_RUN_ATTEMPT: ${{ github.run_attempt }}
run: | |
seonghobae
left a comment
There was a problem hiding this comment.
The exact-head quality contract has one blocking control-flow defect. Apply the inline minimal suggestion, rerun the focused five-test contract, then the complete current-head quality/security suite. Keep Draft until GREEN.
| @@ -433,12 +449,48 @@ jobs: | |||
| echo "::error::Coverage source tree could not be materialized; see the coverage-source-tree job log for the exact target repository, base SHA, head SHA, and fetch or merge failure." | |||
| exit 1 | |||
There was a problem hiding this comment.
This early termination prevents the later continue-on-error identity/download gates and the unified recovery step from emitting the required failed-jobs-only/full-rerun guidance. Keep this as a non-terminating diagnostic; the later Report missing current-attempt coverage source step remains the sole fail-closed exit.
| exit 1 | |
| # Continue to the unified current-attempt recovery gate for bounded fail-closed guidance. |
|
@coderabbitai autofix Apply the exact inline suggestion from review |
|
The agent generated fixes only for
Lines 447–456 if: needs.coverage-source-tree.result != 'success'
run: |
echo "::error::Coverage source tree could not be materialized; see the coverage-source-tree job log for the exact target repository, base SHA, head SHA, and fetch or merge failure."
- exit 1
- name: Verify coverage source identity for current workflow attempt
id: coverage_source_identity
+ if: always()
continue-on-error: true
env:
COVERAGE_SOURCE_ARTIFACT_ID: ${{ needs.coverage-source-tree.outputs.coverage_source_artifact_id }}Lines 473–479 printf 'artifact_id=%s\n' "$artifact_id" >>"$GITHUB_OUTPUT"
- name: Download current-attempt materialized pull request merge tree
- if: steps.coverage_source_identity.outcome == 'success'
+ if: needs.coverage-source-tree.result == 'success' && steps.coverage_source_identity.outcome == 'success'
id: coverage_source_download
continue-on-error: true
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1Lines 482–488 path: ${{ runner.temp }}/opencode-coverage-artifact
- name: Report missing current-attempt coverage source
- if: steps.coverage_source_identity.outcome != 'success' || steps.coverage_source_download.outcome != 'success'
+ if: always() && (needs.coverage-source-tree.result != 'success' || steps.coverage_source_identity.outcome != 'success' || steps.coverage_source_download.outcome != 'success')
env:
GITHUB_RUN_ATTEMPT: ${{ github.run_attempt }}
run: | |
|
Implement the existing RED contract directly on Modify only
Run the focused five-test contract, complete central suite with 100% branch coverage, production docstrings, compileall, and clean-tree checks. Keep Draft until the new exact head is green. |
|
@coderabbitai Please fix the deterministic exact-head failure directly on branch |
|
/oc Refetch PR #812 and repair only its live Draft head; abort on movement. The focused current-head contract proves producer-failure recovery is unreachable because |
|
@opencode-agent address Repair exact current head |
|
/oc Refetch the live head and continue only if it is |
|
Apply the sole remaining exact-head control-flow repair directly to In Strengthen |
seonghobae
left a comment
There was a problem hiding this comment.
The remaining exact-head contract also requires explicit always() aggregate conditions. Apply these three direct YAML suggestions together with removal of the earlier premature exit, then rerun the focused five-test contract.
|
|
||
| - name: Download materialized pull request merge tree | ||
| - name: Verify coverage source identity for current workflow attempt | ||
| id: coverage_source_identity |
There was a problem hiding this comment.
Identity validation must still run after a producer failure so it can produce a bounded, inspectable outcome for the unified recovery gate.
| id: coverage_source_identity | |
| if: always() | |
| id: coverage_source_identity |
| printf 'artifact_id=%s\n' "$artifact_id" >>"$GITHUB_OUTPUT" | ||
|
|
||
| - name: Download current-attempt materialized pull request merge tree | ||
| if: steps.coverage_source_identity.outcome == 'success' |
There was a problem hiding this comment.
Download must run only for a successful producer and successful current-attempt identity, while remaining evaluable under failed-job reruns.
| if: steps.coverage_source_identity.outcome == 'success' | |
| if: >- | |
| always() | |
| && needs.coverage-source-tree.result == 'success' | |
| && steps.coverage_source_identity.outcome == 'success' |
| path: ${{ runner.temp }}/opencode-coverage-artifact | ||
|
|
||
| - name: Report missing current-attempt coverage source | ||
| if: steps.coverage_source_identity.outcome != 'success' || steps.coverage_source_download.outcome != 'success' |
There was a problem hiding this comment.
Make the final recovery step authoritative for every producer, identity, or download failure.
| if: steps.coverage_source_identity.outcome != 'success' || steps.coverage_source_download.outcome != 'success' | |
| if: >- | |
| always() | |
| && ( | |
| needs.coverage-source-tree.result != 'success' | |
| || steps.coverage_source_identity.outcome != 'success' | |
| || steps.coverage_source_download.outcome != 'success' | |
| ) |
|
@coderabbitai autofix Apply every exact inline suggestion in reviews |
|
The agent generated fixes only for
Lines 447–455 if: needs.coverage-source-tree.result != 'success'
run: |
echo "::error::Coverage source tree could not be materialized; see the coverage-source-tree job log for the exact target repository, base SHA, head SHA, and fetch or merge failure."
- exit 1
- name: Verify coverage source identity for current workflow attempt
+ if: always()
id: coverage_source_identity
continue-on-error: true
env:Lines 473–479 printf 'artifact_id=%s\n' "$artifact_id" >>"$GITHUB_OUTPUT"
- name: Download current-attempt materialized pull request merge tree
- if: steps.coverage_source_identity.outcome == 'success'
+ if: needs.coverage-source-tree.result == 'success' && steps.coverage_source_identity.outcome == 'success'
id: coverage_source_download
continue-on-error: true
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1Lines 482–488 path: ${{ runner.temp }}/opencode-coverage-artifact
- name: Report missing current-attempt coverage source
- if: steps.coverage_source_identity.outcome != 'success' || steps.coverage_source_download.outcome != 'success'
+ if: always() && (needs.coverage-source-tree.result != 'success' || steps.coverage_source_identity.outcome != 'success' || steps.coverage_source_download.outcome != 'success')
env:
GITHUB_RUN_ATTEMPT: ${{ github.run_attempt }}
run: | |
|
/oc Continue from the exact current head. Verify the permanent coverage-artifact rerun control flow rather than trusting predecessor green runs. The early producer diagnostic must never terminate before recovery guidance; identity validation must run only after producer success and validate the current attempt plus a positive decimal artifact ID; download must require producer and identity success; the final missing-source report must use |
Incident and root cause
A failed-jobs-only rerun of central OpenCode run
31022108085forContextualWisdomLab/pg-llm-batch#53rerancoverage-evidencewithout rerunning the already-successfulcoverage-source-treeproducer. Its one-day source artifact had expired, so the consumer failed atactions/download-artifactbefore tests or docstrings ran.The previous static artifact name did not bind the consumer to one immutable upload. Extending retention would retain private source evidence longer and would not repair attempt identity.
Exact current state
2137012a2bf57b19a36f20ff6dcaac3e3e3b8cba;e71fdab2ab088001f218765ecb5e3b7fabfee11a;Permanent boundary already implemented
github.run_attempt;artifact-idand a producer-attested literal run attempt;coverage-evidenceremains limited toactions: read, with no repository-content token, OIDC credential, model secret, or write credential;Current RED evidence
Exact-head workflow run
31153864111, job92831560192, reports 1 failed, 4 passed intests/test_opencode_coverage_artifact_rerun_contract.py.The remaining defect is control flow after producer failure:
Report coverage source materialization failurestill exits immediately;always()-based aggregate conditions.Required GREEN repair
always()while retainingcontinue-on-errorand exact current-attempt/artifact-ID checks;always(), producer success, and identity success;always()and fail when producer, identity, or download evidence is not successful;Permanent scope
.github/workflows/opencode-review-dispatch.yml.github/workflows/opencode-coverage-artifact-rerun-quality-ci.ymltests/test_opencode_coverage_artifact_rerun_contract.pydocs/doctoring/opencode-coverage-artifact-reruns.mdCHANGELOG.mdKeep Draft until the focused contract, complete central suite, 100% production branch/docstring evidence, compilation, exact-head security/supply-chain checks, automated review, qualifying independent non-author approval, zero actionable threads, and branch protection all succeed without bypass. Closes #811 only after protected merge.