diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index d12d1961b..7b098f4a1 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -492,6 +492,7 @@ 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]" diff --git a/tests/test_codeql_workflow_paths_ignore.py b/tests/test_codeql_workflow_paths_ignore.py index 86cfeb599..88f1b0f35 100644 --- a/tests/test_codeql_workflow_paths_ignore.py +++ b/tests/test_codeql_workflow_paths_ignore.py @@ -28,6 +28,25 @@ 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)" + # 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 def test_codeql_autofix_excludes_workflow_files_from_formatting() -> None: repo_root = Path(__file__).resolve().parents[1]