Skip to content

Move fork-PR credentialed CI off pull_request_target - #1044

Open
david-siqi-liu wants to merge 3 commits into
mainfrom
david/ci-fork-integration-approval
Open

david-siqi-liu wants to merge 3 commits into
mainfrom
david/ci-fork-integration-approval

Conversation

@david-siqi-liu

@david-siqi-liu david-siqi-liu commented Oct 8, 2026 •

Copy link
Copy Markdown
Collaborator

After this PR, no workflow uses pull_request_target. Fork PRs get credentialed CI when an org member (MEMBER or OWNER) comments a command on the PR. Every comment-triggered run uses the default branch's workflow definitions. Design doc (option B): https://docs.google.com/document/d/1v-6znVBCb8YfGxr12SBd80w3i9n4U0fMEYohyz9Aoyw/edit

Commands

Org members comment these on a PR:

  • /integration-test runs the full Integration workflow with secrets on the PR's current head commit.
  • /integration-test <sha> does the same, but only if the head is still <sha> (7 to 40 hex characters). If the fork pushed since, it refuses and replies with the new head.
  • /ug-review runs the UG rubric review.
  • /user-journey-check runs the user-journey gate. For in-repo PRs it also runs automatically, so the command is mostly for forks.

Each command posts a commit status and a comment with the run link on the PR. The statuses are Fork integration and User Journey Test Required. Each new push needs a new command. Anyone else who comments /integration-test gets a reply saying only org members can run integration tests.

Before and after

Live integration on fork PRs:

  • Before: every credentialed job skips, because fork PRs get no secrets on pull_request. That covers the E2E CUJs, workspace validation, and the smoke, full, and managed journeys.
  • After: a member reviews, then comments /integration-test or /integration-test <sha>. It runs integration.yml on the pinned commit with secrets.

Live integration on in-repo PRs:

  • Before: runs automatically.
  • After: unchanged. /integration-test also works as an on-demand rerun, and it never cancels the automatic run.

UG review:

  • Before: adding the ug-review label, via pull_request_target.
  • After: a member comments /ug-review. It still runs only default-branch code and never executes the PR.

User Journey Test Required:

  • Before: pull_request_target on every PR.
  • After: pull_request for in-repo PRs, and /user-journey-check for fork PRs. It still reads the PR only through the API.

pull_request_target:

  • Before: used by ug-review.yml and user-journey-test-required.yml.
  • After: not used anywhere, and a contract test fails if it comes back. No admin event-policy exception is needed before GitHub blocks it on public repos on 2026-11-02.

Fork safety in integration.yml

  • It takes an optional ref input. When the input is empty, existing callers behave exactly as before.
  • Every checkout pins ref and sets persist-credentials: false.
  • setup-uv skips its cache for ref-pinned runs, so fork builds cannot poison it.
  • Concurrency groups key on the PR number, so runs for different PRs never cancel each other. Concurrency is set per job, so ordinary PR comments never cancel a run.

Testing

OIDC note: under issue_comment, the OIDC subject is the default branch, not a PR ref. If the JFrog trust policy for the Windows installation lane keys on PR refs, that one lane fails on fork runs. The other lanes use secrets, not OIDC.

This pull request and its description were written by Isaac.

@david-siqi-liu
david-siqi-liu force-pushed the david/ci-fork-integration-approval branch 2 times, most recently from c21bf9a to aa4658a Compare October 8, 2026 15:23
Base automatically changed from david/ci-skip-windows-oidc-on-forks to main October 8, 2026 15:47
@david-siqi-liu
david-siqi-liu force-pushed the david/ci-fork-integration-approval branch from aa4658a to 30e828f Compare October 8, 2026 17:02
@david-siqi-liu david-siqi-liu changed the title Run credentialed integration tests on approved fork PRs Run credentialed integration on fork PRs via /integration-test Oct 8, 2026
@david-siqi-liu
david-siqi-liu force-pushed the david/ci-fork-integration-approval branch 2 times, most recently from ea0669a to ef6ad0d Compare October 8, 2026 17:20
@david-siqi-liu david-siqi-liu changed the title Run credentialed integration on fork PRs via /integration-test Move fork-PR credentialed CI off pull_request_target Oct 8, 2026
@david-siqi-liu
david-siqi-liu force-pushed the david/ci-fork-integration-approval branch 4 times, most recently from 47bbbf4 to e76dce1 Compare October 8, 2026 20:16
Fork PRs get no secrets on pull_request, so every credentialed integration
job skips for them, and GitHub is closing the pull_request_target route
(default-branch-only workflows, the checkout fork guard, and the default
block in public repos from 2026-11-02).

Following dbt-databricks, an org member comments /integration-test after
reviewing a PR. An issue_comment workflow from the default branch runs
integration.yml on the PR head with secrets and posts a Fork integration
status and comment. /integration-test <sha> runs only if the head is still
the reviewed commit. Non-members get a reply saying only org members can
run it, and in-repo PRs can use it as an on-demand rerun. integration.yml
takes the commit as a ref input, pins every checkout to it without
persisted credentials, skips the uv cache for these runs, and keys its
concurrency group per PR for comment events.

ug-review.yml moves to an org member /ug-review comment.
user-journey-test-required.yml runs on pull_request for in-repo PRs and on
an org member /user-journey-check comment for fork PRs, reporting a commit
status back. No workflow uses pull_request_target any more.

Co-authored-by: Isaac <no-reply@databricks.com>
@david-siqi-liu
david-siqi-liu force-pushed the david/ci-fork-integration-approval branch from e76dce1 to 978df65 Compare October 9, 2026 17:13
david-siqi-liu and others added 2 commits October 9, 2026 18:21
The managed-opencode job landed on main (#896) after this branch was cut, so it
lacked the pinned, credential-free checkout and the disabled uv cache that fork
runs require.

Co-authored-by: Isaac <no-reply@databricks.com>
The authorize step is bash that only runs on ubuntu-latest, and its fake `gh`
shim cannot execute on the Windows unit-test runner.

Co-authored-by: Isaac <no-reply@databricks.com>
@david-siqi-liu
david-siqi-liu marked this pull request as ready for review October 9, 2026 19:12

@rohita5l rohita5l left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed the CI trigger changes. Please address the inline P1 concerning journey-check results being attached to a different revision than the one evaluated. Focused verification: 91 tests passed; live comment-triggered workflows were not exercised.

RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
run: |
set -euo pipefail
sha=$(gh api "repos/$GITHUB_REPOSITORY/pulls/$PR_NUMBER" --jq .head.sha)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P1] Bind the journey-check status to the revision actually evaluated.

The gate reads the PR diff before invoking the judge, but this reporting step fetches the current head SHA again after evaluation. If another commit is pushed during the check, a successful verdict for the previous revision is posted to the new, unchecked commit. For fork PRs, the synchronize-triggered gate is skipped, so that push does not cancel this comment-triggered evaluation.

Capture and expose the evaluated SHA, verify the PR revision remains unchanged across the diff reads, and post the result only against that SHA rather than refetching the current head here. Please add coverage for a head change between evaluation and reporting.

@max-rozen-oss-db max-rozen-oss-db left a comment •

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you put something in our AGENTS.md/CLAUDE.md that certain workflows need to run on pull_request not pull_request_target?

Personally I prefer to can trigger CI with a label (less clutter than comments), would be nice to have both options

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants