{"id":54887,"date":"2020-10-22T13:07:50","date_gmt":"2020-10-22T20:07:50","guid":{"rendered":"https:\/\/github.blog\/?p=54887"},"modified":"2021-08-18T14:41:09","modified_gmt":"2021-08-18T21:41:09","slug":"devops-best-practices-qa-automated-deployments-at-github","status":"publish","type":"post","link":"https:\/\/github.blog\/enterprise-software\/devops\/devops-best-practices-qa-automated-deployments-at-github\/","title":{"rendered":"DevOps best practices Q&amp;A: Automated deployments at GitHub"},"content":{"rendered":"<p><i><a href=\"https:\/\/resources.github.com\/devops\">DevOps<\/a> success looks different for everyone. But like open source, sharing best practices helps us all build better software. In this Q&amp;A, <\/i><a href=\"https:\/\/github.com\/rnkaufman\"><i>Nina Kaufman<\/i><\/a><i>, Senior Software Engineer on GitHub\u2019s Deploy Team, explains how automation ensures code gets deployed to github.com safely and reliably. <\/i><\/p>\n<hr \/>\n<h2 id=\"what-is-the-github-deploy-team-and-what-is-your-role\"><a class=\"heading-link\" href=\"#what-is-the-github-deploy-team-and-what-is-your-role\"><b>What is the GitHub Deploy Team, and what is your role?\u00a0<\/b><span class=\"heading-hash pl-2 text-italic text-bold\" aria-hidden=\"true\"><\/span><\/a><\/h2>\n<p>I\u2019m a software engineer, but you could also call me an infrastructure engineer. Aside from myself, our team is made up of five other engineers, a manager, and one product manager. Day to day, our biggest goal is ensuring our teams across GitHub can deploy with a high velocity, safely and securely to github.com.<\/p>\n<p>We support hundreds of engineers, as well as hundreds of applications that are being deployed 24\/7. For github.com alone, we have between 120 and 150 deploys a week just to production and in the past week we shipped 421 pull requests within those deploys.<\/p>\n<h2 id=\"walk-us-through-an-automated-deployment-where-does-everything-start\"><a class=\"heading-link\" href=\"#walk-us-through-an-automated-deployment-where-does-everything-start\"><b>Walk us through an automated deployment. Where does everything start?\u00a0<\/b><span class=\"heading-hash pl-2 text-italic text-bold\" aria-hidden=\"true\"><\/span><\/a><\/h2>\n<p>Ultimately, we push code to production on our own GitHub cloud platform, on our data centers, utilizing features provided by the GitHub UI and API along the way. The deployment process can be initiated with ChatOps, a series of <a href=\"https:\/\/hubot.github.com\/\">Hubot<\/a> commands. They enable us to automate all sorts of workflows and have a pretty simple interface for people to engage with in order to roll out their changes.<\/p>\n<p>When folks have a change that they&#8217;d like to ship or deploy to github.com, they just need to run <code>.deploy<\/code> with a link to their pull request and the system will automatically deconstruct what&#8217;s within that link, using GitHub&#8217;s API for understanding important details such as the required CI checks, authorization, and authentication. Once the deployment has progressed through a series of stages\u2014which we will talk about in more detail later\u2014you&#8217;re able to merge your pull request in GitHub, and from there you can continue on with your day, continue making improvements, and shipping features. The system will know exactly how to deploy it, which servers are involved, and what systems to run. The person running the command has no need to know that it&#8217;s all happening. Before any changes are made, we run a series of authentication processes to ensure a user even has the right access to run these commands.<\/p>\n<h2 id=\"what-happens-behind-the-developer-facing-workflow-to-ensure-things-deploy-reliably-to-production\"><a class=\"heading-link\" href=\"#what-happens-behind-the-developer-facing-workflow-to-ensure-things-deploy-reliably-to-production\"><b>What happens behind the developer-facing workflow to ensure things deploy reliably to production?\u00a0<\/b><span class=\"heading-hash pl-2 text-italic text-bold\" aria-hidden=\"true\"><\/span><\/a><\/h2>\n<p>After you hit <code>.deploy<\/code> and your changes go through a series of stages, we use <a href=\"https:\/\/martinfowler.com\/bliki\/CanaryRelease.html\">canary deployments<\/a> (Canary) to gradually roll out and verify new functionality before sending the changes to full production. Canary is a smaller subset of our production hosts that contains a new change, so that if there\u2019s a breaking change, not everyone will encounter the error. It would only be a very small percentage of servers.<\/p>\n<p>During deployment, you can look at a series of dashboards to monitor for errors. You can drill in and see how your change is making an impact on users; if it\u2019s increasing errors, or if it has engagement, things like that. You\u2019re able to get a pretty good grasp on what you\u2019re shipping and the impact it has during the deployment process since it rolls out changes a bit at a time, not all at once.<\/p>\n<h2 id=\"how-do-you-measure-your-teams-success-and-impact\"><a class=\"heading-link\" href=\"#how-do-you-measure-your-teams-success-and-impact\"><b>How do you measure your team\u2019s success and impact?<\/b><span class=\"heading-hash pl-2 text-italic text-bold\" aria-hidden=\"true\"><\/span><\/a><\/h2>\n<p>Our team has a set of service level objectives (SLOs) defined, so we have metrics that we measure our success for deployment time, local development setup time, and more. We also have developer satisfaction surveys that we conduct internally, as well as interviews to measure the way folks perceive deployments and ways to improve. We\u2019re always looking back at those metrics to see where we can improve and make changes to our process.<\/p>\n<p>One of the other things that we look at is the number of rollbacks that we do over a period of time, or how often we ship something that ends up breaking or not performing in the way we expect. We found that our rate of rollbacks was fairly low. Folks were generally shipping changes that look good, are successful, and perform as everyone expects and intends them to. In this\u00a0 case, we could shift to a culture of trust around saying, \u201cHey, developers know what they&#8217;re shipping. It&#8217;s been tested. They&#8217;re going to make sure that things work.\u201d Then, generally it can progress and go to a full rollout with minimal intervention, if any at all. At this point, the people who are shipping can just merge their changes.<\/p>\n<h2 id=\"along-with-automation-what-impact-does-this-culture-of-trust-have-on-the-organization-and-the-developer-experience\"><a class=\"heading-link\" href=\"#along-with-automation-what-impact-does-this-culture-of-trust-have-on-the-organization-and-the-developer-experience\"><b><\/b><b>Along with automation, what impact does this \u201cculture of trust\u201d have on the organization and the developer experience?\u00a0<\/b><span class=\"heading-hash pl-2 text-italic text-bold\" aria-hidden=\"true\"><\/span><\/a><\/h2>\n<p>We&#8217;re doing the same number of deployments as we did several years ago, but with our adoption of batched changes, increased automation, and canary deploys, we&#8217;ve actually increased throughput. Previously, we deployed around 150 deployments a week. Now we batch a lot more changes together than we used to, so while we&#8217;re still doing roughly the same <i>amount<\/i> of deployments, we&#8217;re shipping <i>more<\/i> changes on each deploy.<\/p>\n<p>There\u2019s less wait time to get your changes out, and it also means that you have a greater confidence level that your changes are going to play nicely with other people&#8217;s changes. Since we\u2019re shipping hundreds of pull requests\u2014over 400 in a single week\u2014you want to make sure that your changes are compatible with as many others at a given time as possible, and we don\u2019t want folks to wait hours in line to be able to ship a change.<\/p>\n<h2 id=\"what-devops-best-practices-or-advice-would-you-recommend-to-teams-who-want-to-improve-their-process-workflow-or-developer-experience\"><a class=\"heading-link\" href=\"#what-devops-best-practices-or-advice-would-you-recommend-to-teams-who-want-to-improve-their-process-workflow-or-developer-experience\"><b>What DevOps best practices or advice would you recommend to teams who want to improve their process, workflow, or developer experience?\u00a0<\/b><span class=\"heading-hash pl-2 text-italic text-bold\" aria-hidden=\"true\"><\/span><\/a><\/h2>\n<p>I would recommend treating infrastructure as a product and treating internal users as if they were external. Implement developer surveys, satisfaction scores, and interview people across the organization to see what pain points they have, or what a day in their life would look like. Having the empathy to understand the problems of other engineers within the organization can definitely improve the product. Sometimes as a result of surveys or interviews, you might find responses that are surprising or hard to hear, but it ultimately makes for a much better product.<\/p>\n<p>We use an <a href=\"https:\/\/measuringu.com\/microsoft-nsat\/\">NSAT score<\/a> to measure our satisfaction internally. From May 2020 to September 2020, we committed to raising that score even more. We still have many improvements to make, but this took an entire company-wide effort. It brought greater harmony between our feature teams and our infrastructure teams, so we integrated folks on the user-facing teams and we brought them in with infrastructure. We asked, \u201cHow would you like to improve the deploy interface and how would you like to see these things happen?\u201d Even though those folks don&#8217;t do infrastructure day to day, we gained valuable insights from their experience with customer-facing products. We were able to work together to make UI\/UX changes that improved shipping velocity, reduced support hours spent debugging deploy-related issues, and ultimately increased developer satisfaction.<\/p>\n<p>Another thing that&#8217;s really useful is unifying and simplifying the tools and processes that you have so that folks don&#8217;t need to worry about finding them. At GitHub, we rely on GitHub itself for everything. We use it for our authentication and for ensuring that folks have access to the right things to be able to run certain commands. We use project management on GitHub, <a href=\"https:\/\/github.com\/features\/actions\">GitHub Actions<\/a>, and all sorts of different tools. Going back to the idea of treating it like an external product, it\u2019s important to have discoverable documentation for any internal APIs, dedicated support channels, and first-class customer support in the same way you would have for anyone outside the company.<\/p>\n<h2 id=\"at-the-end-of-the-day-successful-devops-comes-down-to-people-not-processes-how-does-your-team-stay-connected\"><a class=\"heading-link\" href=\"#at-the-end-of-the-day-successful-devops-comes-down-to-people-not-processes-how-does-your-team-stay-connected\"><b>At the end of the day, successful DevOps comes down to people, not processes. How does your team stay connected?\u00a0<\/b><span class=\"heading-hash pl-2 text-italic text-bold\" aria-hidden=\"true\"><\/span><\/a><\/h2>\n<p>GitHub is a global company. We have folks on my team in Berlin, Vancouver, and all over the US. Going out of our way to come together and keep up with one another is really important because the team camaraderie and overall gratification of working with one another will push and propel a lot of the features forward more quickly than they would otherwise. We do bi-weekly coffee chats, book clubs, and art chats where people share their projects to stay connected.<\/p>\n<p>Sometimes I wake up and check notifications on my GitHub issues, and it feels like waking up on my birthday. If I ran into a problem and documented it, someone in Berlin will take it and fix it while I\u2019m asleep. To me, it doesn&#8217;t feel like I&#8217;m isolated because there&#8217;s always an ongoing conversation. There are always updates to see when I wake up. We\u2019re always deploying GitHub, always improving it.<\/p>\n<p><script type=\"application\/ld+json\">{\"@context\":\"https:\/\/schema.org\",\"@type\":\"FAQPage\",\"mainEntity\":[{\"@type\":\"Question\",\"name\":\"What is the GitHub Deploy Team, and what is your role? \",\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"I'm a software engineer, but you could also call me an infrastructure engineer. Aside from myself, our team is made up of five other engineers, a manager, and one product manager. Day to day, our biggest goal is ensuring our teams across GitHub can deploy with a high velocity, safely and securely to github.com.\\n\\nWe support hundreds of engineers, as well as hundreds of applications that are being deployed 24\/7. For github.com alone, we have between 120 and 150 deploys a week just to production and in the past week we shipped 421 pull requests within those deploys.\\n\"}},{\"@type\":\"Question\",\"name\":\"Walk us through an automated deployment. Where does everything start? \",\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"Ultimately, we push code to production on our own GitHub cloud platform, on our data centers, utilizing features provided by the GitHub UI and API along the way. The deployment process can be initiated with ChatOps, a series of Hubot commands. They enable us to automate all sorts of workflows and have a pretty simple interface for people to engage with in order to roll out their changes.\\n\\nWhen folks have a change that they'd like to ship or deploy to github.com, they just need to run `.deploy` with a link to their pull request and the system will automatically deconstruct what's within that link, using GitHub's API for understanding important details such as the required CI checks, authorization, and authentication. Once the deployment has progressed through a series of stages\u2014which we will talk about in more detail later\u2014you're able to merge your pull request in GitHub, and from there you can continue on with your day, continue making improvements, and shipping features. The system will know exactly how to deploy it, which servers are involved, and what systems to run. The person running the command has no need to know that it's all happening. Before any changes are made, we run a series of authentication processes to ensure a user even has the right access to run these commands.\\n\"}},{\"@type\":\"Question\",\"name\":\"What happens behind the developer-facing workflow to ensure things deploy reliably to production? \",\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"After you hit `.deploy` and your changes go through a series of stages, we use canary deployments (Canary) to gradually roll out and verify new functionality before sending the changes to full production. Canary is a smaller subset of our production hosts that contains a new change, so that if there's a breaking change, not everyone will encounter the error. It would only be a very small percentage of servers.\\n\\nDuring deployment, you can look at a series of dashboards to monitor for errors. You can drill in and see how your change is making an impact on users; if it's increasing errors, or if it has engagement, things like that. You're able to get a pretty good grasp on what you're shipping and the impact it has during the deployment process since it rolls out changes a bit at a time, not all at once. \\n\"}},{\"@type\":\"Question\",\"name\":\"How do you measure your team's success and impact?\",\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"Our team has a set of service level objectives (SLOs) defined, so we have metrics that we measure our success for deployment time, local development setup time, and more. We also have developer satisfaction surveys that we conduct internally, as well as interviews to\\nmeasure the way folks perceive deployments and ways to improve. We're always\\nlooking back at those metrics to see where we can improve and make changes to our\\nprocess. \\n\\nOne of the other things that we look at is the number of rollbacks that we do over a period of time, or how often we ship something that ends up breaking or not performing in the way we expect. We found that our rate of rollbacks was fairly low. Folks were generally shipping changes that look good, are successful, and perform as everyone expects and intends them to. In this  case, we could shift to a culture of trust around saying, \"Hey, developers know what they're shipping. It's been tested. They're going to make sure that things work.\" Then, generally it can progress and go to a full rollout with minimal intervention, if any at all. At this point, the people who are shipping can just merge their changes.\"}},{\"@type\":\"Question\",\"name\":\"Along with automation, what impact does this \"culture of trust\" have on the organization and the developer experience? \",\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"We're doing the same number of deployments as we did several years ago, but with our adoption of batched changes, increased automation, and canary deploys, we've actually increased throughput. Previously, we deployed around 150 deployments a week. Now we batch a lot more changes together than we used to, so while we're still doing roughly the same amount of deployments, we're shipping more changes on each deploy. \\n\\nThere's less wait time to get your changes out, and it also means that you have a greater confidence level that your changes are going to play nicely with other people's changes. Since we're shipping hundreds of pull requests\u2014over 400 in a single week\u2014you want to make sure that your changes are compatible with as many others at a given time as possible, and we don't\\nwant folks to wait hours in line to be able to ship a change.\\n\"}},{\"@type\":\"Question\",\"name\":\"What DevOps best practices or advice would you recommend to teams who want to improve their process, workflow, or developer experience? \",\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"I would recommend treating infrastructure as a product and treating internal users as if they were external. Implement developer surveys, satisfaction scores, and interview people across the organization to see what pain points they have, or what a day in their life would look like. Having the empathy to understand the problems of other engineers within the organization can definitely improve the product. Sometimes as a result of surveys or interviews, you might find responses that are surprising or hard to hear, but it ultimately makes for a much better product.\\n\\nWe use an NSAT score to measure our satisfaction internally. From May 2020 to September 2020, we committed to raising that score even more. We still have many improvements to make, but this took an entire company-wide effort. It brought greater harmony between our feature teams and our infrastructure teams, so we integrated folks on the user-facing teams and we brought them in with infrastructure. We asked, \"How would you like to improve the deploy interface and how would you like to see these things happen?\" Even though those folks don't do infrastructure day to day, we gained valuable insights from their experience with customer-facing products. We were able to work together to make UI\/UX changes that improved shipping velocity, reduced support hours spent debugging deploy-related issues, and ultimately increased developer satisfaction.\\n\\nAnother thing that's really useful is unifying and simplifying the tools and processes that you have so that folks don't need to worry about finding them. At GitHub, we rely on GitHub itself for everything. We use it for our authentication and for ensuring that folks have access to the right things to be able to run certain commands. We use project management on GitHub, GitHub Actions, and all sorts of different tools. Going back to the idea of treating it like an external product, it's important to have discoverable documentation for any internal APIs, dedicated support channels, and first-class customer support in the same way you would have for anyone outside the company. \"}},{\"@type\":\"Question\",\"name\":\"At the end of the day, successful DevOps comes down to people, not processes. How does your team stay connected? \",\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"\"}}]}<\/script><\/p>\n","protected":false},"excerpt":{"rendered":"<p>How GitHub measures and improves reliability, security, and developer happiness with automated deployments.<\/p>\n","protected":false},"author":1270,"featured_media":54892,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_gh_post_show_toc":"","_gh_post_is_no_robots":"","_gh_post_is_featured":"","_gh_post_is_excluded":"","_gh_post_is_unlisted":"","_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":"","_gh_post_recirc_hide":"","_gh_post_recirc_col_1":"","_gh_post_recirc_col_2":"","_gh_post_recirc_col_3":"","_gh_post_recirc_col_4":"","_featured_video":"","_gh_post_additional_query_params":"","_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_feature_clip_id":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"{title}\n\n{excerpt}\n\n{url}","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,"jetpack_post_was_ever_published":false,"_links_to":"","_links_to_target":""},"categories":[3317,3313],"tags":[],"coauthors":[],"class_list":["post-54887","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-devops","category-enterprise-software"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v27.7 (Yoast SEO v27.7) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>DevOps best practices Q&amp;A: Automated deployments at GitHub - 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\/enterprise-software\/devops\/devops-best-practices-qa-automated-deployments-at-github\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"DevOps best practices Q&amp;A: Automated deployments at GitHub\" \/>\n<meta property=\"og:description\" content=\"How GitHub measures and improves reliability, security, and developer happiness with automated deployments.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/github.blog\/enterprise-software\/devops\/devops-best-practices-qa-automated-deployments-at-github\/\" \/>\n<meta property=\"og:site_name\" content=\"The GitHub Blog\" \/>\n<meta property=\"article:published_time\" content=\"2020-10-22T20:07:50+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2021-08-18T21:41:09+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/github.blog\/wp-content\/uploads\/2020\/10\/96791358-28389980-13ad-11eb-848c-bc23632decc9-1.png?fit=1200%2C630\" \/>\n\t<meta property=\"og:image:width\" content=\"1200\" \/>\n\t<meta property=\"og:image:height\" content=\"630\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Grace Madlinger\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:image\" content=\"https:\/\/github.blog\/wp-content\/uploads\/2020\/10\/96791358-28389980-13ad-11eb-848c-bc23632decc9-1.png?fit=1200%2C630\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Grace Madlinger\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"7 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/github.blog\\\/enterprise-software\\\/devops\\\/devops-best-practices-qa-automated-deployments-at-github\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/github.blog\\\/enterprise-software\\\/devops\\\/devops-best-practices-qa-automated-deployments-at-github\\\/\"},\"author\":{\"name\":\"Grace Madlinger\",\"@id\":\"https:\\\/\\\/github.blog\\\/#\\\/schema\\\/person\\\/a56f02fc284136b4ac30429c8ea846ce\"},\"headline\":\"DevOps best practices Q&amp;A: Automated deployments at GitHub\",\"datePublished\":\"2020-10-22T20:07:50+00:00\",\"dateModified\":\"2021-08-18T21:41:09+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/github.blog\\\/enterprise-software\\\/devops\\\/devops-best-practices-qa-automated-deployments-at-github\\\/\"},\"wordCount\":1494,\"image\":{\"@id\":\"https:\\\/\\\/github.blog\\\/enterprise-software\\\/devops\\\/devops-best-practices-qa-automated-deployments-at-github\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/github.blog\\\/wp-content\\\/uploads\\\/2020\\\/10\\\/96792315-26300400-13c8-11eb-8c02-d9be6941b8e6.png?fit=2415%2C1270\",\"articleSection\":[\"DevOps\",\"Enterprise software\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/github.blog\\\/enterprise-software\\\/devops\\\/devops-best-practices-qa-automated-deployments-at-github\\\/\",\"url\":\"https:\\\/\\\/github.blog\\\/enterprise-software\\\/devops\\\/devops-best-practices-qa-automated-deployments-at-github\\\/\",\"name\":\"DevOps best practices Q&amp;A: Automated deployments at GitHub - The GitHub Blog\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/github.blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/github.blog\\\/enterprise-software\\\/devops\\\/devops-best-practices-qa-automated-deployments-at-github\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/github.blog\\\/enterprise-software\\\/devops\\\/devops-best-practices-qa-automated-deployments-at-github\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/github.blog\\\/wp-content\\\/uploads\\\/2020\\\/10\\\/96792315-26300400-13c8-11eb-8c02-d9be6941b8e6.png?fit=2415%2C1270\",\"datePublished\":\"2020-10-22T20:07:50+00:00\",\"dateModified\":\"2021-08-18T21:41:09+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/github.blog\\\/#\\\/schema\\\/person\\\/a56f02fc284136b4ac30429c8ea846ce\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/github.blog\\\/enterprise-software\\\/devops\\\/devops-best-practices-qa-automated-deployments-at-github\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/github.blog\\\/enterprise-software\\\/devops\\\/devops-best-practices-qa-automated-deployments-at-github\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/github.blog\\\/enterprise-software\\\/devops\\\/devops-best-practices-qa-automated-deployments-at-github\\\/#primaryimage\",\"url\":\"https:\\\/\\\/github.blog\\\/wp-content\\\/uploads\\\/2020\\\/10\\\/96792315-26300400-13c8-11eb-8c02-d9be6941b8e6.png?fit=2415%2C1270\",\"contentUrl\":\"https:\\\/\\\/github.blog\\\/wp-content\\\/uploads\\\/2020\\\/10\\\/96792315-26300400-13c8-11eb-8c02-d9be6941b8e6.png?fit=2415%2C1270\",\"width\":2415,\"height\":1270},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/github.blog\\\/enterprise-software\\\/devops\\\/devops-best-practices-qa-automated-deployments-at-github\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/github.blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Enterprise software\",\"item\":\"https:\\\/\\\/github.blog\\\/enterprise-software\\\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"DevOps\",\"item\":\"https:\\\/\\\/github.blog\\\/enterprise-software\\\/devops\\\/\"},{\"@type\":\"ListItem\",\"position\":4,\"name\":\"DevOps best practices Q&amp;A: Automated deployments at GitHub\"}]},{\"@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\\\/a56f02fc284136b4ac30429c8ea846ce\",\"name\":\"Grace Madlinger\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/60eda2feb07571ecac8140aecc08be845873c4fde8bc9a7562b64886f462cf10?s=96&d=mm&r=g8d0a29f32831fdb18774f82f4c3cf85a\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/60eda2feb07571ecac8140aecc08be845873c4fde8bc9a7562b64886f462cf10?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/60eda2feb07571ecac8140aecc08be845873c4fde8bc9a7562b64886f462cf10?s=96&d=mm&r=g\",\"caption\":\"Grace Madlinger\"},\"url\":\"https:\\\/\\\/github.blog\\\/author\\\/gmadlinger\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"DevOps best practices Q&amp;A: Automated deployments at GitHub - 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\/enterprise-software\/devops\/devops-best-practices-qa-automated-deployments-at-github\/","og_locale":"en_US","og_type":"article","og_title":"DevOps best practices Q&amp;A: Automated deployments at GitHub","og_description":"How GitHub measures and improves reliability, security, and developer happiness with automated deployments.","og_url":"https:\/\/github.blog\/enterprise-software\/devops\/devops-best-practices-qa-automated-deployments-at-github\/","og_site_name":"The GitHub Blog","article_published_time":"2020-10-22T20:07:50+00:00","article_modified_time":"2021-08-18T21:41:09+00:00","og_image":[{"width":1200,"height":630,"url":"https:\/\/github.blog\/wp-content\/uploads\/2020\/10\/96791358-28389980-13ad-11eb-848c-bc23632decc9-1.png?fit=1200%2C630","type":"image\/png"}],"author":"Grace Madlinger","twitter_card":"summary_large_image","twitter_image":"https:\/\/github.blog\/wp-content\/uploads\/2020\/10\/96791358-28389980-13ad-11eb-848c-bc23632decc9-1.png?fit=1200%2C630","twitter_misc":{"Written by":"Grace Madlinger","Est. reading time":"7 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/github.blog\/enterprise-software\/devops\/devops-best-practices-qa-automated-deployments-at-github\/#article","isPartOf":{"@id":"https:\/\/github.blog\/enterprise-software\/devops\/devops-best-practices-qa-automated-deployments-at-github\/"},"author":{"name":"Grace Madlinger","@id":"https:\/\/github.blog\/#\/schema\/person\/a56f02fc284136b4ac30429c8ea846ce"},"headline":"DevOps best practices Q&amp;A: Automated deployments at GitHub","datePublished":"2020-10-22T20:07:50+00:00","dateModified":"2021-08-18T21:41:09+00:00","mainEntityOfPage":{"@id":"https:\/\/github.blog\/enterprise-software\/devops\/devops-best-practices-qa-automated-deployments-at-github\/"},"wordCount":1494,"image":{"@id":"https:\/\/github.blog\/enterprise-software\/devops\/devops-best-practices-qa-automated-deployments-at-github\/#primaryimage"},"thumbnailUrl":"https:\/\/github.blog\/wp-content\/uploads\/2020\/10\/96792315-26300400-13c8-11eb-8c02-d9be6941b8e6.png?fit=2415%2C1270","articleSection":["DevOps","Enterprise software"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/github.blog\/enterprise-software\/devops\/devops-best-practices-qa-automated-deployments-at-github\/","url":"https:\/\/github.blog\/enterprise-software\/devops\/devops-best-practices-qa-automated-deployments-at-github\/","name":"DevOps best practices Q&amp;A: Automated deployments at GitHub - The GitHub Blog","isPartOf":{"@id":"https:\/\/github.blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/github.blog\/enterprise-software\/devops\/devops-best-practices-qa-automated-deployments-at-github\/#primaryimage"},"image":{"@id":"https:\/\/github.blog\/enterprise-software\/devops\/devops-best-practices-qa-automated-deployments-at-github\/#primaryimage"},"thumbnailUrl":"https:\/\/github.blog\/wp-content\/uploads\/2020\/10\/96792315-26300400-13c8-11eb-8c02-d9be6941b8e6.png?fit=2415%2C1270","datePublished":"2020-10-22T20:07:50+00:00","dateModified":"2021-08-18T21:41:09+00:00","author":{"@id":"https:\/\/github.blog\/#\/schema\/person\/a56f02fc284136b4ac30429c8ea846ce"},"breadcrumb":{"@id":"https:\/\/github.blog\/enterprise-software\/devops\/devops-best-practices-qa-automated-deployments-at-github\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/github.blog\/enterprise-software\/devops\/devops-best-practices-qa-automated-deployments-at-github\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/github.blog\/enterprise-software\/devops\/devops-best-practices-qa-automated-deployments-at-github\/#primaryimage","url":"https:\/\/github.blog\/wp-content\/uploads\/2020\/10\/96792315-26300400-13c8-11eb-8c02-d9be6941b8e6.png?fit=2415%2C1270","contentUrl":"https:\/\/github.blog\/wp-content\/uploads\/2020\/10\/96792315-26300400-13c8-11eb-8c02-d9be6941b8e6.png?fit=2415%2C1270","width":2415,"height":1270},{"@type":"BreadcrumbList","@id":"https:\/\/github.blog\/enterprise-software\/devops\/devops-best-practices-qa-automated-deployments-at-github\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/github.blog\/"},{"@type":"ListItem","position":2,"name":"Enterprise software","item":"https:\/\/github.blog\/enterprise-software\/"},{"@type":"ListItem","position":3,"name":"DevOps","item":"https:\/\/github.blog\/enterprise-software\/devops\/"},{"@type":"ListItem","position":4,"name":"DevOps best practices Q&amp;A: Automated deployments at GitHub"}]},{"@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\/a56f02fc284136b4ac30429c8ea846ce","name":"Grace Madlinger","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/60eda2feb07571ecac8140aecc08be845873c4fde8bc9a7562b64886f462cf10?s=96&d=mm&r=g8d0a29f32831fdb18774f82f4c3cf85a","url":"https:\/\/secure.gravatar.com\/avatar\/60eda2feb07571ecac8140aecc08be845873c4fde8bc9a7562b64886f462cf10?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/60eda2feb07571ecac8140aecc08be845873c4fde8bc9a7562b64886f462cf10?s=96&d=mm&r=g","caption":"Grace Madlinger"},"url":"https:\/\/github.blog\/author\/gmadlinger\/"}]}},"jetpack_publicize_connections":[],"jetpack_featured_media_url":"https:\/\/github.blog\/wp-content\/uploads\/2020\/10\/96792315-26300400-13c8-11eb-8c02-d9be6941b8e6.png?fit=2415%2C1270","jetpack_shortlink":"https:\/\/wp.me\/pamS32-ehh","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/github.blog\/wp-json\/wp\/v2\/posts\/54887","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\/1270"}],"replies":[{"embeddable":true,"href":"https:\/\/github.blog\/wp-json\/wp\/v2\/comments?post=54887"}],"version-history":[{"count":10,"href":"https:\/\/github.blog\/wp-json\/wp\/v2\/posts\/54887\/revisions"}],"predecessor-version":[{"id":59571,"href":"https:\/\/github.blog\/wp-json\/wp\/v2\/posts\/54887\/revisions\/59571"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/github.blog\/wp-json\/wp\/v2\/media\/54892"}],"wp:attachment":[{"href":"https:\/\/github.blog\/wp-json\/wp\/v2\/media?parent=54887"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/github.blog\/wp-json\/wp\/v2\/categories?post=54887"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/github.blog\/wp-json\/wp\/v2\/tags?post=54887"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/github.blog\/wp-json\/wp\/v2\/coauthors?post=54887"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}