Github PR Checks Without Disallowing Pushing

Viewed 95

Please read carefully as I believe my use case is unique and I have tried searching a lot on how to do this, but I am still unsure.

Generally, I am trying to set up a repo for a group of developers to work on and have it contain CI checks and require reviewers. However, I have run into some issues with how Github enforces branch protection. On top of that, I cannot use Actions as we are using a self-hosted Enterprise Github through an organization.

My desires:

  • Use Jenkins (which is already set up and building) builds as checks for PRs. If the checks don't pass, you cannot click merge on the PR.
  • Allow pushing to a branch that I have a PR up for so the author can push changes based on PR comments.
  • Require two approvals from maintainers. You cannot click merge without these.
  • It seems I could protect a master branch for example. However, I would like to enforce the PR checks whenever a person chooses to make a PR. For example, from one dev branch into another dev branch.

Use case: An author sets up a PR for merging a branch some-work into dev. Jenkins builds the HEAD of the branch some-work to evaluate the checks. I would like to enforce this PR to have two approvals from maintainers. So, those reviewers make some comments and request some changes. The author makes those changes and pushes a new commit to the some-work branch. Jenkins runs on the new HEAD to reevaluate the checks. Then, if-and-only-if the two reviewers approve and the checks pass can the merge button be clicked.

What I have tried:

  • Using Github branch protections: the required approvals and the required status checks. However, this prevents any pushing or force pushing to the branch being developed on. I could just apply these protections to master, but I also want these checks part of any PR (even dev2->dev1, for example).
  • Github actions, but these are not available in the self-hosted enterprise Github I have to use.

What I understand:

  • I understand that I can protect master, for example, in this manner with the native Github branch protection. However, if I want master to be something that always works, it is understandable that developers would break up a feature into multiple branches. They would also want their follow developers to review it when merging it from their branch to an intermediate (non-master) branch. Then the actual branch being merged into master consists of code written by many developers.

Thank you all in advance for your time and help. :)

2 Answers

Using Github branch protections: the required approvals and the required status checks.
However, this prevents any pushing or force pushing to the branch being developed on

But... that issue (not being able to push a protected branch) could be part of a possible solution.

I would make jenkins create/reset a PR branch based on a push on a topic branch (like some-work-pr, based on some-work)

  • some-work is not protected, and can receive commits at any time
  • some-work-pr is created by Jenkins protected, and cannot be modified: compilation/test/review/approval happens here.

PR would only be done from xxx-pr branches (protected PR branches created/managed by Jenkins), while other topic branches continue to evolve.

You can only enforce these policies with branch protections, so if you want to enable required CI checks before merging a PR for all branches, then you need to protect all branches (e.g., with the pattern **). In that case, you'll need to have developers use a forking model for your repositories so that they can push code to their forks and then merge in the changes via pull requests only.

Note that if you adopt an approach where projects are implemented as a set of small, incremental changes that are merged frequently and use feature flags to control whether the code is enabled, then as a practical matter developers will only merge into the main branch and you can get away with only protecting the main branch.

Related