End-to-end Pull Request on Azure DevOps
Azure DevOps - Pull Request details

End-to-end Pull Request on Azure DevOps

Introduction

Every software has a need to evolve, either to implement new features, to decommission old ones or to fix bugs that may appear during the development stage. In a distributed version control world like git developers handle code on their local repository, add or fix some piece of code, commit to their local repository and then push their changes to the server-side repository. But what should happen next and how could we ensure to integrate to the master branch a verified source code who don't break the overall application ? This is something achievable with the concept of Pull Request! In this brief tutorial I'll demo you the usage of Pull Request offered by Azure DevOps. Hope this help :-)

Concepts

Azure DevOps is an Application Lifecycle Management solution provided as a SaaS on Azure. It aims to fully support end-to-end DevOps cycle by helping developers ship software faster with higher quality. Azure DevOps includes Azure Boards, Azure Repos, Azure Pipelines, Azure Artifacts and Azure Test Plans. And last but not least, it's used by more than 80,000 Microsoft engineers and thousands of our customers !


Contributions to public repository required the need to have a workflow discussing the changes between the developers and maintainers instead of allowing anyone to commit to the master branch because first they probably don't have write access to the master and because mainteners need to ensure the code quality to be committed. The Git community massively adopted the concept and usage of a Pull Request. As described here by GitHub, "Pull requests let you tell others about changes you've pushed to a branch in a repository [on GitHub]. Once a pull request is opened, you can discuss and review the potential changes with collaborators and add follow-up commits before your changes are merged into the base branch."

This introduce the concept of a branch which is a copy of a master repository at a time with some divergence due to code changes on the branch, code changes on the master or -most of the time- code changes on both branch and master. This allow every developers to isolate their changes from the code base and to rely on git to merge these changes to the master branch once developments are finished. Despite me talking only about merging a feature branch to the master branch, Pull Request is not limitted to work on the master one but can be used in any branch-to-branch scenario.

Following the definitions above you could notice that Pull Request is not only a feature but more a workflow to ensure any piece of code comming from branches are integrated to the master branch by combining peer review and in some cases by executing successfully build and / or release. At the end the goal is to have the master branch updated with codes changes that is ready to be built and released.

Objectives

The purpose of this article is to provide an end-to-end guidance to support Pull Request on your existing Azure DevOps Repos and Pipelines, from the service configuration to running a Pull Request iteration and demonstrate how it works.

Our end-user workflow will include the creation of a branch to implement our code, a Pull Request creation to merge that branch to the master, a PR validation process including running a successful Build pipeline where that build is the same as for the master branch, running a successful Release pipeline where, again, this is the same pipeline as for the master branch and a peer review approval before completing the merge.

As a pre-requisite to run this tutorial you should have an existing Azure DevOps environment including an Azure Repos of type Git and 2 Azure Pipelines, one Build pipeline producing artifacts and one Release pipeline using the build artifacts. If you don't have any of these you could rely on Azure DevOps Demo Generator to create a freshly new environment, just make sure it covers our needs. Having a release pipeline isn't required to use Pull Request but triggering a release automatically anytime a PR is raised will help to catch any deployment issues that could happen in early stage from the beginning of the cycle.

The three main steps we'll follow through this article are :

  1. Setting up the existing Azure Repos & Pipelines
  2. Code a new feature
  3. Merge my code to master branch

Then we'll end by a short discussion about the enhancements and a conclusion.


1. Setting up the existing Azure Repos & Pipelines

To implement Pull Request on Azure DevOps we have to configure at least 2 elements : Azure Repos and Azure release Pipeline.

Regarding Azure Repos we'll rely on the branching ability provided by git and available on Azure DevOps. The workflow from the developer's viewpoint is pretty simple : create a branch, work on that branch and then create a PR.

With regards to our requirements running a successful Build is mandatory so the first thing to do is to require a Build Validation for every PR to merge from branches to master. This is done by setting up a branch policy on the master one. To do so just navigate to Azure Repos > Branches and then by clicking on the "Branch policies" from the ellipsis right after the "master" record.

Then scroll down to the page and click on the "+ Add build policy" button below the Build validation section. This opens a new blade when you can refer to your build pipeline, just choose your build here. Since we'd like it to be done automatically we leave the trigger set to "Automatic". As running a successful build is a mandatory step we'll choose the "Required" option under the Policy requirement. Then fill-in a name and save.


This returns you to the Branch policies page for your branch. We'll now implement the successful run of a Release pipeline. This is done by setting a status policy for your master branch. Since we're already on the Branch policies page for the master branch we just have to click on the "+ Add status policy" button below the "Require approval from external services" section. This opens a blade where we can select the status to check. For that field particularly you'll need to fill-in your Release pipeline name pefixed with the "VSTS-RM/" token. So in my example my Release pipeline name is "Azure Web App CD", the status to check will be "VSTS-RM/Azure Web App CD".


Since running a successful Release is mandatory we'll check the Required option for the Policy requirement then save. At the end you should have something close to the screenshot below.

If so then we're done with configuring Azure Repos.

It's important to understand few things : Adding a Build validation will run every build pipeline added to the validation as well as ensuring they end in success. Adding a status policy linked to a Release pipeline will not run that pipeline but will just check it ends with success. That's why we need to do some configuration for the related Release pipeline to be executed.

The first step will be to activate the release for every stages concerned by a deployment from a Pull Request. My suggestion here is to have a separate stage instead of relying on existing ones for the ease of the demo and also to avoid overriding existing deployed environment with a PR feature. So once you have your stages ready, click on the Pre-deployment conditions button then enable the pull request deployment flag for all your concerned stages.

The next step is about enabling the Pull Request trigger on the artifact related to the build pipeline. Navigate to the Continuous deployment trigger of your build artifact then enable the Pull request trigger. It's important to leave the Target Branch to master since we defined policies on that branch. Once enabled you could see the list of stages that will run a deployment for the PR under the Stages section. In my case I got only one stage because I want to deploy a PR on a dedicated integration environment called "INTE-PR env".

We are all done now so let's use it !

2. Code a new feature

The first things to do for the developer is to create a new branch from the master one to implement the new feature. To do so start from Azure Repos > Branches and click on the "New Branches" button at the top right of the screen, enter a name and then click on the "Create branch" button. You have the choice here to link your branch to a backlog item such as a user story or a task which is something I would recommend to you but for the purpose of the demo let's keep it clean.

On your computer start by synchronizing your local repository with the latest version available from the server by running a git pull command. By doing so you'll also get the new branch information so now let's move on to that new branch on your local repo by executing the git checkout command followed by the branch name.

Now you are ready to develop to that branch on your repo. The usual development process will involve to run several git commit command line followed by a git push action to send your modifications to the server repo.

You could check your git push command to your branch by going to Azure Repos > Pushes and then filtering on your branch name. By clicking the arrow at the left of your push you'll get the list of the commits embedded in that push.

Now that you've finished to develop your feature let's create a Pull Request to merge your code to the master branch.


3. Merge my code to master branch

To create a Pull Request, start from Azure Repos then click on Pull requests from the menu. This load a page inviting you to create a new pull request so click on the "New pull request" button. You're now required to enter few informations about your pull request.

Make sure you selected the right branch to merge to the master one. Add a title to your PR and even if not required add a short description of the changes. It's also a good practice to add reviewers so add one. You'll notice you are able to link your PR to a work item which is also a good practice but for the purpose of the demo leave it void. Once you're ready click on the "Create" button.

After creating the PR you'll land to the PR detailed page showing you at the right the current required policies and their state. In my case the first one is related to the build pipeline execution and the second one is related to the release pipeline.

If you open the Build page from Azure Pipelines you'll see the execution status and details about your Pull Request build execution.

If you now move to the Release page and click on the last one related to your PR you'll get details about the type of release (which should be "Pull request deployment"), the artifact that triggered that release (which should be your code build) and the different stages executed.

Let's now go back to the Pull Request detail page as an approver or having privileges to complete the request. Since the build and the release completed successfuly you should get a green check for both pipeline under the Policies section. If everything goes well with the code you could decide to approve the request by clicking the "Approve" button. You could also decide to approve with suggestion, wait for author (for instance if you leave a comment) or reject the request. Once you approve the PR a log will appears.

Now that everything is OK the last step is to complete the PR. By clicking on the "Complete" button you'll be invited to enter a short and a long description. You'll also have 2 interesting options. The first one is about to delete the branch after merging. This is relevant if you're working in a feature-branch style where you'll create a branch each time you'll implement a new feature. If you're working in a developer-branch style then uncheck that box because the developer should keep his branch to work on future evolutions or bug fixes.

The second feature is about squashing changes when merging. As described here "Squash merging is a merge option that allows you to condense the Git history of topic branches when you complete a pull request. Instead of each commit on the topic branch being added to the history of the default branch, a squash merge takes all the file changes and adds them to a single new commit on the default branch."

From my point of view this is mainly up to the size of the changes you plan to merge and the way you're organized. If you're working on several bug fixes on your branch then merging them to master I would recommend to not squash in order to keep every commits related to each single fix. If you're working with feature-branch then squashing changes make sense since you're only interested in having the history of merging a feature to your master branch.

Once you complete the PR you'll notice some changes & activities :

  • If you check the "delete branch" option then your branch will be deleted
  • When moving to your master branch you'll see some commit activities as well as a push activity. Depending on the squash option you selected you may have a push owning a single commit or having the several ones related to your branch activity when developing the feature.
  • If you have a build pipeline with continous integration activated then it will be run. If you have a release pipeline with a continuous deployment option activated then it'll be triggered once the build complete.


Enhancements

Exclude PR-dedicated Release stage from a standard Release

When you setup your existing release pipeline to support your Pull Request then you need to select the stages that should be run which is fine. But when your release pipeline will be run either from a standard continuous deployment trigger or from a manual one then any stage will be run even the ones that you dedicated to a PR only, if any, which is the case in that tutorial. In that case I suggest to add an Artifact filter on the pre-deployment condition trigger of the related PR-dedicated stage which will exclude a build execution comming from the master branch thus ensuring to not run when comming from a PR workflow. Another option way more easy would be to create a dedicated Release pipeline for the Pull Request workflow.

Trigger your master branch build even on a feature branch

You'll notice in our scenario that when working on the branch we don't trigger a build pipeline until creating a PR. We have the ability to change that by triggering a build intented primarily for your master branch but to run it on your feature branch. By doing so the developer would be able to detect build issue early in the process and this could end in reducing the time of the overall workflow avoid back & forth activities.

To trigger a build on your branch you'll have to activate the continuous integration trigger on your build pipeline as well as adding a branch filter inclusion. For instance you could decide that every feature branch should start by the "ft-" token and then add a branch inclusion filter with a branch specification value set to "ft-*".

By doing so you should update your release pipeline to avoid overriding all the target environment of your release when comming from a feature branch build otherwise you could end by publishing a feature to production before creating a Pull Request! :

  1. The build pipeline artifact used should come from the master branch: From the build artifact blade of your release ensure to select the Default version to the "Latest from the build pipeline default branch with tags" value (if master is the default branch of your build pipeline) otherwise choose "Latest from a specific branch with tags" and fill in the branch name.
  1. The continuous deployment trigger should be restricted to the master branch: This is done by adding a build branch filter which includes the master branch.

Exclude build tasks when running a feature branch build

When you're running a build pipeline mutualized for the master branch as well as for the feature branchs (like described above) you'll also have the need to exclude some task to be executed depending on the path you come from. You could do so by adding a Custom condition on the task where it is supported to specify the condition that should be met to run the task. This is something documented here.


Conclusion

Here we are ! We've seen through this article an end to end scenario of using the Pull Request feature of Azure Repos. This enable a collaborative process ensuring to keep high quality code changes to be merged to the master branch. At the end every changes are under control. As a next step you could imagine to rely on a fully automated Pull Request process by running build tasks such as code coverage and code quality.

Feedback is a gift : If you have any feedback, precision or comments related to this article or Azure DevOps feel free to add a comment and I'll be happy to take it into consideration.


References

Shubhadeep Chattopadhyay

Engineering Manager / Technical Product Manager with high expertise in Enterprise SaaS Product Development.

4 年

This very useful article. I am facing a couple of issues, can you please help me out. 1. Right now when I am creating a Pull Request, when the approver accepts and completes the pull request then the CI pipeline is triggered and merged with the main branch. The problem is I am tagging the work item in the PR and the status of that task is getting updated automatically to Done. How can I restrict that? 2. Is there any way to merge one branch to another based upon the work item status change? Please let me know your thoughts.

回复
Kirsten Kluge

Happy developers are the most valuable!

5 年

Hi, very good article. I have one question: How should I cleanup my stages when the pr is finished? for example I deploy a Azure Web App to verify the pr. So every pr gets its own Web App. After the pr is finished or canceled this Web App has to be removed. I can not find any trigger that will allow that. Do you have any hint how I can get something like that working? Thanks, Kirsten

Jo?o Heytor Kreitlow Pereira

DevOps Engineer | Solutions Architect | Engineering Manager | Cloud Engineer | Driving DevOps culture and cloud excellence through people

5 年

Great article! Thanks!

Azin Zare

Software QA Engineer | Manual Testing | Test Automation | Playwright | Cypress | Selenium

5 年

Thanks.?

Divya Vaishnavi

Product Lead @ Microsoft

6 年

Great article. Aren't you missing tests though.. unit tests for your PR and functional / API or E2E tests before you deploy

要查看或添加评论,请登录

Olivier L.的更多文章

  • Exploring The Prompt: A Path To A Better Prompt

    Exploring The Prompt: A Path To A Better Prompt

    Audience: Anyone interested in Generative AI ??—especially GenAI users and designers, whether for personal use…

  • Exploring The Prompt: Playing With Attention

    Exploring The Prompt: Playing With Attention

    Audience: Anyone interested by Generative AI ?? but mostly GenAI users and designers prompting for personnal use, for…

    4 条评论
  • Having Fun With The Azure RateCard API

    Having Fun With The Azure RateCard API

    Yes, I know what you're telling to yourself. "How could I get fun by playing with an API ? And especially the Azure…

    5 条评论

社区洞察

其他会员也浏览了