Repository navigation
fix(ci): pin auto-rebase checkout to the called workflow SHA #2654
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
seonghobae
wants to merge
1
commit into
main
Choose a base branch
from
ci/pin-auto-rebase-called-workflow-sha
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,66 @@ | ||
| """Supply-chain contract for the PR auto-rebase scheduler source checkout.""" | ||
|
|
||
| from __future__ import annotations | ||
|
|
||
| from pathlib import Path | ||
|
|
||
|
|
||
| _WORKFLOW = ( | ||
| Path(__file__).resolve().parents[1] | ||
| / ".github" | ||
| / "workflows" | ||
| / "pr-auto-rebase.yml" | ||
| ) | ||
|
|
||
|
|
||
| def _workflow_text() -> str: | ||
| """Read the auto-rebase workflow as UTF-8 text.""" | ||
| return _WORKFLOW.read_text(encoding="utf-8") | ||
|
|
||
|
|
||
| def test_auto_rebase_validates_called_workflow_sha_before_checkout() -> None: | ||
| """A floating branch tip must not be checked out before SHA validation.""" | ||
| workflow = _workflow_text() | ||
| guard = workflow.index("Resolve immutable called-workflow source") | ||
| checkout = workflow.index("Checkout immutable called-workflow source") | ||
|
|
||
| assert guard < checkout | ||
| assert "CALLER_REPOSITORY: ${{ github.repository }}" in workflow | ||
| assert "WORKFLOW_SHA: ${{ github.workflow_sha }}" in workflow | ||
| assert '[ "$CALLER_REPOSITORY" != "$expected_repository" ]' in workflow | ||
| assert 'expected_repository="ContextualWisdomLab/.github"' in workflow | ||
| assert 'expected_file=".github/workflows/pr-auto-rebase.yml"' in workflow | ||
| assert '[[ "$WORKFLOW_SHA" =~ ^[0-9a-f]{40}$ ]]' in workflow | ||
| assert "repository: ${{ steps.trusted_source.outputs.repository }}" in workflow | ||
| assert "ref: ${{ steps.trusted_source.outputs.sha }}" in workflow | ||
| assert "ref: main" not in workflow | ||
| assert "CANONICAL_REF: main" not in workflow | ||
| assert "ref: ${{ env.CANONICAL_REF }}" not in workflow | ||
| assert "ref: ${{ github.sha }}" not in workflow | ||
|
|
||
|
|
||
| def test_auto_rebase_verifies_checked_out_sha_matches_runtime_parameter() -> None: | ||
| """The commit that executes must equal the validated 40-character SHA.""" | ||
| workflow = _workflow_text() | ||
| verification = workflow.index("Verify immutable called-workflow checkout") | ||
| self_test = workflow.index("Self-test auto-rebase scheduler contract") | ||
|
|
||
| assert verification < self_test | ||
| assert 'actual_sha="$(git rev-parse HEAD)"' in workflow | ||
| assert '[ "$actual_sha" != "$EXPECTED_SHA" ]' in workflow | ||
| assert '[ ! -f "$EXPECTED_FILE" ] || [ -L "$EXPECTED_FILE" ]' in workflow | ||
|
|
||
|
|
||
| def test_auto_rebase_canonical_ref_input_cannot_select_source() -> None: | ||
| """Callers may still send canonical_ref, but it never selects the checkout.""" | ||
| workflow = _workflow_text() | ||
| declaration = workflow.split("canonical_ref:", 1)[1].split( | ||
| "repository_dispatch:", 1 | ||
| )[0] | ||
|
|
||
| assert "Deprecated compatibility input" in declaration | ||
| assert "ignored" in declaration | ||
| assert 'default: ""' in declaration | ||
| assert workflow.count("canonical_ref") == 1 | ||
| assert "inputs.canonical_ref" not in workflow | ||
| assert "github.event.client_payload.canonical_ref" not in workflow |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
호출 워크플로가 아닌 실행 중인 재사용 워크플로의 SHA를 사용하세요.
같은 저장소의 브랜치에서
@main의 재사용 워크플로를 호출하면github.workflow_sha는 호출자 워크플로의 커밋을 가리킵니다. 현재 코드는 그 커밋을 체크아웃합니다. 해당 커밋에 예상 파일이 있으면 이후 SHA 검사와 파일 검사도 통과합니다. 그 결과, 검증하려는 재사용 워크플로와 다른 버전의scripts/ci/pr_auto_rebase.py가 쓰기 자격 증명을 사용하는 단계에서 실행될 수 있습니다.job.workflow_sha를 사용하고job.workflow_repository와job.workflow_file_path도 예상 소스와 대조하세요. 테스트의 SHA 출처 단언도 함께 수정하세요. (docs.github.com)🤖 Prompt for AI Agents