{"id":14,"date":"2015-06-02T00:00:00","date_gmt":"2015-06-02T07:00:00","guid":{"rendered":"https:\/\/github.test\/2015-06-02-deploying-branches-to-github-com\/"},"modified":"2024-06-17T08:31:24","modified_gmt":"2024-06-17T15:31:24","slug":"deploying-branches-to-github-com","status":"publish","type":"post","link":"https:\/\/github.blog\/engineering\/engineering-principles\/deploying-branches-to-github-com\/","title":{"rendered":"Deploying branches to GitHub.com"},"content":{"rendered":"<p>At GitHub, we use a variant of the <a href=\"https:\/\/guides.github.com\/introduction\/flow\/\">Flow<\/a> pattern to deploy changes: new code is always deployed from a pull request branch, and merged only once it has been confirmed in production. <code>master<\/code> is our stable release branch, so everything on <code>master<\/code> is considered production-ready code. If a branch deploy ships bad code containing a bug or performance regression, it is rolled back by deploying the latest <code>master<\/code> to production.<\/p>\n<p>Using this workflow, engineers at GitHub <a href=\"https:\/\/github.com\/blog\/1241-deploying-at-github\">deploy changes to our website<\/a> several hundred times every week.<\/p>\n<div class=\"chat\" style=\"margin: 30px 0\">\n<div class=\"message self\"><img src=\"https:\/\/avatars.githubusercontent.com\/u\/2567?v=4&s=22\" srcset=\"https:\/\/avatars.githubusercontent.com\/u\/2567?v=4&s=22 1x, https:\/\/avatars.githubusercontent.com\/u\/2567?v=4&s=44 2x, https:\/\/avatars.githubusercontent.com\/u\/2567?v=4&s=88 4x\" class=\"avatar avatar-small\" alt=\"tmm1\" \/><br \/>\n<b class=\"author\">tmm1<\/b><\/p>\n<div class=\"entry\">\/graph me 20150517..20150523 @github.deploys.total<\/div>\n<\/div>\n<div class=\"message robot\"><img src=\"https:\/\/avatars.githubusercontent.com\/u\/480938?v=4&s=22\" srcset=\"https:\/\/avatars.githubusercontent.com\/u\/480938?v=4&s=22 1x, https:\/\/avatars.githubusercontent.com\/u\/480938?v=4&s=44 2x, https:\/\/avatars.githubusercontent.com\/u\/480938?v=4&s=88 4x\" class=\"avatar avatar-small\" alt=\"hubot\" \/><br \/>\n<b class=\"author\">Hubot<\/b>\n<\/div>\n<\/div>\n<p>All deployments happen in chat via <a href=\"https:\/\/hubot.github.com\">Hubot commands<\/a>, which ensures that everyone in the company (from development to operations to support) has visibility into changes that are being pushed into production.<\/p>\n<div class=\"chat\" style=\"margin: 30px 0\">\n<div class=\"message self\"><img src=\"https:\/\/avatars.githubusercontent.com\/u\/2567?v=4&s=22\" srcset=\"https:\/\/avatars.githubusercontent.com\/u\/2567?v=4&s=22 1x, https:\/\/avatars.githubusercontent.com\/u\/2567?v=4&s=44 2x, https:\/\/avatars.githubusercontent.com\/u\/2567?v=4&s=88 4x\" class=\"avatar avatar-small\" alt=\"tmm1\" \/><br \/>\n<b class=\"author\">tmm1<\/b><\/p>\n<div class=\"entry\">\/deploy github\/my-feature to production<\/div>\n<\/div>\n<div class=\"message robot github\">\n<div class=\"entry\">tmm1 is <span class=\"link\">deploying<\/span> github\/my-feature (<span class=\"link\">deadbeef<\/span>) to production.<br \/>\nCheck out the <span class=\"link\">haystack firehose<\/span> so you&#8217;re the first to know of any new exceptions.<\/div>\n<div class=\"entry success\">tmm1&#8217;s production <span class=\"link\">deployment<\/span> of github\/my-feature (deadbeef) is done! (82s)<\/div>\n<\/div>\n<div class=\"message mentioned robot\"><img src=\"https:\/\/avatars.githubusercontent.com\/u\/480938?v=4&s=22\" srcset=\"https:\/\/avatars.githubusercontent.com\/u\/480938?v=4&s=22 1x, https:\/\/avatars.githubusercontent.com\/u\/480938?v=4&s=44 2x, https:\/\/avatars.githubusercontent.com\/u\/480938?v=4&s=88 4x\" class=\"avatar avatar-small\" alt=\"hubot\" \/><br \/>\n<b class=\"author\">Hubot<\/b><\/p>\n<div class=\"entry\">tmm1, make sure you watch for exceptions <span class=\"link\">in haystack<\/span> and perf issues at <span class=\"link\">graphme<\/span><\/div>\n<\/div>\n<\/div>\n<p>Deployments are reported <a href=\"https:\/\/developer.github.com\/changes\/2014-01-09-preview-the-new-deployments-api\/\">to the GitHub API<\/a> and show up in the timeline on corresponding pull requests.<\/p>\n<p><img data-recalc-dims=\"1\" decoding=\"async\" loading=\"lazy\" src=\"https:\/\/i0.wp.com\/cloud.githubusercontent.com\/assets\/2567\/7905866\/37331f22-085b-11e5-94dc-e245cd9efed1.png?ssl=1\" alt=\"deployments in pull request timeline\" \/><\/p>\n<p>Recent deployments are also available through chat.<\/p>\n<div class=\"chat\" style=\"margin: 30px 0\">\n<div class=\"message self\"><img src=\"https:\/\/avatars.githubusercontent.com\/u\/2567?v=4&s=22\" srcset=\"https:\/\/avatars.githubusercontent.com\/u\/2567?v=4&s=22 1x, https:\/\/avatars.githubusercontent.com\/u\/2567?v=4&s=44 2x, https:\/\/avatars.githubusercontent.com\/u\/2567?v=4&s=88 4x\" class=\"avatar avatar-small\" alt=\"tmm1\" \/><br \/>\n<b class=\"author\">tmm1<\/b><\/p>\n<div class=\"entry\">\/deployed github<\/div>\n<\/div>\n<div class=\"message robot\"><img src=\"https:\/\/avatars.githubusercontent.com\/u\/480938?v=4&s=22\" srcset=\"https:\/\/avatars.githubusercontent.com\/u\/480938?v=4&s=22 1x, https:\/\/avatars.githubusercontent.com\/u\/480938?v=4&s=44 2x, https:\/\/avatars.githubusercontent.com\/u\/480938?v=4&s=88 4x\" class=\"avatar avatar-small\" alt=\"hubot\" \/><br \/>\n<b class=\"author\">Hubot<\/b><\/p>\n<div class=\"entry\">\n<pre><code>2015-05-27 15:10:16 -0700 - rtomayko <span class=\"link\">deployed<\/span> github\/<span class=\"link\">regen-missing-merge-commits<\/span>(a987454a) to production <span class=\"link\">(compare)<\/span>\n2015-05-27 13:37:05 -0700 - connors <span class=\"link\">deployed<\/span> github\/master(ce83e8bb) to production <span class=\"link\">(compare)<\/span>\n2015-05-27 13:29:32 -0700 - jakeboxer <span class=\"link\">deployed<\/span> github\/<span class=\"link\">org-migration-logged-out-500<\/span>(98451e5c) to production <span class=\"link\">(compare)<\/span>\n2015-05-27 13:13:04 -0700 - grantr <span class=\"link\">deployed<\/span> github\/<span class=\"link\">add-at-to-code-tokenizer<\/span>(d4daff29) to production <span class=\"link\">(compare)<\/span>\n2015-05-27 12:04:40 -0700 - jakeboxer <span class=\"link\">deployed<\/span> github\/<span class=\"link\">fix-accept-invitation-timeout<\/span>(f224305e) to production <span class=\"link\">(compare)<\/span>\n2015-05-27 11:56:34 -0700 - jasonrudolph <span class=\"link\">deployed<\/span> github\/<span class=\"link\">api-fix-schema-doc-generation<\/span>(b2805955) to production <span class=\"link\">(compare)<\/span>\n2015-05-27 11:35:02 -0700 - spraints <span class=\"link\">deployed<\/span> github\/<span class=\"link\">silence-yajl-errors<\/span>(3adc5bc7) to production <span class=\"link\">(compare)<\/span><\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<p>Over the years, we&#8217;ve built a number of deployment features into Hubot and Heaven (our Capistrano-based deployment API) to help streamline our process. Below are some of our favorites.<\/p>\n<h4 id=\"deploy-queues\"><a class=\"heading-link\" href=\"#deploy-queues\">Deploy Queues<span class=\"heading-hash pl-2 text-italic text-bold\" aria-hidden=\"true\"><\/span><\/a><\/h4>\n<p>During peak work hours, multiple developers are often trying to deploy their changes to production. To avoid confusion and give everyone a fair chance, we can ask Hubot to add us to the deployment queue.<\/p>\n<div class=\"chat\" style=\"margin: 30px 0\">\n<div class=\"message self\"><img src=\"https:\/\/avatars.githubusercontent.com\/u\/2567?v=4&s=22\" srcset=\"https:\/\/avatars.githubusercontent.com\/u\/2567?v=4&s=22 1x, https:\/\/avatars.githubusercontent.com\/u\/2567?v=4&s=44 2x, https:\/\/avatars.githubusercontent.com\/u\/2567?v=4&s=88 4x\" class=\"avatar avatar-small\" alt=\"tmm1\" \/><br \/>\n<b class=\"author\">tmm1<\/b><\/p>\n<div class=\"entry\">\/queue me for github<\/div>\n<\/div>\n<div class=\"message mentioned robot\"><img src=\"https:\/\/avatars.githubusercontent.com\/u\/480938?v=4&s=22\" srcset=\"https:\/\/avatars.githubusercontent.com\/u\/480938?v=4&s=22 1x, https:\/\/avatars.githubusercontent.com\/u\/480938?v=4&s=44 2x, https:\/\/avatars.githubusercontent.com\/u\/480938?v=4&s=88 4x\" class=\"avatar avatar-small\" alt=\"hubot\" \/><br \/>\n<b class=\"author\">Hubot<\/b><\/p>\n<div class=\"entry\">tmm1: Ok, I added you to the queue for github. There are 3 people ahead of you.<\/div>\n<\/div>\n<\/div>\n<p>We can also check the status of the queue, to deploy directly if it&#8217;s empty or to find a less busy time if it&#8217;s looking particularly full.<\/p>\n<div class=\"chat\" style=\"margin: 30px 0\">\n<div class=\"message self\"><img src=\"https:\/\/avatars.githubusercontent.com\/u\/2567?v=4&s=22\" srcset=\"https:\/\/avatars.githubusercontent.com\/u\/2567?v=4&s=22 1x, https:\/\/avatars.githubusercontent.com\/u\/2567?v=4&s=44 2x, https:\/\/avatars.githubusercontent.com\/u\/2567?v=4&s=88 4x\" class=\"avatar avatar-small\" alt=\"tmm1\" \/><br \/>\n<b class=\"author\">tmm1<\/b><\/p>\n<div class=\"entry\">\/queue for github<\/div>\n<\/div>\n<div class=\"message mentioned robot\"><img src=\"https:\/\/avatars.githubusercontent.com\/u\/480938?v=4&s=22\" srcset=\"https:\/\/avatars.githubusercontent.com\/u\/480938?v=4&s=22 1x, https:\/\/avatars.githubusercontent.com\/u\/480938?v=4&s=44 2x, https:\/\/avatars.githubusercontent.com\/u\/480938?v=4&s=88 4x\" class=\"avatar avatar-small\" alt=\"hubot\" \/><br \/>\n<b class=\"author\">Hubot<\/b><\/p>\n<div class=\"entry\">tmm1: The current queue for github: mastahyeti, aroben, bhuga<\/div>\n<\/div>\n<\/div>\n<p>We can also unqueue ourselves if something comes up and we have to step away from the computer.<\/p>\n<div class=\"chat\" style=\"margin: 30px 0\">\n<div class=\"message self\"><img src=\"https:\/\/avatars.githubusercontent.com\/u\/2567?v=4&s=22\" srcset=\"https:\/\/avatars.githubusercontent.com\/u\/2567?v=4&s=22 1x, https:\/\/avatars.githubusercontent.com\/u\/2567?v=4&s=44 2x, https:\/\/avatars.githubusercontent.com\/u\/2567?v=4&s=88 4x\" class=\"avatar avatar-small\" alt=\"tmm1\" \/><br \/>\n<b class=\"author\">tmm1<\/b><\/p>\n<div class=\"entry\">\/unqueue me for github<\/div>\n<\/div>\n<div class=\"message mentioned robot\"><img src=\"https:\/\/avatars.githubusercontent.com\/u\/480938?v=4&s=22\" srcset=\"https:\/\/avatars.githubusercontent.com\/u\/480938?v=4&s=22 1x, https:\/\/avatars.githubusercontent.com\/u\/480938?v=4&s=44 2x, https:\/\/avatars.githubusercontent.com\/u\/480938?v=4&s=88 4x\" class=\"avatar avatar-small\" alt=\"hubot\" \/><br \/>\n<b class=\"author\">Hubot<\/b><\/p>\n<div class=\"entry\">tmm1: Ok, tmm1 isn&#8217;t in the github queue anymore.<\/div>\n<\/div>\n<\/div>\n<h4 id=\"deploy-guards\"><a class=\"heading-link\" href=\"#deploy-guards\">Deploy Guards<span class=\"heading-hash pl-2 text-italic text-bold\" aria-hidden=\"true\"><\/span><\/a><\/h4>\n<p>To ensure bad code cannot make it to production, Hubot won&#8217;t let us deploy a branch until continuous integration tests have run. This prevents trigger-finger deploys while CI is still running.<\/p>\n<div class=\"chat\" style=\"margin: 30px 0\">\n<div class=\"message self\"><img src=\"https:\/\/avatars.githubusercontent.com\/u\/2567?v=4&s=22\" srcset=\"https:\/\/avatars.githubusercontent.com\/u\/2567?v=4&s=22 1x, https:\/\/avatars.githubusercontent.com\/u\/2567?v=4&s=44 2x, https:\/\/avatars.githubusercontent.com\/u\/2567?v=4&s=88 4x\" class=\"avatar avatar-small\" alt=\"tmm1\" \/><br \/>\n<b class=\"author\">tmm1<\/b><\/p>\n<div class=\"entry\">\/deploy github\/my-feature to production<\/div>\n<\/div>\n<div class=\"message robot mentioned\"><img src=\"https:\/\/avatars.githubusercontent.com\/u\/480938?v=4&s=22\" srcset=\"https:\/\/avatars.githubusercontent.com\/u\/480938?v=4&s=22 1x, https:\/\/avatars.githubusercontent.com\/u\/480938?v=4&s=44 2x, https:\/\/avatars.githubusercontent.com\/u\/480938?v=4&s=88 4x\" class=\"avatar avatar-small\" alt=\"hubot\" \/><br \/>\n<b class=\"author\">Hubot<\/b><\/p>\n<div class=\"entry\">tmm1: Sorry, I couldn&#8217;t deploy github\/my-feature: <span class=\"link\">github<\/span> and <span class=\"link\">enterprise<\/span> are still building.<\/div>\n<\/div>\n<\/div>\n<p>Similarly, if CI completed but our branch failed some tests, Hubot will prevent us from deploying.<\/p>\n<div class=\"chat\" style=\"margin: 30px 0\">\n<div class=\"message self\"><img src=\"https:\/\/avatars.githubusercontent.com\/u\/2567?v=4&s=22\" srcset=\"https:\/\/avatars.githubusercontent.com\/u\/2567?v=4&s=22 1x, https:\/\/avatars.githubusercontent.com\/u\/2567?v=4&s=44 2x, https:\/\/avatars.githubusercontent.com\/u\/2567?v=4&s=88 4x\" class=\"avatar avatar-small\" alt=\"tmm1\" \/><br \/>\n<b class=\"author\">tmm1<\/b><\/p>\n<div class=\"entry\">\/deploy github\/my-feature to production<\/div>\n<\/div>\n<div class=\"message robot mentioned\"><img src=\"https:\/\/avatars.githubusercontent.com\/u\/480938?v=4&s=22\" srcset=\"https:\/\/avatars.githubusercontent.com\/u\/480938?v=4&s=22 1x, https:\/\/avatars.githubusercontent.com\/u\/480938?v=4&s=44 2x, https:\/\/avatars.githubusercontent.com\/u\/480938?v=4&s=88 4x\" class=\"avatar avatar-small\" alt=\"hubot\" \/><br \/>\n<b class=\"author\">Hubot<\/b><\/p>\n<div class=\"entry\">tmm1: Sorry, I couldn&#8217;t deploy github\/my-feature: <span class=\"link\">github<\/span> and <span class=\"link\">enterprise<\/span> failed to build.<\/div>\n<\/div>\n<\/div>\n<p>Since <code>master<\/code> is our stable release branch, we want to ensure that any branches being deployed are caught up with the latest code in <code>master<\/code>. Before proceeding with a deployment, Hubot will detect if our branch is behind and automatically merge in <code>master<\/code> if required.<\/p>\n<div class=\"chat\" style=\"margin: 30px 0\">\n<div class=\"message self\"><img src=\"https:\/\/avatars.githubusercontent.com\/u\/2567?v=4&s=22\" srcset=\"https:\/\/avatars.githubusercontent.com\/u\/2567?v=4&s=22 1x, https:\/\/avatars.githubusercontent.com\/u\/2567?v=4&s=44 2x, https:\/\/avatars.githubusercontent.com\/u\/2567?v=4&s=88 4x\" class=\"avatar avatar-small\" alt=\"tmm1\" \/><br \/>\n<b class=\"author\">tmm1<\/b><\/p>\n<div class=\"entry\">\/deploy github\/my-feature to production<\/div>\n<\/div>\n<div class=\"message robot github\">\n<div class=\"entry\">\nAuto-merged master into my-feature on deployment &#8211; Aman Gupta ( <span class=\"link\">github\/github@feedface<\/span> )<\/div>\n<div class=\"entry success\">Build <span class=\"link\">#2077391<\/span> (feedface) of github\/my-feature was successful (97s, queued 0s)<\/div>\n<div class=\"entry success\">Build <span class=\"link\">#2077392<\/span> (feedface) of enterprise\/my-feature was successful (106s, queued 0s)<\/div>\n<div class=\"entry\">tmm1 is <span class=\"link\">deploying<\/span> github\/my-feature (<span class=\"link\">feedface<\/span>) to production.<\/div>\n<div class=\"entry success\">tmm1&#8217;s production <span class=\"link\">deployment<\/span> of github\/my-feature (feedface) is done! (100s)<\/div>\n<\/div>\n<\/div>\n<p>To ensure deployments are visible to the rest of the team, Hubot forces us to deploy from specific chat rooms.<\/p>\n<div class=\"chat\" style=\"margin: 30px 0\">\n<div class=\"message self\"><img src=\"https:\/\/avatars.githubusercontent.com\/u\/2567?v=4&s=22\" srcset=\"https:\/\/avatars.githubusercontent.com\/u\/2567?v=4&s=22 1x, https:\/\/avatars.githubusercontent.com\/u\/2567?v=4&s=44 2x, https:\/\/avatars.githubusercontent.com\/u\/2567?v=4&s=88 4x\" class=\"avatar avatar-small\" alt=\"tmm1\" \/><br \/>\n<b class=\"author\">tmm1<\/b><\/p>\n<div class=\"entry\">\/deploy github\/my-feature to production<\/div>\n<\/div>\n<div class=\"message robot mentioned\"><img src=\"https:\/\/avatars.githubusercontent.com\/u\/480938?v=4&s=22\" srcset=\"https:\/\/avatars.githubusercontent.com\/u\/480938?v=4&s=22 1x, https:\/\/avatars.githubusercontent.com\/u\/480938?v=4&s=44 2x, https:\/\/avatars.githubusercontent.com\/u\/480938?v=4&s=88 4x\" class=\"avatar avatar-small\" alt=\"hubot\" \/><br \/>\n<b class=\"author\">Hubot<\/b><\/p>\n<div class=\"entry\">tmm1: Sorry, github must be deployed from the appropriate room.<\/div>\n<\/div>\n<\/div>\n<p>In rare emergency situations, it is possible to override these guards using <code>\/deploy!<\/code>.<\/p>\n<h4 id=\"deploy-locks\"><a class=\"heading-link\" href=\"#deploy-locks\">Deploy Locks<span class=\"heading-hash pl-2 text-italic text-bold\" aria-hidden=\"true\"><\/span><\/a><\/h4>\n<p>As soon as a branch is deployed, Hubot locks the environment so no other branches can be deployed to it. This prevents others from accidentally deploying while a developer is testing their branch.<\/p>\n<div class=\"chat\" style=\"margin: 30px 0\">\n<div class=\"message self\"><img src=\"https:\/\/avatars.githubusercontent.com\/u\/2567?v=4&s=22\" srcset=\"https:\/\/avatars.githubusercontent.com\/u\/2567?v=4&s=22 1x, https:\/\/avatars.githubusercontent.com\/u\/2567?v=4&s=44 2x, https:\/\/avatars.githubusercontent.com\/u\/2567?v=4&s=88 4x\" class=\"avatar avatar-small\" alt=\"tmm1\" \/><br \/>\n<b class=\"author\">tmm1<\/b><\/p>\n<div class=\"entry\">\/deploy github\/my-feature to production<\/div>\n<\/div>\n<div class=\"message robot mentioned\"><img src=\"https:\/\/avatars.githubusercontent.com\/u\/480938?v=4&s=22\" srcset=\"https:\/\/avatars.githubusercontent.com\/u\/480938?v=4&s=22 1x, https:\/\/avatars.githubusercontent.com\/u\/480938?v=4&s=44 2x, https:\/\/avatars.githubusercontent.com\/u\/480938?v=4&s=88 4x\" class=\"avatar avatar-small\" alt=\"hubot\" \/><br \/>\n<b class=\"author\">Hubot<\/b><\/p>\n<div class=\"entry\">tmm1: Sorry, github in production is locked by mastahyeti<\/div>\n<\/div>\n<\/div>\n<p>Once we&#8217;ve merged our branch, Hubot will automatically unlock the environment and let the next person in the queue know they can deploy.<\/p>\n<div class=\"chat\" style=\"margin: 30px 0\">\n<div class=\"message robot\"><img src=\"https:\/\/avatars.githubusercontent.com\/u\/480938?v=4&s=22\" srcset=\"https:\/\/avatars.githubusercontent.com\/u\/480938?v=4&s=22 1x, https:\/\/avatars.githubusercontent.com\/u\/480938?v=4&s=44 2x, https:\/\/avatars.githubusercontent.com\/u\/480938?v=4&s=88 4x\" class=\"avatar avatar-small\" alt=\"hubot\" \/><br \/>\n<b class=\"author\">Hubot<\/b><\/p>\n<div class=\"entry\">mastahyeti: it looks like you merged the &#8220;stronger-ssh-keys&#8221; branch into master, so I&#8217;ve unlocked github in production.<\/div>\n<\/div>\n<div class=\"message robot mentioned\"><img src=\"https:\/\/avatars.githubusercontent.com\/u\/480938?v=4&s=22\" srcset=\"https:\/\/avatars.githubusercontent.com\/u\/480938?v=4&s=22 1x, https:\/\/avatars.githubusercontent.com\/u\/480938?v=4&s=44 2x, https:\/\/avatars.githubusercontent.com\/u\/480938?v=4&s=88 4x\" class=\"avatar avatar-small\" alt=\"hubot\" \/><br \/>\n<b class=\"author\">Hubot<\/b><\/p>\n<div class=\"entry\">tmm1: you&#8217;re up to deploy github!<\/div>\n<\/div>\n<\/div>\n<p>We can also manually unlock deploys to let someone else have a turn, when we decide not to merge our branch just yet.<\/p>\n<div class=\"chat\" style=\"margin: 30px 0\">\n<div class=\"message self\"><img src=\"https:\/\/avatars.githubusercontent.com\/u\/2567?v=4&s=22\" srcset=\"https:\/\/avatars.githubusercontent.com\/u\/2567?v=4&s=22 1x, https:\/\/avatars.githubusercontent.com\/u\/2567?v=4&s=44 2x, https:\/\/avatars.githubusercontent.com\/u\/2567?v=4&s=88 4x\" class=\"avatar avatar-small\" alt=\"tmm1\" \/><br \/>\n<b class=\"author\">tmm1<\/b><\/p>\n<div class=\"entry\">\/unlock github in prod<\/div>\n<\/div>\n<div class=\"message robot mentioned\"><img src=\"https:\/\/avatars.githubusercontent.com\/u\/480938?v=4&s=22\" srcset=\"https:\/\/avatars.githubusercontent.com\/u\/480938?v=4&s=22 1x, https:\/\/avatars.githubusercontent.com\/u\/480938?v=4&s=44 2x, https:\/\/avatars.githubusercontent.com\/u\/480938?v=4&s=88 4x\" class=\"avatar avatar-small\" alt=\"hubot\" \/><br \/>\n<b class=\"author\">Hubot<\/b><\/p>\n<div class=\"entry\">tmm1: github in production is now unlocked.<\/div>\n<\/div>\n<\/div>\n<p>Finally, during outages, attacks, and other emergency situations, we can lock deployments manually to prevent changes while we investigate problems.<\/p>\n<div class=\"chat\" style=\"margin: 30px 0\">\n<div class=\"message self\"><img src=\"https:\/\/avatars.githubusercontent.com\/u\/2567?v=4&s=22\" srcset=\"https:\/\/avatars.githubusercontent.com\/u\/2567?v=4&s=22 1x, https:\/\/avatars.githubusercontent.com\/u\/2567?v=4&s=44 2x, https:\/\/avatars.githubusercontent.com\/u\/2567?v=4&s=88 4x\" class=\"avatar avatar-small\" alt=\"tmm1\" \/><br \/>\n<b class=\"author\">tmm1<\/b><\/p>\n<div class=\"entry\">\/lock github in production investigating deployment api 500s<\/div>\n<\/div>\n<div class=\"message robot mentioned\"><img src=\"https:\/\/avatars.githubusercontent.com\/u\/480938?v=4&s=22\" srcset=\"https:\/\/avatars.githubusercontent.com\/u\/480938?v=4&s=22 1x, https:\/\/avatars.githubusercontent.com\/u\/480938?v=4&s=44 2x, https:\/\/avatars.githubusercontent.com\/u\/480938?v=4&s=88 4x\" class=\"avatar avatar-small\" alt=\"hubot\" \/><br \/>\n<b class=\"author\">Hubot<\/b><\/p>\n<div class=\"entry\">tmm1: github in production is now locked.<\/div>\n<\/div>\n<\/div>\n<h4 id=\"deploy-environments\"><a class=\"heading-link\" href=\"#deploy-environments\">Deploy Environments<span class=\"heading-hash pl-2 text-italic text-bold\" aria-hidden=\"true\"><\/span><\/a><\/h4>\n<p>In addition to the main production environment, we can deploy to staging servers that are only accessible by GitHub staff. This staging environment closely mirrors our production environment, including real-world datasets to ensure high-fidelity testing.<\/p>\n<p>To find out what environments are available for deployments, we can ask Hubot for a list and see which ones are currently unlocked.<\/p>\n<div class=\"chat\" style=\"margin: 30px 0\">\n<div class=\"message self\"><img src=\"https:\/\/avatars.githubusercontent.com\/u\/2567?v=4&s=22\" srcset=\"https:\/\/avatars.githubusercontent.com\/u\/2567?v=4&s=22 1x, https:\/\/avatars.githubusercontent.com\/u\/2567?v=4&s=44 2x, https:\/\/avatars.githubusercontent.com\/u\/2567?v=4&s=88 4x\" class=\"avatar avatar-small\" alt=\"tmm1\" \/><br \/>\n<b class=\"author\">tmm1<\/b><\/p>\n<div class=\"entry\">\/where can i deploy github<\/div>\n<\/div>\n<div class=\"message robot\"><img src=\"https:\/\/avatars.githubusercontent.com\/u\/480938?v=4&s=22\" srcset=\"https:\/\/avatars.githubusercontent.com\/u\/480938?v=4&s=22 1x, https:\/\/avatars.githubusercontent.com\/u\/480938?v=4&s=44 2x, https:\/\/avatars.githubusercontent.com\/u\/480938?v=4&s=88 4x\" class=\"avatar avatar-small\" alt=\"hubot\" \/><br \/>\n<b class=\"author\">Hubot<\/b><\/p>\n<div class=\"entry\">\n<pre><code>Deployment status for github:\n--------------------------------------------------------------------------------\nproduction: locked 42 seconds ago by grantr: testing the code-search-docvalues branch\nlab: locked 15 minutes ago by tmm1: testing the git-repld-reconcile-full-resync branch\ngarage: unlocked\nspider-skull-island: locked 13 minutes ago by grantr: testing the code-search-docvalues branch\nmachine-room: locked 20 hours ago by haileys: testing the upgrade-route-syntax branch\nbranch-lab: always available\n\nThe queue for production has 1 person waiting.<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<p>The lab, garage and other staging environments each replicate different aspects of production: frontend web workers, background job queues, CDN setup for assets, Git fileserver workers, etc. Depending on what part of the stack a branch touches, we can pick a matching staging environment to exercise the new code without affecting production user traffic.<\/p>\n<p>One of these environments is a special &#8220;branch lab&#8221; which does not require locking, because it sets up an isolated sandbox for each branch. This helps avoid deploy lock contention and lets developers and designers deploy experimental UI changes as shareable URLs they can send to others in the company for feedback.<\/p>\n<div class=\"chat\" style=\"margin: 30px 0\">\n<div class=\"message self\"><img src=\"https:\/\/avatars.githubusercontent.com\/u\/2567?v=4&s=22\" srcset=\"https:\/\/avatars.githubusercontent.com\/u\/2567?v=4&s=22 1x, https:\/\/avatars.githubusercontent.com\/u\/2567?v=4&s=44 2x, https:\/\/avatars.githubusercontent.com\/u\/2567?v=4&s=88 4x\" class=\"avatar avatar-small\" alt=\"tmm1\" \/><br \/>\n<b class=\"author\">tmm1<\/b><\/p>\n<div class=\"entry\">\/deploy github\/my-feature to branch-lab<\/div>\n<\/div>\n<div class=\"message robot github\">\n<div class=\"entry\">tmm1 is <span class=\"link\">deploying<\/span> github\/my-feature (<span class=\"link\">feedface<\/span>) to branch-lab.<br \/>\nReview the <span class=\"link\">deployment checklist<\/span> before deploying to production.<\/div>\n<div class=\"entry success\">tmm1&#8217;s branch-lab <span class=\"link\">deployment<\/span> of github\/my-feature (feedface) is done! (22s)<\/div>\n<\/div>\n<div class=\"message robot mentioned\"><img src=\"https:\/\/avatars.githubusercontent.com\/u\/480938?v=4&s=22\" srcset=\"https:\/\/avatars.githubusercontent.com\/u\/480938?v=4&s=22 1x, https:\/\/avatars.githubusercontent.com\/u\/480938?v=4&s=44 2x, https:\/\/avatars.githubusercontent.com\/u\/480938?v=4&s=88 4x\" class=\"avatar avatar-small\" alt=\"hubot\" \/><br \/>\n<b class=\"author\">Hubot<\/b><\/p>\n<div class=\"entry\">tmm1: your branch-lab is available at <span class=\"link\">https:\/\/my-feature.branch.github.com<\/span><\/div>\n<\/div>\n<\/div>\n<p>The branch lab is implemented as a single staging server which runs one unicorn worker per branch. The branches deployed there can be listed via chat, and a branch can be deleted once it&#8217;s no longer being used. If the free memory on that server starts to run out, we automatically prune the oldest branches to free up some space.<\/p>\n<div class=\"chat\" style=\"margin: 30px 0\">\n<div class=\"message self\"><img src=\"https:\/\/avatars.githubusercontent.com\/u\/2567?v=4&s=22\" srcset=\"https:\/\/avatars.githubusercontent.com\/u\/2567?v=4&s=22 1x, https:\/\/avatars.githubusercontent.com\/u\/2567?v=4&s=44 2x, https:\/\/avatars.githubusercontent.com\/u\/2567?v=4&s=88 4x\" class=\"avatar avatar-small\" alt=\"tmm1\" \/><br \/>\n<b class=\"author\">tmm1<\/b><\/p>\n<div class=\"entry\">\/branch-lab list<\/div>\n<\/div>\n<div class=\"message robot\"><img src=\"https:\/\/avatars.githubusercontent.com\/u\/480938?v=4&s=22\" srcset=\"https:\/\/avatars.githubusercontent.com\/u\/480938?v=4&s=22 1x, https:\/\/avatars.githubusercontent.com\/u\/480938?v=4&s=44 2x, https:\/\/avatars.githubusercontent.com\/u\/480938?v=4&s=88 4x\" class=\"avatar avatar-small\" alt=\"hubot\" \/><br \/>\n<b class=\"author\">Hubot<\/b><\/p>\n<div class=\"entry\">\n<pre><code>+------------------------------+----------------+----------------+--------------------------------------------------------+\n|                            branch-lab (9 branches, disk: 14G used + 91G free, mem: 3G free)                             |\n+------------------------------+----------------+----------------+--------------------------------------------------------+\n| octicons-playground          | aaronshekey    |    2 hours ago | https:\/\/octicons-playground.branch.github.com          |\n| move-audit-log               | amosie         |    5 hours ago | https:\/\/move-audit-log.branch.github.com               |\n| nh-audit-log-docs            | nickh          |    5 hours ago | https:\/\/nh-audit-log-docs.branch.github.com            |\n| show-lfs-even-if-over        | tclem          |    6 hours ago | https:\/\/show-lfs-even-if-over.branch.github.com        |\n| js-clone-selector            | dgraham        |    7 hours ago | https:\/\/js-clone-selector.branch.github.com            |\n| clear-user-session-for-oauth | ptoomey3       |    7 hours ago | https:\/\/clear-user-session-for-oauth.branch.github.com |\n| remove-wizard                | amosie         |   11 hours ago | https:\/\/remove-wizard.branch.github.com                |\n| mobile-file-finder           | tmm1           |   18 hours ago | https:\/\/mobile-file-finder.branch.github.com           |\n| ship-header-nav              | mdo            |   22 hours ago | https:\/\/ship-header-nav.branch.github.com              |\n+------------------------------+----------------+----------------+--------------------------------------------------------+<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<p>We can also manually remove branches that we&#8217;re done testing, or have shipped to production already:<\/p>\n<div class=\"chat\" style=\"margin: 30px 0\">\n<div class=\"message self\"><img src=\"https:\/\/avatars.githubusercontent.com\/u\/2567?v=4&s=22\" srcset=\"https:\/\/avatars.githubusercontent.com\/u\/2567?v=4&s=22 1x, https:\/\/avatars.githubusercontent.com\/u\/2567?v=4&s=44 2x, https:\/\/avatars.githubusercontent.com\/u\/2567?v=4&s=88 4x\" class=\"avatar avatar-small\" alt=\"tmm1\" \/><br \/>\n<b class=\"author\">tmm1<\/b><\/p>\n<div class=\"entry\">\/branch-lab remove my-feature<\/div>\n<\/div>\n<div class=\"message robot\"><img src=\"https:\/\/avatars.githubusercontent.com\/u\/480938?v=4&s=22\" srcset=\"https:\/\/avatars.githubusercontent.com\/u\/480938?v=4&s=22 1x, https:\/\/avatars.githubusercontent.com\/u\/480938?v=4&s=44 2x, https:\/\/avatars.githubusercontent.com\/u\/480938?v=4&s=88 4x\" class=\"avatar avatar-small\" alt=\"hubot\" \/><br \/>\n<b class=\"author\">Hubot<\/b><\/p>\n<div class=\"entry\">Removing my-feature from branch-lab<\/div>\n<\/div>\n<\/div>\n<h4 id=\"deploy-targets\"><a class=\"heading-link\" href=\"#deploy-targets\">Deploy Targets<span class=\"heading-hash pl-2 text-italic text-bold\" aria-hidden=\"true\"><\/span><\/a><\/h4>\n<p>Once a branch has passed automated tests, undergone code-review, and been verified in staging, it comes time to push it into production. Recall that GitHub engineers are not allowed to merge any pull request that has not yet been verified in production. Production traffic patterns and datasets often trigger edge-cases that expose bugs and performance issues which might not have been seen otherwise, and we want to ensure that our <code>master<\/code> branch always represents our stable production release.<\/p>\n<p>To safely roll out a risky branch, we can ask Hubot to deploy it to a specific subset of servers within an environment. This limits the user impact of the change, and allows us to monitor for new exceptions or performance regressions coming from the servers that are running our branch.<\/p>\n<p>A change to the Rails version for example can be deployed to one or two frontend webservers, and if things look good we can continue to deploy it to more frontends. Similarly, an upgraded version of Git could be deployed to a handful of backend fileservers.<\/p>\n<div class=\"chat\" style=\"margin: 30px 0\">\n<div class=\"message self\"><img src=\"https:\/\/avatars.githubusercontent.com\/u\/2567?v=4&s=22\" srcset=\"https:\/\/avatars.githubusercontent.com\/u\/2567?v=4&s=22 1x, https:\/\/avatars.githubusercontent.com\/u\/2567?v=4&s=44 2x, https:\/\/avatars.githubusercontent.com\/u\/2567?v=4&s=88 4x\" class=\"avatar avatar-small\" alt=\"tmm1\" \/><br \/>\n<b class=\"author\">tmm1<\/b><\/p>\n<div class=\"entry\">\/deploy github\/rails-6-upgrade to production\/fe130,fe131<\/div>\n<\/div>\n<div class=\"message robot github\"><img src=\"https:\/\/avatars.githubusercontent.com\/u\/480938?v=4&s=22\" srcset=\"https:\/\/avatars.githubusercontent.com\/u\/480938?v=4&s=22 1x, https:\/\/avatars.githubusercontent.com\/u\/480938?v=4&s=44 2x, https:\/\/avatars.githubusercontent.com\/u\/480938?v=4&s=88 4x\" class=\"avatar avatar-small\" alt=\"hubot\" \/><\/p>\n<div class=\"entry\">tmm1 is <span class=\"link\">deploying<\/span> github\/rails-6-upgrade (<span class=\"link\">feedbeef<\/span>) to production (github-fe130-cp1-prd, github-fe131-cp1-prd).<\/div>\n<div class=\"entry success\">tmm1&#8217;s production <span class=\"link\">deployment<\/span> of github\/rails-6-upgrade (feedbeef) is done! (46s)<\/div>\n<\/div>\n<div class=\"message robot mentioned\"><img src=\"https:\/\/avatars.githubusercontent.com\/u\/480938?v=4&s=22\" srcset=\"https:\/\/avatars.githubusercontent.com\/u\/480938?v=4&s=22 1x, https:\/\/avatars.githubusercontent.com\/u\/480938?v=4&s=44 2x, https:\/\/avatars.githubusercontent.com\/u\/480938?v=4&s=88 4x\" class=\"avatar avatar-small\" alt=\"hubot\" \/><br \/>\n<b class=\"author\">Hubot<\/b><\/p>\n<div class=\"entry\">Exceptions have recently elevated on github (12 exceptions) in the last 3 minutes. tmm1 was the last person to deploy at 07:40 pm PDT (-0700). Care to check it out in haystack?<\/div>\n<\/div>\n<\/div>\n<p>Once we&#8217;ve gained confidence in our branch, we can deploy it to all of production and then merge it to unlock deployments for the next developer in the queue.<\/p>\n<h4 id=\"deploy-everything\"><a class=\"heading-link\" href=\"#deploy-everything\">Deploy Everything<span class=\"heading-hash pl-2 text-italic text-bold\" aria-hidden=\"true\"><\/span><\/a><\/h4>\n<p>Our deployment chatops and workflows work so well that we use them for everything in the company. If we want to add a DNS record, we make a pull request to github\/dns and use <code>\/deploy dns<\/code>. If we want to add a monitoring alert for a new service, we make a pull request to github\/nagios and use <code>\/deploy nagios<\/code>. If we want to install a new software package on a specific frontend, we use <code>\/deploy puppet\/add-package-branch to prod\/fe142<\/code>. We even use similar workflows to ship new versions of our <a href=\"https:\/\/github.com\/blog\/1271-how-we-ship-github-for-windows\">native desktop apps<\/a>.<\/p>\n<p>If you aren&#8217;t already, we highly recommend you try some of the techniques mentioned in this blog post. This workflow brings a ton of great benefits, including:<\/p>\n<ul>\n<li>Low training overhead &#8211; every time you deploy, you&#8217;re training the next person who is watching the chat transcript.<\/li>\n<li>Deep integration into <a href=\"https:\/\/github.com\/atmos\/hubot-deploy\">chat<\/a> and the <a href=\"https:\/\/developer.github.com\/v3\/repos\/deployments\/\">GitHub API<\/a> means everyone in the company has visibility into deployments.<\/li>\n<li>The process is so lightweight we can use it even for a tiny 1 line change, making code review much more likely to happen.<\/li>\n<li>Frequent feedback on small ships ensures nobody spends two weeks on a bad approach.<\/li>\n<li>Merge conflicts are rare and trivial when they arise, despite our monolithic architecture.<\/li>\n<li>The process gives developers ownership, agency, quick wins, and meaningful responsibility. These are what developer happiness is all about.<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>At GitHub, we use a variant of the Flow pattern to deploy changes: new code is always deployed from a pull request branch, and merged only once it has been&hellip;<\/p>\n","protected":false},"author":1516,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_gh_post_show_toc":"no","_gh_post_is_no_robots":"no","_gh_post_is_featured":"no","_gh_post_is_excluded":"no","_gh_post_is_unlisted":"no","_gh_post_related_link_1":"","_gh_post_related_link_2":"","_gh_post_related_link_3":"","_gh_post_sq_img":"","_gh_post_sq_img_id":"","_gh_post_cta_title":"","_gh_post_cta_text":"","_gh_post_cta_link":"","_gh_post_cta_button":"Click Here to Learn More","_gh_post_recirc_hide":"no","_gh_post_recirc_col_1":"gh-auto-select","_gh_post_recirc_col_2":"77524","_gh_post_recirc_col_3":"65303","_gh_post_recirc_col_4":"65316","_featured_video":"","_gh_post_additional_query_params":"","_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2},"_wpas_customize_per_network":false,"_links_to":"","_links_to_target":""},"categories":[72,3308],"tags":[],"coauthors":[2239],"class_list":["post-14","post","type-post","status-publish","format-standard","hentry","category-engineering","category-engineering-principles"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v27.3 (Yoast SEO v27.3) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Deploying branches to GitHub.com - The GitHub Blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/github.blog\/engineering\/engineering-principles\/deploying-branches-to-github-com\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Deploying branches to GitHub.com\" \/>\n<meta property=\"og:description\" content=\"At GitHub, we use a variant of the Flow pattern to deploy changes: new code is always deployed from a pull request branch, and merged only once it has been&hellip;\" \/>\n<meta property=\"og:url\" content=\"https:\/\/github.blog\/engineering\/engineering-principles\/deploying-branches-to-github-com\/\" \/>\n<meta property=\"og:site_name\" content=\"The GitHub Blog\" \/>\n<meta property=\"article:published_time\" content=\"2015-06-02T07:00:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-06-17T15:31:24+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/cloud.githubusercontent.com\/assets\/2567\/7905866\/37331f22-085b-11e5-94dc-e245cd9efed1.png\" \/>\n<meta name=\"author\" content=\"Aman Gupta\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Aman Gupta\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"8 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/github.blog\\\/engineering\\\/engineering-principles\\\/deploying-branches-to-github-com\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/github.blog\\\/engineering\\\/engineering-principles\\\/deploying-branches-to-github-com\\\/\"},\"author\":{\"name\":\"Aman Gupta\",\"@id\":\"https:\\\/\\\/github.blog\\\/#\\\/schema\\\/person\\\/b6022d80f91af93848f0bc1f4964dea7\"},\"headline\":\"Deploying branches to GitHub.com\",\"datePublished\":\"2015-06-02T07:00:00+00:00\",\"dateModified\":\"2024-06-17T15:31:24+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/github.blog\\\/engineering\\\/engineering-principles\\\/deploying-branches-to-github-com\\\/\"},\"wordCount\":1709,\"image\":{\"@id\":\"https:\\\/\\\/github.blog\\\/engineering\\\/engineering-principles\\\/deploying-branches-to-github-com\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/cloud.githubusercontent.com\\\/assets\\\/2567\\\/7905866\\\/37331f22-085b-11e5-94dc-e245cd9efed1.png\",\"articleSection\":[\"Engineering\",\"Engineering principles\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/github.blog\\\/engineering\\\/engineering-principles\\\/deploying-branches-to-github-com\\\/\",\"url\":\"https:\\\/\\\/github.blog\\\/engineering\\\/engineering-principles\\\/deploying-branches-to-github-com\\\/\",\"name\":\"Deploying branches to GitHub.com - The GitHub Blog\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/github.blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/github.blog\\\/engineering\\\/engineering-principles\\\/deploying-branches-to-github-com\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/github.blog\\\/engineering\\\/engineering-principles\\\/deploying-branches-to-github-com\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/cloud.githubusercontent.com\\\/assets\\\/2567\\\/7905866\\\/37331f22-085b-11e5-94dc-e245cd9efed1.png\",\"datePublished\":\"2015-06-02T07:00:00+00:00\",\"dateModified\":\"2024-06-17T15:31:24+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/github.blog\\\/#\\\/schema\\\/person\\\/b6022d80f91af93848f0bc1f4964dea7\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/github.blog\\\/engineering\\\/engineering-principles\\\/deploying-branches-to-github-com\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/github.blog\\\/engineering\\\/engineering-principles\\\/deploying-branches-to-github-com\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/github.blog\\\/engineering\\\/engineering-principles\\\/deploying-branches-to-github-com\\\/#primaryimage\",\"url\":\"https:\\\/\\\/cloud.githubusercontent.com\\\/assets\\\/2567\\\/7905866\\\/37331f22-085b-11e5-94dc-e245cd9efed1.png\",\"contentUrl\":\"https:\\\/\\\/cloud.githubusercontent.com\\\/assets\\\/2567\\\/7905866\\\/37331f22-085b-11e5-94dc-e245cd9efed1.png\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/github.blog\\\/engineering\\\/engineering-principles\\\/deploying-branches-to-github-com\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/github.blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Engineering\",\"item\":\"https:\\\/\\\/github.blog\\\/engineering\\\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Engineering principles\",\"item\":\"https:\\\/\\\/github.blog\\\/engineering\\\/engineering-principles\\\/\"},{\"@type\":\"ListItem\",\"position\":4,\"name\":\"Deploying branches to GitHub.com\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/github.blog\\\/#website\",\"url\":\"https:\\\/\\\/github.blog\\\/\",\"name\":\"The GitHub Blog\",\"description\":\"Updates, ideas, and inspiration from GitHub to help developers build and design software.\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/github.blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/github.blog\\\/#\\\/schema\\\/person\\\/b6022d80f91af93848f0bc1f4964dea7\",\"name\":\"Aman Gupta\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/0c4d7caf2538a56cb0ee01ec6fe9b9b2adc1f1682cf7d696aa11ea27a4ee11d7?s=96&d=mm&r=g8a71bf84f84f95e424922ced35647a3f\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/0c4d7caf2538a56cb0ee01ec6fe9b9b2adc1f1682cf7d696aa11ea27a4ee11d7?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/0c4d7caf2538a56cb0ee01ec6fe9b9b2adc1f1682cf7d696aa11ea27a4ee11d7?s=96&d=mm&r=g\",\"caption\":\"Aman Gupta\"},\"sameAs\":[\"http:\\\/\\\/twitter.com\\\/tmm1\"],\"url\":\"https:\\\/\\\/github.blog\\\/author\\\/tmm1\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Deploying branches to GitHub.com - The GitHub Blog","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/github.blog\/engineering\/engineering-principles\/deploying-branches-to-github-com\/","og_locale":"en_US","og_type":"article","og_title":"Deploying branches to GitHub.com","og_description":"At GitHub, we use a variant of the Flow pattern to deploy changes: new code is always deployed from a pull request branch, and merged only once it has been&hellip;","og_url":"https:\/\/github.blog\/engineering\/engineering-principles\/deploying-branches-to-github-com\/","og_site_name":"The GitHub Blog","article_published_time":"2015-06-02T07:00:00+00:00","article_modified_time":"2024-06-17T15:31:24+00:00","og_image":[{"url":"https:\/\/cloud.githubusercontent.com\/assets\/2567\/7905866\/37331f22-085b-11e5-94dc-e245cd9efed1.png","type":"","width":"","height":""}],"author":"Aman Gupta","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Aman Gupta","Est. reading time":"8 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/github.blog\/engineering\/engineering-principles\/deploying-branches-to-github-com\/#article","isPartOf":{"@id":"https:\/\/github.blog\/engineering\/engineering-principles\/deploying-branches-to-github-com\/"},"author":{"name":"Aman Gupta","@id":"https:\/\/github.blog\/#\/schema\/person\/b6022d80f91af93848f0bc1f4964dea7"},"headline":"Deploying branches to GitHub.com","datePublished":"2015-06-02T07:00:00+00:00","dateModified":"2024-06-17T15:31:24+00:00","mainEntityOfPage":{"@id":"https:\/\/github.blog\/engineering\/engineering-principles\/deploying-branches-to-github-com\/"},"wordCount":1709,"image":{"@id":"https:\/\/github.blog\/engineering\/engineering-principles\/deploying-branches-to-github-com\/#primaryimage"},"thumbnailUrl":"https:\/\/cloud.githubusercontent.com\/assets\/2567\/7905866\/37331f22-085b-11e5-94dc-e245cd9efed1.png","articleSection":["Engineering","Engineering principles"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/github.blog\/engineering\/engineering-principles\/deploying-branches-to-github-com\/","url":"https:\/\/github.blog\/engineering\/engineering-principles\/deploying-branches-to-github-com\/","name":"Deploying branches to GitHub.com - The GitHub Blog","isPartOf":{"@id":"https:\/\/github.blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/github.blog\/engineering\/engineering-principles\/deploying-branches-to-github-com\/#primaryimage"},"image":{"@id":"https:\/\/github.blog\/engineering\/engineering-principles\/deploying-branches-to-github-com\/#primaryimage"},"thumbnailUrl":"https:\/\/cloud.githubusercontent.com\/assets\/2567\/7905866\/37331f22-085b-11e5-94dc-e245cd9efed1.png","datePublished":"2015-06-02T07:00:00+00:00","dateModified":"2024-06-17T15:31:24+00:00","author":{"@id":"https:\/\/github.blog\/#\/schema\/person\/b6022d80f91af93848f0bc1f4964dea7"},"breadcrumb":{"@id":"https:\/\/github.blog\/engineering\/engineering-principles\/deploying-branches-to-github-com\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/github.blog\/engineering\/engineering-principles\/deploying-branches-to-github-com\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/github.blog\/engineering\/engineering-principles\/deploying-branches-to-github-com\/#primaryimage","url":"https:\/\/cloud.githubusercontent.com\/assets\/2567\/7905866\/37331f22-085b-11e5-94dc-e245cd9efed1.png","contentUrl":"https:\/\/cloud.githubusercontent.com\/assets\/2567\/7905866\/37331f22-085b-11e5-94dc-e245cd9efed1.png"},{"@type":"BreadcrumbList","@id":"https:\/\/github.blog\/engineering\/engineering-principles\/deploying-branches-to-github-com\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/github.blog\/"},{"@type":"ListItem","position":2,"name":"Engineering","item":"https:\/\/github.blog\/engineering\/"},{"@type":"ListItem","position":3,"name":"Engineering principles","item":"https:\/\/github.blog\/engineering\/engineering-principles\/"},{"@type":"ListItem","position":4,"name":"Deploying branches to GitHub.com"}]},{"@type":"WebSite","@id":"https:\/\/github.blog\/#website","url":"https:\/\/github.blog\/","name":"The GitHub Blog","description":"Updates, ideas, and inspiration from GitHub to help developers build and design software.","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/github.blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/github.blog\/#\/schema\/person\/b6022d80f91af93848f0bc1f4964dea7","name":"Aman Gupta","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/0c4d7caf2538a56cb0ee01ec6fe9b9b2adc1f1682cf7d696aa11ea27a4ee11d7?s=96&d=mm&r=g8a71bf84f84f95e424922ced35647a3f","url":"https:\/\/secure.gravatar.com\/avatar\/0c4d7caf2538a56cb0ee01ec6fe9b9b2adc1f1682cf7d696aa11ea27a4ee11d7?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/0c4d7caf2538a56cb0ee01ec6fe9b9b2adc1f1682cf7d696aa11ea27a4ee11d7?s=96&d=mm&r=g","caption":"Aman Gupta"},"sameAs":["http:\/\/twitter.com\/tmm1"],"url":"https:\/\/github.blog\/author\/tmm1\/"}]}},"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/pamS32-e","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/github.blog\/wp-json\/wp\/v2\/posts\/14","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/github.blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/github.blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/github.blog\/wp-json\/wp\/v2\/users\/1516"}],"replies":[{"embeddable":true,"href":"https:\/\/github.blog\/wp-json\/wp\/v2\/comments?post=14"}],"version-history":[{"count":3,"href":"https:\/\/github.blog\/wp-json\/wp\/v2\/posts\/14\/revisions"}],"predecessor-version":[{"id":78419,"href":"https:\/\/github.blog\/wp-json\/wp\/v2\/posts\/14\/revisions\/78419"}],"wp:attachment":[{"href":"https:\/\/github.blog\/wp-json\/wp\/v2\/media?parent=14"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/github.blog\/wp-json\/wp\/v2\/categories?post=14"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/github.blog\/wp-json\/wp\/v2\/tags?post=14"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/github.blog\/wp-json\/wp\/v2\/coauthors?post=14"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}