[CI] Run CI on external fork PRs via approved-for-ci-run label - #458
elenagaljak-db wants to merge 1 commit into
Conversation
Signed-off-by: elenagaljak-db <elena.galjak@databricks.com>
125cd0b to
7e6aa99
Compare
|
|
||
| - run: gh pr --repo "${GITHUB_REPOSITORY}" edit "${PR_NUMBER}" --remove-label "approved-for-ci-run" | ||
|
|
||
| - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 |
There was a problem hiding this comment.
This depth-one checkout breaks when a fork is more than one unique commit ahead of main. The base repository does not have the fork-only parent commits, and the shallow checkout cannot supply them when pushing ci-run/pr-N, so the remote rejects the push.
Could we fetch the approved SHA's full ancestry before pushing?
with:
fetch-depth: 0| # For `git push` and `gh pr create` we use CI_ACCESS_TOKEN | ||
|
|
||
|
|
||
| if: | |
There was a problem hiding this comment.
This condition accepts any label event while approved-for-ci-run remains present, and it also accepts same-repository PRs that do not need mirroring. If the collaborator lookup fails, bash -e exits before the label is removed, so a later unrelated label can replay the job.
Could we restrict the job to the exact approval label on a fork PR?
if: |
github.event.action == 'labeled' &&
github.event.label.name == 'approved-for-ci-run' &&
github.event.pull_request.head.repo.full_name != github.repositoryIt would also be good to treat a failed permission lookup as denial and consume approved-for-ci-run in a separate step with if: always(), so every approval attempt removes the label.
| steps: | ||
| - name: Close CI-run PR and delete the `ci-run/pr-${{ env.PR_NUMBER }}` branch | ||
| run: | | ||
| CLOSED="$(gh pr --repo "${GITHUB_REPOSITORY}" list --head "${BRANCH}" --json 'closed' --jq '.[].closed')" |
There was a problem hiding this comment.
Cleanup only deletes the branch while closing an open mirror PR. If the push succeeds but PR creation fails, or the mirror PR was already closed without deleting its branch, ci-run/pr-N remains in the repository.
Could we close any open mirror and then delete the ref independently?
gh pr list --state open --head "$BRANCH" --json number --jq '.[].number' |
while read -r number; do
gh pr close "$number"
done
gh api --method DELETE "repos/$GITHUB_REPOSITORY/git/refs/heads/$BRANCH" || trueThe existing job-scoped GITHUB_TOKEN has contents: write, so this does not need another App token.
| labels: linux-ubuntu-latest | ||
|
|
||
| steps: | ||
| - name: Generate a GitHub App installation token |
There was a problem hiding this comment.
The App is already scoped correctly, but neither this token request nor the PR description records the complete boundary. Could we request only Contents: write and Pull requests: write, switch from the deprecated app-id input to client-id, and document that the App is installed only on databricks/zerobus-sdk with no Workflows: write permission?
with:
client-id: ${{ secrets.CI_APP_CLIENT_ID }}
private-key: ${{ secrets.CI_APP_PRIVATE_KEY }}
permission-contents: write
permission-pull-requests: writeThe missing workflow permission means external PRs that change .github/workflows/** cannot use this mirror path. It would be good to document the alternate process for testing those contributions as well.
| # Create local PR for an `approved-for-ci-run` labelled PR to run CI pipeline in it. | ||
|
|
||
| permissions: | ||
| pull-requests: write # for `gh pr edit` |
There was a problem hiding this comment.
Could we remove the trailing whitespace here and update the following comment to say GitHub App token instead of CI_ACCESS_TOKEN?
| env: | ||
| GH_TOKEN: ${{ steps.app-token.outputs.token }} | ||
| run: | | ||
| cat << EOF > body.md |
There was a problem hiding this comment.
body.md is created inside the fork worktree, so a committed symlink at that path can redirect this fixed-content write and fail the run. Could we pass the body directly to gh pr create and include the immutable approved SHA for auditability?
env:
APPROVED_SHA: ${{ github.event.pull_request.head.sha }}
run: |
gh pr create \
--body "CI run for PR #$PR_NUMBER. Approved SHA: $APPROVED_SHA" \
--head "$BRANCH" \
--base main \
--draft
What changes are proposed in this pull request?
Fork PRs can't run CI: GitHub denies them the OIDC token, so the JFrog auth step fails (ACTIONS_ID_TOKEN_REQUEST_TOKEN unbound).
This adds a pull_request_target workflow: a maintainer (write access)reviews the fork code and adds the
approved-for-ci-runlabel, whichmirrors the PR into an internalci-run/pr-<N>branch + PR. As a same-repo PR it gets OIDC, so JFrog auth and full CI run normally.The label is auto-removed so each push needs re-approval.
Requires:
approved-for-ci-runlabel,CI_APP_ID+CI_APP_PRIVATE_KEYsecrets, and PR-write on the CI GitHub App.How is this tested?