From bf7a98ea9e0b5bc3b1d351b29b703211f72f02ea Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Mon, 28 Sep 2026 04:08:42 +0900 Subject: [PATCH] fix(ci): isolate coverage checkout by run attempt --- .github/workflows/opencode-review-dispatch.yml | 12 ++++++------ tests/test_opencode_agent_contract.py | 8 +++++++- tests/test_pr_review_autofix_nvidia_nim_contract.py | 2 +- 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/.github/workflows/opencode-review-dispatch.yml b/.github/workflows/opencode-review-dispatch.yml index a74d6eaf1a..0ac2ec1fd6 100644 --- a/.github/workflows/opencode-review-dispatch.yml +++ b/.github/workflows/opencode-review-dispatch.yml @@ -479,11 +479,11 @@ jobs: - name: Prepare pull request merge tree for coverage measurement env: COVERAGE_SOURCE_ARCHIVE: ${{ runner.temp }}/opencode-coverage-artifact/opencode-coverage-source.tar - COVERAGE_SOURCE_WORKDIR: ${{ runner.temp }}/pr-head + COVERAGE_SOURCE_WORKDIR: ${{ runner.temp }}/opencode-coverage-${{ github.run_id }}-${{ github.run_attempt }} run: | set -euo pipefail - rm -rf "$COVERAGE_SOURCE_WORKDIR" - mkdir -p "$COVERAGE_SOURCE_WORKDIR" + # Each attempt owns a fresh tree; never delete another job's checkout. + mkdir "$COVERAGE_SOURCE_WORKDIR" # The archive contains pull-request-controlled paths. Validate every # member before extraction so a symlink, hardlink, device, FIFO, or # traversal path cannot redirect a later trusted host-side parser. @@ -533,7 +533,7 @@ jobs: env: PR_BASE_SHA: ${{ needs.validate-pr-metadata.outputs.base_sha }} PR_HEAD_SHA: ${{ needs.validate-pr-metadata.outputs.head_sha }} - COVERAGE_SOURCE_WORKDIR: ${{ runner.temp }}/pr-head + COVERAGE_SOURCE_WORKDIR: ${{ runner.temp }}/opencode-coverage-${{ github.run_id }}-${{ github.run_attempt }} # Dependency resolution may consume wheels/packages, but PR-defined # install/build hooks are never executed implicitly. UV_NO_BUILD: "1" @@ -568,7 +568,7 @@ jobs: - name: Enforce changed-file syntax gate env: PR_BASE_SHA: ${{ needs.validate-pr-metadata.outputs.base_sha }} - COVERAGE_SOURCE_WORKDIR: ${{ runner.temp }}/pr-head + COVERAGE_SOURCE_WORKDIR: ${{ runner.temp }}/opencode-coverage-${{ github.run_id }}-${{ github.run_attempt }} run: | set -euo pipefail # Deterministic per-file syntax check on the PR's changed files. The @@ -600,7 +600,7 @@ jobs: env: PR_BASE_SHA: ${{ needs.validate-pr-metadata.outputs.base_sha }} PR_HEAD_SHA: ${{ needs.validate-pr-metadata.outputs.head_sha }} - COVERAGE_SOURCE_WORKDIR: ${{ runner.temp }}/pr-head + COVERAGE_SOURCE_WORKDIR: ${{ runner.temp }}/opencode-coverage-${{ github.run_id }}-${{ github.run_attempt }} # Apply wheel-only resolution in the same step that consumes # pull-request dependency metadata. A value on an earlier step does # not cross the GitHub Actions step boundary. diff --git a/tests/test_opencode_agent_contract.py b/tests/test_opencode_agent_contract.py index 5cbc0a8cb4..df17a35688 100644 --- a/tests/test_opencode_agent_contract.py +++ b/tests/test_opencode_agent_contract.py @@ -568,7 +568,13 @@ def test_opencode_target_coverage_materializes_only_after_authorized_dispatch(): assert "GH_TOKEN:" not in measure_step assert "ACTIONS_RUNTIME_TOKEN GH_TOKEN GITHUB_TOKEN" in measure_step assert "secrets." not in measure_step - assert "COVERAGE_SOURCE_WORKDIR: ${{ runner.temp }}/pr-head" in workflow + assert ( + "COVERAGE_SOURCE_WORKDIR: ${{ runner.temp }}/opencode-coverage-" + "${{ github.run_id }}-${{ github.run_attempt }}" in workflow + ) + prepare = workflow.split(" - name: Prepare pull request merge tree for coverage measurement", 1)[1].split(" - name:", 1)[0] + assert 'mkdir "$COVERAGE_SOURCE_WORKDIR"' in prepare + assert 'rm -rf "$COVERAGE_SOURCE_WORKDIR"' not in prepare assert ( 'python3 -I - "$COVERAGE_SOURCE_ARCHIVE" "$COVERAGE_SOURCE_WORKDIR"' in workflow ) diff --git a/tests/test_pr_review_autofix_nvidia_nim_contract.py b/tests/test_pr_review_autofix_nvidia_nim_contract.py index e6ddc239d7..4709af94f1 100644 --- a/tests/test_pr_review_autofix_nvidia_nim_contract.py +++ b/tests/test_pr_review_autofix_nvidia_nim_contract.py @@ -17,7 +17,7 @@ DOCTORING_RECORD = Path("docs/doctoring/hourly-nvidia-nim-autofix.md") CHANGELOG = Path("CHANGELOG.md") REVIEW_DISPATCH_WORKFLOW = Path(".github/workflows/opencode-review-dispatch.yml") -REVIEW_DISPATCH_BLOB_SHA = "a74d6eaf1a6c998b59d7db152cbb173bdfba7bf8" +REVIEW_DISPATCH_BLOB_SHA = "0ac2ec1fd69e60b228ac30b0b797403988d1a7ce" def _workflow_text(path: Path) -> str: