Wait for MR approval in CI pipeline jobs
Problem to Solve
Auditing and compliance teams need to document approvals for software delivery. Currently in GitLab there's no way to connect an approver to a CI pipeline which made a change to a production environment.
We occasionally receive requests for a "manual approval job" that will stop a pipeline and force it to wait for someone with signing authority to approve the deployment before continuing; this is in fact how this issue began. This kind of approach works, but is limited in that it slows down teams and is incompatible with a CD way of working. Here at GitLab we want to support the spirit of the requirement, but in a way that empowers teams to deliver in a compliant way without a manual pause.
Instead of implementing a manual approval job, we will add a new kind of syntax for a job that will require the MR introducing the change to have been approved, and wait if that has not yet been completed. This has a few benefits:
- The approvals are built into the existing change process through MRs
- This does not add a new kind of additional approval within GitLab
- Pre-approvals can be collected, avoiding adding delays
- There is no manual stopping point needed
This would be implemented for a job via the
when: keyword, by adding an
approved value; typically this would be paired with the
master pipeline jobs that actually do the deployment. When set, the job will wait for the approval on the MR before continuing. If the MR is already approved (which could optionally be enforced with the existing optional requirement for # of MR approvals), it considers itself to have already collected the required approvals and continues on.
By implementing things in this way we can also take advantage of great security features like requiring passwords for approval, and any other improvements that come for MR approvals.
Issues with Proposal
Counting in approvals from associated merge requests seems nice, however, there are some edge cases we have to take into account.
- If the associated source branch was deleted, we cannot track the MR number (MR# is written in commit message be default, however, users can edit the message and delete it).
- All commits on master doesn't mean to be created via merge requests. There are the other cases such as manual-merge, auto-merge via API, pull mirror and more.
- git-tags are not associated with merge requests. How does this feature behave if pipeline runs on tag i.e.
This means we cannot redirect users to MR pages 100% and we may need an independent UI for this approval system. We can't proceed with this issue until we determine the appropriate path forward here.
- From a UX perspective we should make the approver(s) that is being inherited from the MR more clear when viewing a pipeline (dashboard view maybe, but definitely pipeline views). I.e., if you're looking at a pipeline, the answer to the question "who approved this" needs to be obvious.
- We need to make it clear, if a pipeline/job is waiting on the MR to be approved, what's happening.
- We need to also make it clear that this feature works best when required approvers is set to >0 for a project. By collecting pre-approvals, any possibility of a pipeline waiting is obviated.
Blocking manual approvals completely
One approach here would be to completely disallow collecting approvals after a pipeline is running (i.e., require that required approvers > 0 for this feature to be enabled.) We considered this, but there are real workflows in certain cases where the approval needs to be collected later. This is particularly true for organizations transitioning from a more centralized change process to CD. We want to support them in this transition, rather than block them out of the feature, so we have chosen to implement things in this way. The nice benefit is that they have a clear step to move to CD when they are ready - start enfrocing required approvers > 0 at merge time, and they've achieved a more agile change process. Super easy and a clear path forward for these teams.
Future iterations could narrow the group of allowed approvers to some specific role(s) or user(s), by improving the general MR approvers feature to support different constraints. A nice benefit of building things in this way is that improvements to this kind of approver can benefit MR approvers as well.
A different approach would be to enable a value in the
.gitlab-ci.yml to constrain the approver list, and not move forward without a match.