diff options
Diffstat (limited to '.html/dev/builds.html')
| -rw-r--r-- | .html/dev/builds.html | 270 |
1 files changed, 0 insertions, 270 deletions
diff --git a/.html/dev/builds.html b/.html/dev/builds.html deleted file mode 100644 index 5626a4e..0000000 --- a/.html/dev/builds.html +++ /dev/null @@ -1,270 +0,0 @@ -<!DOCTYPE html> -<html> -<head> - <title> - The Codex » - Nobody Cares About Your Build - </title> - - <link - rel='stylesheet' - type='text/css' - href='http://fonts.googleapis.com/css?family=Buenard:400,700&subset=latin,latin-ext'> - <link - rel="stylesheet" - type="text/css" - href="../media/css/reset.css"> - <link - rel="stylesheet" - type="text/css" - href="../media/css/grimoire.css"> -</head> -<body> - -<div id="shell"> - - <ol id="breadcrumbs"> - - <li class="crumb-0 not-last"> - - <a href="../">index</a> - - </li> - - <li class="crumb-1 not-last"> - - <a href="./">dev</a> - - </li> - - <li class="crumb-2 last"> - - builds - - </li> - - </ol> - - - - <div id="article"> - <h1 id="nobody-cares-about-your-build">Nobody Cares About Your Build</h1> -<p>Every software system, from simple Python packages to huge enterprise-grade -systems spanning massive clusters, has a build—a set of steps that must be -followed to go from a source tree or a checked-out project to a ready-to-use -build product. A build system's job is to automate these steps.</p> -<p>Build systems are critical to software development.</p> -<p>They're also one of the most common avoidable engineering failures.</p> -<p>A reliable, comfortable build system has measurable benefits for software -development. Being able to build a testable, deployable system at any point -during development lets the team test more frequently. Frequent testing -isolates bugs and integration problems earlier, reducing their impact. Simple, -working builds allow new team members to ramp up more quickly on a project: -once they understand how one piece of the system is constructed, they can -apply that knowledge to the entire system and move on to doing useful work. If -releases, the points where code is made available outside the development -team, are done using the same build system that developers use in daily life, -there will be fewer surprises during releases as the “release” build process -will be well-understood from development.</p> -<h2 id="builds-have-needs-too">Builds Have Needs, Too</h2> -<p>In 1947, Abraham Maslow described a <a href="http://en.wikipedia.org/wiki/Maslow's_hierarchy_of_needs">hierarchy of -needs</a> for a -person's physical and mental well-being on the premise that all the items at -the lowest level of the hierarchy must be met before a person will be able to -focus usefully on higher-level needs. Maslow's hierarchy begins with a set of -needs that, without which, you do not have a person (for long)—physiological -needs like “breathing,” “food,” and “water.” At the peak, there are extremely -high-level needs that are about being a happy and enlightened -person—“creativity,” “morality,” “curiosity,” and so on.</p> -<p><img alt="A three-tier pyramid. At the bottom: Automatable. Repeatable. Standardized. -Extensible. Understood. In the middle tier: Simple. Fast. Unit tests. Part of -the project. Environment independent. At the top: Metrics. Parallel builds. -Acceptance tests. Product caching. IDE -integration." src="/media/dev/builds/buildifesto-pyramid.png"></p> -<p>Builds, and software engineering as a whole, can be described the same way: at -the top of the hierarchy is a working system that solves a problem, and at the -bottom are the things you need to have software at all. If you don't meet -needs at a given level, you will eventually be forced to stop what you're -doing at a higher level and face them.</p> -<p>Before a build is a build, there are five key needs to meet:</p> -<ul> -<li><strong>It must be repeatable</strong>. Every time you start your build on a given source - tree, it must build exactly the same products without any further - intervention. Without this, you can't reliably decide whether a given build - is “good,” and can easily wind up with a build that needs to be run several - times, or a build that relies on running several commands in the right - order, to produce a build.</li> -<li><strong>It must be automatable</strong>. Build systems are used by developers sitting at - their desks, but they’re also used by automatic build systems for nightly - builds and continuous integration, and they can be made into parts of other - builds. A build system that can only be run by having someone sit down at a - keyboard and mouse and kicking it off can’t be integrated into anything - else.</li> -<li><strong>It must be standardized</strong>. If you have multiple projects that build - similar things—for example, several Java libraries—all of them must be built - the same way. Without this, it's difficult for a developer to apply - knowledge from one project to another, and it's difficult to debug problems - with individual builds.</li> -<li><strong>It must be extensible</strong>. Not all builds are created equal. Where one build - compiles a set of source files, another needs five libraries and a WSDL - descriptor before it can compile anything. There must be affordances within - the standard build that allow developers to describe the ways their build is - different. Without this, you have to write what amounts to a second build - tool to ensure that all the “extra” steps for certain projects happen.</li> -<li><strong>Someone must understand it</strong>. A build nobody understands is a time bomb: - when it finally breaks (and it will), your project will be crippled until - someone fixes it or, more likely, hacks around it.</li> -</ul> -<p>If you have these five things, you have a working build. The next step is to -make it comfortable. Comfortable builds can be used daily for development -work, demonstrations, and tests as well as during releases; builds that are -used constantly don't get a chance to “rust” as developers ignore them until a -release or a demo and don’t hide surprises for launch day.</p> -<ul> -<li><strong>It must be simple</strong>. When a complicated build breaks, you need someone who - understands it to fix it for you. Simple builds mean more people can - understand it and fewer things can break.</li> -<li><strong>It must be fast</strong>. A slow build will be hacked around or ignored entirely. - Ideally, someone creating a local build for a small change should have a - build ready in seconds.</li> -<li><strong>It must be part of the product</strong>. The team responsible for developing a - project must be in control of and responsible for its build. Changes to it - and bugs against it must be treated as changes to the product or bugs in the - product.</li> -<li><strong>It must run unit tests</strong>. Unit tests, which are completely isolated tests - written by and for developers, can catch a large number of bugs, but they're - only useful if they get run. The build must run the unit test suite for the - product it's building every build.</li> -<li><strong>It must build the same thing in any environment</strong>. A build is no good if - developers can only get a working build from a specific machine, or where a - build from one developer's machine is useless anywhere else. If the build is - uniform on any environment, any developer can cook up a build for a test or - demo at any time.</li> -</ul> -<p>Finally, there are “chrome” features that take a build from effective to -excellent. These vary widely from project to project and from organization to -organization. Here are some common chrome needs:</p> -<ul> -<li><strong>It should integrate with your IDEs</strong>. This goes both directions: it should - be possible to run the build without leaving your IDE or editor suite, and - it should be possible to translate the build system into IDE-specific - configurations to reduce duplication between IDE settings and the build - configuration.</li> -<li><strong>It should generate metrics</strong>. If you gather metrics for test coverage, - common bugs, complexity analysis, or generate reports or documentation, the - build system should be responsible for it. This keeps all the common - administrative actions for the project in the same place as the rest of the - configuration, and provides the same consistency that the system gives the - rest of the build.</li> -<li><strong>It should support multiple processors</strong>. For medium-sized builds that - aren’t yet large enough to merit breaking down into libraries, being able to - perform independent build steps in parallel can be a major time-saver. This - can extend to distributed build systems, where idle CPU time can be donated - to other peoples’ builds.</li> -<li><strong>It should run integration and acceptance tests</strong>. Taking manual work from - the quality control phase of a project and running it automatically during - builds amplifies the benefits of early testing and, if your acceptance tests - are good, when your project is done.</li> -<li><strong>It should not need repeating</strong>. Once you declare a particular set of build - products “done,” you should be able to use those products as-is any time you - need them. Without this, you will eventually find yourself rebuilding the - same code from the same release over and over again.</li> -</ul> -<h2 id="what-doesnt-work">What Doesn’t Work</h2> -<p>Builds, like any other part of software development, have -antipatterns—recurring techniques for solving a problem that introduce more -problems.</p> -<ul> -<li><strong>One Source Tree, Many Products</strong>. Many small software projects that - survive to grow into large, monolithic projects are eventually broken up - into components. It's easy to do this by taking the existing source tree and - building parts of it, and it's also wrong. Builds that slice up a single - source tree require too much discipline to maintain and too much mental - effort to understand. Break your build into separate projects that are built - separately, and have each build produce one product.</li> -<li><strong>The Build And Deploy System</strong>. Applications that have a server component - often choose to automate deployment and setup using the same build system - that builds the project. Too often, the extra build steps that set up a - working system from the built project are tacked onto the end of an existing - build. This breaks standardization, making that build harder to understand, - and means that that one build is producing more than one thing—it's - producing the actual project, and a working system around the project.</li> -<li><strong>The Build Button</strong>. IDEs are really good at editing code. Most of them - will produce a build for you, too. Don't rely on IDE builds for your build - system, and don't let the IDE reconfigure the build process. Most IDEs don't - differentiate between settings that apply to the project and settings that - apply to the local environment, leading to builds that rely on libraries or - other projects being in specific places and on specific IDE settings that - are often buried in complex settings dialogs.</li> -<li><strong>Manual Steps</strong>. Anything that gets done by hand will eventually be done - wrong. Automate every step.</li> -</ul> -<h2 id="what-does-work">What Does Work</h2> -<p>Similarly, there are patterns—solutions that recur naturally and can be -applied to many problems.</p> -<ul> -<li><strong>Do One Thing Well</strong>. The UNIX philosophy of small, cohesive tools works - for build systems, too: if you need to build a package, and then install it - on a server, write three builds: one that builds the package, one that takes - a package and installs it, and a third that runs the first two builds in - order. The individual builds will be small enough to easily understand and - easy to standardize, and the package ends up installed on the server when - the main build finishes.</li> -<li><strong>Dependency Repositories</strong>. After a build is done, make the built product - available to other builds and to the user for reuse rather than rebuilding - it every time you need it. Similarly, libraries and other inward - dependencies for a build can be shared between builds, reducing duplication - between projects.</li> -<li><strong>Convention Over Extension</strong>. While it's great that your build system is - extensible, think hard about whether you really need to extend your build. - Each extension makes that project’s build that much harder to understand and - adds one more point of failure.</li> -</ul> -<h2 id="pick-a-tool-any-tool">Pick A Tool, Any Tool</h2> -<p>Nothing here is new. The value of build systems has been -<a href="http://www.joelonsoftware.com/articles/fog0000000043.html">discussed</a> -<a href="http://www.gamesfromwithin.com/articles/0506/000092.html">in</a> -<a href="http://c2.com/cgi/wiki?BuildSystem">great</a> -<a href="http://www.codinghorror.com/blog/archives/000988.html">detail</a> elsewhere. -Much of the accumulated build wisdom of the software industry has already been -incorporated to one degree or another into build tools. What matters is that -you pick one, then use it with the discipline needed to get repeatable results -without thinking.</p> - </div> - - - -<div id="comments"> -<div id="disqus_thread"></div> -<script type="text/javascript"> - /* * * CONFIGURATION VARIABLES: EDIT BEFORE PASTING INTO YOUR WEBPAGE * * */ - var disqus_shortname = 'grimoire'; // required: replace example with your forum shortname - - /* * * DON'T EDIT BELOW THIS LINE * * */ - (function() { - var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true; - dsq.src = 'http://' + disqus_shortname + '.disqus.com/embed.js'; - (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq); - })(); -</script> -<noscript>Please enable JavaScript to view the <a href="http://disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript> -<a href="http://disqus.com" class="dsq-brlink">comments powered by <span class="logo-disqus">Disqus</span></a> -</div> - - - - <div id="footer"> - <p> - - The Codex — - - Powered by <a href="http://markdoc.org/">Markdoc</a>. - -<a href="https://bitbucket.org/ojacobson/grimoire.ca/src/master/wiki/dev/builds.md">See this page on Bitbucket</a> (<a href="https://bitbucket.org/ojacobson/grimoire.ca/history-node/master/wiki/dev/builds.md">history</a>). - - </p> - </div> - -</div> -</body> -</html>
\ No newline at end of file |
