From f0afb474bd0789647c1b10db5d74ed0a5c1e75e3 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 6 Jul 2026 19:18:39 +0000 Subject: [PATCH 1/3] Initial plan From 79db15e597b4f77a5b068948c04fd490aecc55ec Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 6 Jul 2026 19:28:15 +0000 Subject: [PATCH 2/3] fix: use commit SHA for autofix checkout to handle deleted PR branches MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The "Auto-fix (lint / format)" job in codeql.yml failed when the PR branch (chunk/add-docstrings-key-functions) was deleted before the workflow's checkout step ran. The job used the branch name as the checkout ref, which fails if the branch no longer exists. Fix: use PR_HEAD_SHA (commit SHA) for the checkout ref — the commit object persists even after branch deletion. Add a separate push_ref output (branch name) used only by the git push step, so the push still targets the correct branch when it exists. Also add a test to guard the new contract. --- .github/workflows/codeql.yml | 9 +++++++-- tests/test_codeql_workflow_paths_ignore.py | 17 +++++++++++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index b76203c74..fd1cf9453 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -324,6 +324,7 @@ jobs: env: EVENT_NAME: ${{ github.event_name }} PR_HEAD_REF: ${{ github.event.pull_request.head.ref }} + PR_HEAD_SHA: ${{ github.event.pull_request.head.sha }} PR_HEAD_REPO: ${{ github.event.pull_request.head.repo.full_name }} REPOSITORY: ${{ github.repository }} REF_NAME: ${{ github.ref_name }} @@ -331,7 +332,10 @@ jobs: set -euo pipefail { if [ "$EVENT_NAME" = "pull_request" ]; then - echo "ref=$PR_HEAD_REF" + # Use the commit SHA for checkout so the job succeeds even if the + # branch is deleted (e.g. auto-deleted after merge) before checkout runs. + echo "ref=$PR_HEAD_SHA" + echo "push_ref=$PR_HEAD_REF" echo "repo=$PR_HEAD_REPO" if [ "$PR_HEAD_REPO" = "$REPOSITORY" ]; then echo "can_push=true" @@ -340,6 +344,7 @@ jobs: fi else echo "ref=$REF_NAME" + echo "push_ref=$REF_NAME" echo "repo=$REPOSITORY" echo "can_push=false" fi @@ -491,7 +496,7 @@ jobs: git config user.email "41898282+github-actions[bot]@users.noreply.github.com" git add -A git commit -m "style: apply automated autofixes (ruff / prettier / clang-format) [CodeQL Advanced]" || echo "No commit created" - git push origin "HEAD:${{ steps.ref.outputs.ref }}" + git push origin "HEAD:${{ steps.ref.outputs.push_ref }}" - name: Produce patch artifact (fork PRs) if: steps.diff.outputs.changed == 'true' && github.event_name == 'pull_request' && steps.ref.outputs.can_push == 'false' diff --git a/tests/test_codeql_workflow_paths_ignore.py b/tests/test_codeql_workflow_paths_ignore.py index 86cfeb599..c68b93ad6 100644 --- a/tests/test_codeql_workflow_paths_ignore.py +++ b/tests/test_codeql_workflow_paths_ignore.py @@ -28,6 +28,23 @@ def test_codeql_autofix_ref_step_avoids_unbound_shell_vars() -> None: assert 'echo "can_push=$can_push_value"' not in content +@pytest.mark.unit +def test_codeql_autofix_uses_sha_for_checkout_and_branch_for_push() -> None: + """Verify the autofix job uses SHA for checkout (resilient to branch deletion) + and a separate push_ref for the git push step (uses branch name).""" + workflow_path = Path(__file__).resolve().parents[1] / ".github" / "workflows" / "codeql.yml" + content = workflow_path.read_text(encoding="utf-8") + + # The "Determine checkout ref" step must expose PR_HEAD_SHA for checkout + assert "PR_HEAD_SHA" in content, "PR_HEAD_SHA env var must be set in the ref step" + assert 'echo "ref=$PR_HEAD_SHA"' in content, "checkout ref must use SHA, not branch name" + assert 'echo "push_ref=$PR_HEAD_REF"' in content, "push_ref must preserve the branch name" + + # The push step must use push_ref (branch name), not ref (SHA) + assert 'steps.ref.outputs.push_ref' in content, "git push must target push_ref (branch name)" + assert 'HEAD:${{ steps.ref.outputs.push_ref }}' in content, "push must use push_ref" + + @pytest.mark.unit def test_codeql_autofix_excludes_workflow_files_from_formatting() -> None: repo_root = Path(__file__).resolve().parents[1] From 18aca9ca0a776cc1978991fc8390e5ce21c07dd1 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 6 Jul 2026 19:29:27 +0000 Subject: [PATCH 3/3] fix: add branch existence guard before push in autofix job If the PR branch is deleted between checkout and push (e.g. auto-deleted after merge), ls-remote now detects the missing ref and skips the push with a clear message instead of failing the step. Also update test to match new PUSH_REF env var pattern. --- .github/workflows/codeql.yml | 7 ++++++- tests/test_codeql_workflow_paths_ignore.py | 4 +++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index fd1cf9453..c4c6e3e4a 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -490,13 +490,18 @@ jobs: if: steps.diff.outputs.changed == 'true' && github.event_name == 'pull_request' && steps.ref.outputs.can_push == 'true' env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + PUSH_REF: ${{ steps.ref.outputs.push_ref }} run: | set -euo pipefail git config user.name "github-actions[bot]" git config user.email "41898282+github-actions[bot]@users.noreply.github.com" git add -A git commit -m "style: apply automated autofixes (ruff / prettier / clang-format) [CodeQL Advanced]" || echo "No commit created" - git push origin "HEAD:${{ steps.ref.outputs.push_ref }}" + if git ls-remote --exit-code origin "refs/heads/$PUSH_REF" >/dev/null 2>&1; then + git push origin "HEAD:$PUSH_REF" + else + echo "PR branch '$PUSH_REF' no longer exists on the remote; skipping push." + fi - name: Produce patch artifact (fork PRs) if: steps.diff.outputs.changed == 'true' && github.event_name == 'pull_request' && steps.ref.outputs.can_push == 'false' diff --git a/tests/test_codeql_workflow_paths_ignore.py b/tests/test_codeql_workflow_paths_ignore.py index c68b93ad6..88f1b0f35 100644 --- a/tests/test_codeql_workflow_paths_ignore.py +++ b/tests/test_codeql_workflow_paths_ignore.py @@ -42,7 +42,9 @@ def test_codeql_autofix_uses_sha_for_checkout_and_branch_for_push() -> None: # The push step must use push_ref (branch name), not ref (SHA) assert 'steps.ref.outputs.push_ref' in content, "git push must target push_ref (branch name)" - assert 'HEAD:${{ steps.ref.outputs.push_ref }}' in content, "push must use push_ref" + # push_ref is surfaced via PUSH_REF env var to keep shell script clean + assert 'PUSH_REF: ${{ steps.ref.outputs.push_ref }}' in content, "PUSH_REF env var must map push_ref" + assert 'HEAD:$PUSH_REF' in content, "push must use PUSH_REF env var (branch name)" @pytest.mark.unit