Gitlab block merge requests from feature into master - gitlab

Is there a way to block creating/approving merge requests from "feature/*" branches into master?
I need to allow only merge requests from "release/*" and "hotfix/*" branches.
When creating MergeRequest via GUI the default target branch is master. So human error while doing this may break a workflow and merge untested\unbuild feature into master.
Our current workflow is coding new features in "feature/*" branches. Merging several features into new "release/*" branch and CI makes a build and tests of this release. After testing this release goes on the prod server and into master.

Since GitLab permissions are role-based, there's no way to set permissions per branch (other than setting a branch as protected in Settings / Repository / Protected Branches, which which controls who can merge not which branch can merge ). However, you could do the following:
In your GitLab CICD (if you don't have it set up already I highly recommend, its a handy tool) set up a check that runs always to determine which branch is trying to be merged ($CI_COMMIT_REF_NAME is what you want, see all GitLab default environment variables here) and if the branch name matches 'feature/*', then have the pipeline fail
Under Settings / General / Merge Requests, under Merge Checks, check the option Pipelines must succeed.
Now, if someone attempts to create a Merge Request from a feature branch, the pipeline will fail and no one will be allowed to approve the Merge Request.

Related

What is the best approach for merging a feature branch into master when said feature branch is using a different build pipeline?

I am using Azure Devops in an IT environment with many different development teams and git repositories. Each development team owns one or more repositories. It's my job to work on various application components contained in said repositories. Because I do not own those repositories, I should not make any changes in build/release pipelines, build policies etc, all by myself because that can impact other people's work.
Now let's say I have a feature branch named UpgradedFeature in the repository FeatureRepository, containing my changes. Said changes also introduce a breaking change in the build pipeline used for that repository for the master branch. Let's say that pipeline is named MasterBuildPipeline.
So in order for my build based on the branch UpgradedFeature to succeed and not impact other people's work, I make a clone of the MasterBuildPipeline, name it UpgradedFeatureBuildPipeline and configure the breaking changes. This new build pipeline is used exclusively by me for the UpgradedFeature branch only.
The build, now using the new UpgradedFeatureBuildPipeline pipeline succeeds and now I want to merge into master , so I make a pull request to merge the changes contained in UpgradedFeature into master. The master branch has a branch policy in place named MasterBranchPolicy like described on https://learn.microsoft.com/en-us/azure/devops/repos/git/branch-policies?view=azure-devops&tabs=browser. This branch policy contains the MasterBuildPipeline and prevents completion of that pull request when the build using that pipeline does not succeed.
So my problem is that my pull request triggers the MasterBranchPolicy containing the MasterBuildPipeline and not the UpgradedFeatureBuildPipeline containing the necessary breaking changes for the build to succeed. So the build fails and I cannot complete the pull request.
Of course I could edit the MasterBuildPipeline for a short time, introduce my breaking changes, run the build, then discard the breaking changes again. But there's a chance I may impact other people's work with that and somehow I have a feeling that's not the right approach. I could also edit or disable the MasterBranchPolicy for a short time but again, I may impact other people's work and I feel it's not the right approach.
How should I do this?
So the build fails and I cannot complete the pull request.
To complete the pull request even through the build fails, you could grant yourself Bypass permissions. Bypass permissions let you complete pull requests that don't satisfy branch policies. You can grant bypass permissions to yourself then complete the pull request. Here is Bypass branch policies for reference.
Please navigate to Project setting >> Repositories >> The repo >> Security >> user (yourself) >> Bypass policies when completing pull requests.
Then, you can Override branch policies and enable merge even the MasterBuildPipeline faild.
Please also note that use caution when granting the ability to bypass policies, especially at the repo and project levels. Policies are a cornerstone of secure and compliant source code management. In your scenario, it's suggested to edit the MasterBuildPipeline and the MasterBranchPolicy or disable the MasterBranchPolicy as you mentioned.
Generally, workflow of DevOps Branching Strategy as follows
Developer will create a feature or bugfix branch out of develop. One feature or bugfix branch usually stands for one JIRA bug or feature item. These branches are personal
The changes will be pushed into the developer's feature or bugfix branch.
When the new feature or bugfix is complete.A developer will create a pull request. Pull requests open a code review phase.
Once a pull request has been approved, the team lead or development team will move it into development.
When the development branch has all the epics and bug fixes, i.e., the content planned for the next release, the development team or team lead will create a release branch. This initiates the release regression testing phase.At this stage, only bug fixes are accepted for release, and the workflow is similar to that of the development branch.
Having a separate release branch will enable future development towards the next release in the development branch. Features for the next release are not included in this release. However, bug fixes for this release will be incorporated into the development of the next release as well.
When release content meets the criteria, the release branch will be frozen, which means that it ends. Content from releases will be merged to master and tagged there. For the next release, a new release branch is created when needed.
As per my experience, I would suggest creating branching policies like
A pull request is requested to merge the develop, release, and master branches.
Pull request approvers should be leads.
All developers can create feature branches.
All developers can push to hotfix and feature branches. Commit messages must include the JIRA issue id.

Why bitbucket pipeline merges pull request before it runs?

In their documentation regarding pull request pipelines, bitbucket says:
Pull requests:
a special pipeline that only runs on pull requests initiated from within your repository. It merges the destination branch into your working branch before it runs. If the merge fails, the pipeline stops.
So I'm wondering, why merging before running the pipeline? Why not just running against the coming branch without merging?
Could the reason be detecting merge conflicts early on in the pipeline before the real merge?
If you want to run a pipeline against the coming branch, this is very doable by using Branch workflows. PR merge trigger is just a slightly different idea, as the result of a PR merge is not necessarily the same as the coming branch. For example, merge conflicts can be introduced, which will make your pipeline fail.
There's one thing that documentation is not quite clear about, so I'll clarify it: all this pre-pipeline merging only occurs inside your build environment. Git history of your repository is absolutely safe, and Bitbucket Pipelines won't introduce any changes to it on your behalf.
Finally, you can run a PR merge pipeline manually from the Pipelines UI, without actually merging a PR (see the same link). This way, you can make sure that the merge result build is passing without actually doing a merge.

How does GitLab CI/CD determine if two branches can be merged?

For example, if the dev branch is behind the build branch when the two branches merge, the merge request can be created. But it is clear that it cannot merge because it is not possible to merge a backward branch into the current branch. In this case, I want to use the.gitlab-ci.yml configuration, To determine if the dev branch is behind the build branch, I wonder, can this be done? How to configure the.gitlab-ci.yml file if possible?
Basically, gitlab attempts the merge using git to determine if there's a conflict. It actually calls to gitaly to do this.
Basically the process goes like this:
The rails app in repository.rb will call to the gitaly conflict service to check for conclicts
The conflict service list_conflict_file in gitaly will call to git2go
The git2go conflicts subcommand will basically perform the git merge operation and return any conflicts that were encountered. This eventually makes its way back as a response to the call from rails in step (1)
So, if you wanted to do something similar in your CI/CD pipeline, you could use git (or a programatic API to git in your favorite language) to attempt a local merge of the two branches in order to detect conflicts.

Azure Devops pipeline triggering twice with Build Validation

I have created a pipeline in my repository which is used to validate code by executing unit tests for code that is being pushed to features/* branches. The same pipeline is used as Build validation pipeline set as Branch Policy on the develop branch to validate incoming PRs. This is the trigger of the pipeline.
# pipeline.yml
trigger:
batch: false
branches:
include:
- features/*
However we have come across the following condition: Given an open PR from refs/heads/features/azure-pipelines -> refs/heads/develop we push a commit on the features/azure-pipelines branch.
This causes the pipeline to trigger twice. To my understanding one of the runs is due to the trigger of the pipeline (The one marked as Individual CI on the screenshot) and the second run is due to branch policy trying to validate code being pushed onto the open PR to develop. (The PR Automated)
Is there any way to disable one of the executions since it's essentially a duplicate? I was maybe looking for a way to retrieve open PRs and abort execution of a pipeline for Individual CI if there is an open PR for a branch but I am not sure that's the best way around that and I am looking for options.
You can set
trigger: none
This way only the branch policy will trigger the pipeline.
Is there any way to disable one of the executions since it's essentially a duplicate?
As we know, we could not disable the Build validation pipeline set as Branch Policy on the develop branch to validate incoming PRs unless we cancel the Build validation.
For your situation, you could try to include [skip ci] in the commit message or description of the HEAD commit to make the Azure Pipelines skip running CI when you plan to merge the features branch to the develop branch.
You could check the document Skipping CI for individual commits for some more details.
Here it depends if they does the same. You can have conditional checks in the pipeline which does a different things for PR and CI runs. However, I'm pretty sure that this is not possible, because one is defined on the YAML and the second on the Azure DevOps portal. So even if you disnle PR trigger here in YAML, a branch policy still runs a PR. And you can specify antyhing in YAML to block branch policy.

Gitlab merge request fast forward merge

I'm trying to setup a gitlab worflow for my team with gitlab-ci. We have a Gitlab CE version 10.2.4 with gitlab CI configured to run a build on every push. Now we would like to use the merge request workflow with protected develop and release branches. Our requirement is that no code can be merged into these branch without running on gitlab-ci first to keep these branches clean.
Since gitlab doesn't seem to have the possibility to automatically test merge request, our only option is to use either Merge commit with semi-linear history or Fast-forward merge. (cf open issue on gitlab)
The issue is that since these merge option require fast-forward, if multiple merge request are created for the same target branch, accepting one merge request changes the target branch. This then prevent other merge request from being merged as they are no longer fast-forward. This means that every time we accept a merge request we have to rebase/merge all the other merge request with the target branch which is quite tedious.
Can anyone using Fast-forward merge option on gitlab explain how they deal with this multiple merge request scenario ? Or is there an other way to ensure that code is tested before being merge without requiring the fast-forward ?
In your project settings, go to "General"->"Merge request" and check "Only allow merge requests to be merged if the pipeline succeeds".

Resources