{"id":14382,"date":"2016-04-21T07:00:45","date_gmt":"2016-04-21T00:00:45","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/visualstudioalm\/?p=14382"},"modified":"2019-02-14T17:34:05","modified_gmt":"2019-02-15T01:34:05","slug":"pull-request-build-policies-for-high-quality-code","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/devops\/pull-request-build-policies-for-high-quality-code\/","title":{"rendered":"Pull request build policies for high quality code"},"content":{"rendered":"<p>Branch policies are a great way to keep your code quality high, but strict build gates can sometimes introduce too much friction into the developer inner-loop.\u00a0 To developers working with pull request build policies, this will sound familiar:\u00a0 You have a PR that&#8217;s been approved and is ready to merge &#8211; but right before you&#8217;re ready to click Complete Merge, another developer&#8217;s changes are merged in, putting your PR out of policy (and requiring another build).\u00a0 Definitely a source of frustration.<\/p>\n<p>To help streamline the pull request workflow, yet still offer protection on your branches, we added some new options to the Team System build policies.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/6\/2019\/05\/branch-policies.png\"><img decoding=\"async\" class=\"alignnone size-full wp-image-15443\" src=\"https:\/\/devblogs.microsoft.com\/devops\/wp-content\/uploads\/sites\/6\/2016\/04\/branch-policies.png\" alt=\"New build policy options for Git pull requests\" width=\"743\" height=\"180\" \/><\/a><\/p>\n<h3>&#8220;Buddy Build&#8221; Policy<\/h3>\n<p>The first of the new build policy options is what we sometimes call a &#8220;buddy build&#8221; policy &#8211; that idea being that you&#8217;re having someone else build your changes to avoid the &#8220;it worked on my box&#8221; problem. \u00a0In this case, the &#8220;buddy&#8221; is the build machine, and like the existing build policy, each time new change are added to the source branch of the PR, those changes are automatically detected and built.<\/p>\n<p>The big difference with this policy option is that when the target branch is updated, a new build is not required. \u00a0In the policy config UI, we expose this setting under the options for what to do when the target branch is updated\u00a0as\u00a0<strong>Don&#8217;t require a new build<\/strong>.<\/p>\n<p>So, in the case above where you&#8217;re about to merge your PR, and someone else merges their changes, you won&#8217;t be forced to rebuild. \u00a0Instead, you&#8217;ll see an option to re-evaluate the merge:<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/6\/2019\/05\/buddy-build-target-updated.png\"><img decoding=\"async\" class=\"alignnone size-full wp-image-15463\" src=\"https:\/\/devblogs.microsoft.com\/devops\/wp-content\/uploads\/sites\/6\/2016\/04\/buddy-build-target-updated.png\" alt=\"Option to re-evaluate the merge when the target branch is updated\" width=\"302\" height=\"193\" \/><\/a><\/p>\n<p>Re-evaluating the merge will create a new merge commit and check for conflicts. \u00a0Assuming there are no conflicts, you&#8217;ll see a message about the target branch being updated with an option to rebuild. \u00a0With the buddy build policy, all you need is one good build to get approval, so the rebuild would be optional in this case.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/6\/2019\/05\/buddy-build-target-updated.png\"><img decoding=\"async\" class=\"alignnone size-full wp-image-15453\" src=\"https:\/\/devblogs.microsoft.com\/devops\/wp-content\/uploads\/sites\/6\/2016\/04\/buddy-build-rebuild-option.png\" alt=\"Rebuild option shown when buddy build policy is enabled\" width=\"302\" height=\"193\" \/><\/a><\/p>\n<h3>Build Expiration<\/h3>\n<p>The second new\u00a0option for handling builds when there are changes to the target branch enables teams to strike a balance between strict builds and the more relaxed buddy build.\u00a0 The option to <strong>Require a new build if older than n hours<\/strong> works pretty much how it sounds.\u00a0 Like the buddy build policy, a change to the target branch doesn&#8217;t immediately invalidate the current build.\u00a0 Instead, it sets an expiration time for the build based on the configuration &#8211; if the option is configured for one hour, a change to the target branch will cause any PR build to expire one hour from the time it originally completed (not one hour from the time the branch was updated).<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/6\/2019\/05\/build-expiration-warning.png\"><img decoding=\"async\" class=\"alignnone size-full wp-image-15655\" src=\"https:\/\/devblogs.microsoft.com\/devops\/wp-content\/uploads\/sites\/6\/2016\/04\/build-expiration-warning.png\" alt=\"Build policy expiration warning\" width=\"303\" height=\"187\" \/><\/a><\/p>\n<p>In the case where a build is successful and the target hasn&#8217;t changed, the build will be good indefinitely.\u00a0 If the build is older than the expiration window and then the target is updated, the build will immediately be invalid and a rebuild will be required.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/6\/2019\/05\/build-expired.png\"><img decoding=\"async\" class=\"alignnone size-full wp-image-15665\" src=\"https:\/\/devblogs.microsoft.com\/devops\/wp-content\/uploads\/sites\/6\/2016\/04\/build-expired.png\" alt=\"Build policy expiration message and rebuild option\" width=\"303\" height=\"187\" \/><\/a><\/p>\n<h3>How should I choose between the build policy options?<\/h3>\n<p>Choosing an option for your build policy comes down to choosing between the risk of introducing a build break and developer friction.\u00a0 On the extremes, no build policy has the least friction and biggest risk of build break and the option to Always requires a new build prevents build breaks but can cause friction as the activity in the repo increases.<\/p>\n<p>If your risk tolerance for a build break is high, the buddy build might be a good option.\u00a0 If you have a long build time, this might also be a good option (though investing to speed up your build would be a good idea, too).<\/p>\n<p>The build expiration feature is a good middle ground that allows teams to tweak the longevity of PR builds.\u00a0 You can simultaneously keep out those stale PRs that had a successful build last week and not require a rebuild when an unrelated change is merged right before you complete your PR.<\/p>\n<p>For more details on how to configure build policies for your pull requests, checkout our <a href=\"https:\/\/msdn.microsoft.com\/library\/vs\/alm\/code\/git\/branch-policies#Requirethepullrequesttobuild\">documentation on MSDN<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Branch policies are a great way to keep your code quality high, but strict build gates can sometimes introduce too much friction into the developer inner-loop.\u00a0 To developers working with pull request build policies, this will sound familiar:\u00a0 You have a PR that&#8217;s been approved and is ready to merge &#8211; but right before you&#8217;re [&hellip;]<\/p>\n","protected":false},"author":198,"featured_media":45953,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1,225],"tags":[],"class_list":["post-14382","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-devops","category-git"],"acf":[],"blog_post_summary":"<p>Branch policies are a great way to keep your code quality high, but strict build gates can sometimes introduce too much friction into the developer inner-loop.\u00a0 To developers working with pull request build policies, this will sound familiar:\u00a0 You have a PR that&#8217;s been approved and is ready to merge &#8211; but right before you&#8217;re [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/posts\/14382","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/users\/198"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/comments?post=14382"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/posts\/14382\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/media\/45953"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/media?parent=14382"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/categories?post=14382"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/tags?post=14382"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}