{"id":116,"date":"2009-12-30T15:51:28","date_gmt":"2009-12-30T15:51:28","guid":{"rendered":"https:\/\/simpleprogrammer.com\/?p=116"},"modified":"2013-07-27T18:47:47","modified_gmt":"2013-07-27T22:47:47","slug":"continuous-integration-best-practices","status":"publish","type":"post","link":"https:\/\/simpleprogrammer.com\/continuous-integration-best-practices\/","title":{"rendered":"Continuous Integration Best Practices"},"content":{"rendered":"<p>In my <a href=\"https:\/\/simpleprogrammer.com\/2009\/12\/23\/do-you-ci-seeing-u-ciing-continuous-integration\/\">earlier post<\/a>, I talked about why you need to start using continuous integration and need a continuous integration server. In this post I will look more at continuous integration best practices when you have a continuous integration server set up.<\/p>\n<p><strong>Unit tests<\/strong><\/p>\n<p>One of the first things your continuous integration server needs to\u00a0do is to run and report on your unit tests as part of the build. \u00a0It is not really a good enough quality checkpoint to make sure that the code simply compiles without errors. \u00a0Your unit tests should be executed as part of every build. \u00a0Every time someone checks in code you want to know that unit tests have not broken. \u00a0Along with this I will include code coverage reports. \u00a0It is very useful to have your code coverage reported by your continuous integration server for the code coverage metrics on your unit tests.<\/p>\n<p><strong>Static Analysis Tools<\/strong><\/p>\n<p>One of the best ways to enforce coding standards and quality standards is through the use of static analysis tools. \u00a0Depending on the language you are using there are several options available. \u00a0For Java there are tools like PMD and Checkstyle, for .NET there are tools like FxCop and StyleCop. \u00a0<a href=\"http:\/\/en.wikipedia.org\/wiki\/List_of_tools_for_static_code_analysis\">Here is a good list<\/a> of some of the ones available for each language. \u00a0There are two basic branches of static analysis tools, ones that check for formatting and convention, and ones that check for bad practices. \u00a0I would strongly suggest employing both. \u00a0Your CI server should run the static analysis tools at the end of each build and preferably track the progress of violations introduced in the build. \u00a0Some CI servers allow you to actually fail the build if an\u00a0amount or\u00a0percentage of the code has violations. I would highly recommend this for a new code base. \u00a0If you end up with a high number of violations the violations just become noise. \u00a0CI server is a good way to make this visible to everyone on the project.<\/p>\n<p><strong>Deployment<\/strong><\/p>\n<p><span style=\"text-decoration: underline;\">If deploying your code to any environment requires more than the push of a button, you&#8217;re doing it wrong.<\/span> I know this may sound like a bold statement, but why would you need to do anything more than this? \u00a0One thing I always emphasize is that the only way for a build to get to an environment is from the CI server pushing it there directly. \u00a0Basically, you should only be deploying builds that are built by the\u00a0CI server. \u00a0When you follow this practice you make sure that the code in an environment is the exact bits that you expect. \u00a0Taking a build from somewhere else is error prone and risky. \u00a0Doing a build manually is a waste of time and also risky. \u00a0Your deployment should be a simple button push which takes bits that have already been built on your CI server and deploys them to the desired\u00a0environment.<\/p>\n<p><strong>Notification<\/strong><\/p>\n<p>Perhaps the most important part of a CI server is notification when a build fails, or when it is fixed. \u00a0If you get this one wrong, you will be constantly chasing down developers breaking the build and your efforts will be in vain. \u00a0It is very important that when a build fails it is a <strong>big deal, a really BIG DEAL.<\/strong> Some teams use flashing lights, others use large\u00a0flat-screen\u00a0TVs, and others just emails, but however you do it, it must be effective and not ignored. \u00a0I would recommend at a minimum setting up an email notification when the build fails and when it is fixed. \u00a0When there is a broken build it is very important that fixing the build becomes top priority. \u00a0One of the things which can help reduce build breaks is to make sure that developers have a way to do the exact same build which will be done by the CI server. \u00a0If a developer can run the same build locally before checking in their code, there really aren&#8217;t many good excuses for breaking the build. \u00a0(This will also require that the build be very fast, in one of my earlier posts I talked about <a href=\"https:\/\/simpleprogrammer.com\/2009\/12\/03\/dedicated-developer-tools-teams\/\">having a dedicated developer tools team<\/a> to do things like\u00a0optimizing\u00a0the build.)<\/p>\n<p><strong>Database<\/strong><\/p>\n<p>I won&#8217;t go into extreme detail here about database integration, since the focus of this post is on CI best practices, but I want to make this important point. \u00a0If your database is not in some way version controlled and built with your source code, there is no point in having the ability to replicate any code build. \u00a0Basically if you cannot tie a version of the database that is also reproducible to the source code, you cannot actually roll back to a specific point in time. \u00a0For some projects this is important, for others it is not, but for all it must be considered. \u00a0Either way you should minimally consider how you will handle database integration with your CI server. \u00a0One of the solutions I have helped to employ on the project I am working on currently is to have a database build which works very similarly to the source code build and applies database changes as SQL change scripts which are applied in a certain order to build the database.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In my earlier post, I talked about why you need to start using continuous integration and need a continuous integration server. In this post I will look more at continuous integration best practices when you have a continuous integration server set up. Unit tests One of the first things your continuous integration server needs to\u00a0do&#8230;<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_kad_post_transparent":"","_kad_post_title":"","_kad_post_layout":"","_kad_post_sidebar_id":"","_kad_post_content_style":"","_kad_post_vertical_padding":"","_kad_post_feature":"","_kad_post_feature_position":"","_kad_post_header":false,"_kad_post_footer":false,"_kad_post_classname":"","footnotes":""},"categories":[163615,31679,1981],"tags":[],"class_list":["post-116","post","type-post","status-publish","format-standard","hentry","category-continuous-integration","category-process-improvement","category-tools"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.6 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Continuous Integration Best Practices<\/title>\n<meta name=\"description\" content=\"A list of items that all continuous integration builds should contain to ensure that continuous integration best practices are being implemented.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/simpleprogrammer.com\/continuous-integration-best-practices\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Continuous Integration Best Practices\" \/>\n<meta property=\"og:description\" content=\"A list of items that all continuous integration builds should contain to ensure that continuous integration best practices are being implemented.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/simpleprogrammer.com\/continuous-integration-best-practices\/\" \/>\n<meta property=\"og:site_name\" content=\"Simple Programmer\" \/>\n<meta property=\"article:published_time\" content=\"2009-12-30T15:51:28+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2013-07-27T22:47:47+00:00\" \/>\n<meta name=\"author\" content=\"John Sonmez\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"John Sonmez\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"4 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/simpleprogrammer.com\\\/continuous-integration-best-practices\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/simpleprogrammer.com\\\/continuous-integration-best-practices\\\/\"},\"author\":{\"name\":\"John Sonmez\",\"@id\":\"https:\\\/\\\/simpleprogrammer.com\\\/#\\\/schema\\\/person\\\/1abc70edfb189184827740310672de67\"},\"headline\":\"Continuous Integration Best Practices\",\"datePublished\":\"2009-12-30T15:51:28+00:00\",\"dateModified\":\"2013-07-27T22:47:47+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/simpleprogrammer.com\\\/continuous-integration-best-practices\\\/\"},\"wordCount\":877,\"commentCount\":1,\"articleSection\":[\"Continuous Integration\",\"Process Improvement\",\"Tools\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/simpleprogrammer.com\\\/continuous-integration-best-practices\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/simpleprogrammer.com\\\/continuous-integration-best-practices\\\/\",\"url\":\"https:\\\/\\\/simpleprogrammer.com\\\/continuous-integration-best-practices\\\/\",\"name\":\"Continuous Integration Best Practices\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/simpleprogrammer.com\\\/#website\"},\"datePublished\":\"2009-12-30T15:51:28+00:00\",\"dateModified\":\"2013-07-27T22:47:47+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/simpleprogrammer.com\\\/#\\\/schema\\\/person\\\/1abc70edfb189184827740310672de67\"},\"description\":\"A list of items that all continuous integration builds should contain to ensure that continuous integration best practices are being implemented.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/simpleprogrammer.com\\\/continuous-integration-best-practices\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/simpleprogrammer.com\\\/continuous-integration-best-practices\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/simpleprogrammer.com\\\/continuous-integration-best-practices\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/simpleprogrammer.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Continuous Integration Best Practices\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/simpleprogrammer.com\\\/#website\",\"url\":\"https:\\\/\\\/simpleprogrammer.com\\\/\",\"name\":\"Simple Programmer\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/simpleprogrammer.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/simpleprogrammer.com\\\/#\\\/schema\\\/person\\\/1abc70edfb189184827740310672de67\",\"name\":\"John Sonmez\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/dc2f18dfa76e017566ce607de002d7abe4acfd5ec19a6db82c180b00867b8d94?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/dc2f18dfa76e017566ce607de002d7abe4acfd5ec19a6db82c180b00867b8d94?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/dc2f18dfa76e017566ce607de002d7abe4acfd5ec19a6db82c180b00867b8d94?s=96&d=mm&r=g\",\"caption\":\"John Sonmez\"},\"url\":\"https:\\\/\\\/simpleprogrammer.com\\\/author\\\/jsonmez\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Continuous Integration Best Practices","description":"A list of items that all continuous integration builds should contain to ensure that continuous integration best practices are being implemented.","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:\/\/simpleprogrammer.com\/continuous-integration-best-practices\/","og_locale":"en_US","og_type":"article","og_title":"Continuous Integration Best Practices","og_description":"A list of items that all continuous integration builds should contain to ensure that continuous integration best practices are being implemented.","og_url":"https:\/\/simpleprogrammer.com\/continuous-integration-best-practices\/","og_site_name":"Simple Programmer","article_published_time":"2009-12-30T15:51:28+00:00","article_modified_time":"2013-07-27T22:47:47+00:00","author":"John Sonmez","twitter_card":"summary_large_image","twitter_misc":{"Written by":"John Sonmez","Est. reading time":"4 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/simpleprogrammer.com\/continuous-integration-best-practices\/#article","isPartOf":{"@id":"https:\/\/simpleprogrammer.com\/continuous-integration-best-practices\/"},"author":{"name":"John Sonmez","@id":"https:\/\/simpleprogrammer.com\/#\/schema\/person\/1abc70edfb189184827740310672de67"},"headline":"Continuous Integration Best Practices","datePublished":"2009-12-30T15:51:28+00:00","dateModified":"2013-07-27T22:47:47+00:00","mainEntityOfPage":{"@id":"https:\/\/simpleprogrammer.com\/continuous-integration-best-practices\/"},"wordCount":877,"commentCount":1,"articleSection":["Continuous Integration","Process Improvement","Tools"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/simpleprogrammer.com\/continuous-integration-best-practices\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/simpleprogrammer.com\/continuous-integration-best-practices\/","url":"https:\/\/simpleprogrammer.com\/continuous-integration-best-practices\/","name":"Continuous Integration Best Practices","isPartOf":{"@id":"https:\/\/simpleprogrammer.com\/#website"},"datePublished":"2009-12-30T15:51:28+00:00","dateModified":"2013-07-27T22:47:47+00:00","author":{"@id":"https:\/\/simpleprogrammer.com\/#\/schema\/person\/1abc70edfb189184827740310672de67"},"description":"A list of items that all continuous integration builds should contain to ensure that continuous integration best practices are being implemented.","breadcrumb":{"@id":"https:\/\/simpleprogrammer.com\/continuous-integration-best-practices\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/simpleprogrammer.com\/continuous-integration-best-practices\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/simpleprogrammer.com\/continuous-integration-best-practices\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/simpleprogrammer.com\/"},{"@type":"ListItem","position":2,"name":"Continuous Integration Best Practices"}]},{"@type":"WebSite","@id":"https:\/\/simpleprogrammer.com\/#website","url":"https:\/\/simpleprogrammer.com\/","name":"Simple Programmer","description":"","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/simpleprogrammer.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/simpleprogrammer.com\/#\/schema\/person\/1abc70edfb189184827740310672de67","name":"John Sonmez","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/dc2f18dfa76e017566ce607de002d7abe4acfd5ec19a6db82c180b00867b8d94?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/dc2f18dfa76e017566ce607de002d7abe4acfd5ec19a6db82c180b00867b8d94?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/dc2f18dfa76e017566ce607de002d7abe4acfd5ec19a6db82c180b00867b8d94?s=96&d=mm&r=g","caption":"John Sonmez"},"url":"https:\/\/simpleprogrammer.com\/author\/jsonmez\/"}]}},"_links":{"self":[{"href":"https:\/\/simpleprogrammer.com\/wp-json\/wp\/v2\/posts\/116","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/simpleprogrammer.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/simpleprogrammer.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/simpleprogrammer.com\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/simpleprogrammer.com\/wp-json\/wp\/v2\/comments?post=116"}],"version-history":[{"count":0,"href":"https:\/\/simpleprogrammer.com\/wp-json\/wp\/v2\/posts\/116\/revisions"}],"wp:attachment":[{"href":"https:\/\/simpleprogrammer.com\/wp-json\/wp\/v2\/media?parent=116"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/simpleprogrammer.com\/wp-json\/wp\/v2\/categories?post=116"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/simpleprogrammer.com\/wp-json\/wp\/v2\/tags?post=116"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}