Enable external pull request pipelines to run for forks

Problem to solve

In https://gitlab.com/gitlab-org/gitlab-ce/issues/65139 we enable create pipelines for external pull requests when a GitHub repository is used with GitLab CI/CD. The merge request addresses pipelines for external pull requests coming from the same repository (no forks).

In this issue we should address the need to run pipelines for external pull requests coming from fork repos.

Intended users

Large projects (especially open source) accept pull requests from forks. Currently there is not way for them to run pipelines when a pull request is opened from a fork.

Further details

Proposal

Current state

When GitLab CI/CD is set for a GitHub repository via the GitHub integration, a webhook subscription is created on the main repository in order to receive push and pull_request webhooks.

When a pull request is opened on GitHub, a pull_request webhook is sent to GitLab. If the pull request is from the same repository, we save the pull request info in external_pull_requests table and trigger a pipeline for external pull request if the commit SHA already is present in the repository mirror. If not, as soon as the mirror is updated (as consequence of the branch push webhook), the open pull request is detected and a pipeline is created for it.

When a pull request is updated on GitHub, a pull_request webhook is sent to GitLab. This time we need to detect the synchronize event and update the own ref for refs/pull/N/head with the new SHA. Then create a pipeline for it.

Required changes

If a the pull request is from a fork repository, we still save the pull request info in external_pull_requests table, fetch refs/pull/{pull-request-iid}/head and update mirror. Finally create a pipeline for the external pull request.

The only difference between same repo PR and fork PR is the extra step where we fetch refs/pull/*/head into the mirror repo so that the Runner can work off the pull request ref.

Permissions and Security

There are some security concerns to be addressed!

TBD

Documentation

Testing

What does success look like, and how can we measure that?

  • When a pull request is created from a fork repo on GitHub, GitLab should run a pipeline for the refs/pull/N/head and the SHA
  • When a pull request is updated from a fork repo on GitHub, GitLab should run a pipeline for the same refs/pull/N/head which should point to a new SHA
  • GitHub integration should still work as expected: e.g. GitLab should display status of the pipeline in the pull request page, block PR if pipeline failed, etc.

Links / references