Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

DEV322_Continuous Integration Best Practices for Software Development Teams

3,018 views

Published on

Today, more teams are adopting continuous integration (CI) techniques to enable collaboration, increase agility, and deliver a high-quality product faster. Cloud-based development tools such as AWS CodeCommit and AWS CodeBuild can enable teams to easily adopt CI practices without the need to manage infrastructure. In this session, we showcase a Crawl, Walk, and Run approach to CI. In Crawl, we showcase how to use AWS CodeBuild with your master code branch for running a basic CI workflow. In Walk, we add team collaboration capabilities to the previously developed CI workflow and showcase feature branches and pull requests. In Run, we showcase how to optimize the CI workflow for speed and quality with caching, code analysis, and integration testing.

  • Be the first to comment

DEV322_Continuous Integration Best Practices for Software Development Teams

  1. 1. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. AWS re:INVENT Continuous Integration Best Practices for Software Development Teams C l a r e L i g u o r i , A W S S e n i o r S o f t w a r e E n g i n e e r D E V 3 2 2 N o v e m b e r 2 9 , 2 0 1 7
  2. 2. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Is the build broken again? I can’t even compile the app! #TeamChat Clare 9:48 a.m. Yeah me too, I guess someone pushed a bad change Nitin 9:50 a.m. Sorry, everyone, that was me. I’m still working on fixing it Aashwin 11:01 a.m.
  3. 3. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Oh no, the last deployment to our test stack failed #TeamChat Nitin 2:15 p.m. Looks like the latest code causes a bunch of null pointer exceptions Aashwin 2:16 p.m. Why didn’t we catch this in code review? Clare 2:17 p.m.
  4. 4. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Is anyone else seeing test failures locally? #TeamChat Aashwin 4:39 p.m. I think it started happening after I pulled Ian’s latest changes Nitin 4:39 p.m. That’s weird, all the tests worked for me locally before I pushed the code Clare 4:45 p.m.
  5. 5. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Agenda • Introduction to continuous integration • Continuous integration tooling • Three techniques • Definition • How to implement it • What your team will say • How to level-up • Final thoughts, questions
  6. 6. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Agenda • Introduction to continuous integration • Continuous integration tooling • Three techniques • Definition • How to implement it • What your team will say • How to level-up • Final thoughts, questions
  7. 7. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. What is continuous integration? 1.Developers regularly check in code to a shared, central repository 2.Automated checks run regularly against the shared codebase 3.Developers get feedback from the automated checks about their code Developer Shared codebase Automated checks Check in code Get feedback Run checks
  8. 8. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. What is continuous integration? 1.Developers regularly check in code to a shared, central repository 2.Automated checks run regularly against the shared codebase 3.Developers get feedback from the automated checks about their code Developer Shared codebase Automated checks Check in code Get feedback Run checks
  9. 9. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. What is continuous integration? 1.Developers regularly check in code to a shared, central repository 2.Automated checks run regularly against the shared codebase 3.Developers get feedback from the automated checks about their code Developer Shared codebase Automated checks Check in code Get feedback Run checks
  10. 10. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. What is continuous integration? 1.Developers regularly check in code to a shared, central repository 2.Automated checks run regularly against the shared codebase 3.Developers get feedback from the automated checks about their code Developer Shared codebase Automated checks Check in code Get feedback Run checks
  11. 11. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. What is continuous integration? 1.Developers regularly check in code to a shared, central repository 2.Automated checks run regularly against the shared codebase 3.Developers get feedback from the automated checks about their code Developer Shared codebase Automated checks Check in code Get feedback Run checks
  12. 12. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Why does continuous integration matter? • Find bugs earlier • Fix bugs faster • Deliver faster • Deliver more often • Unblock developers • Grow developers
  13. 13. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Why does continuous integration matter? • Find bugs earlier • Fix bugs faster • Deliver faster • Deliver more often • Unblock developers • Grow developers Quality: 5x lower change failure rate Source: 2017 State of DevOps Report (Puppet)
  14. 14. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Why does continuous integration matter? • Find bugs earlier • Fix bugs faster • Deliver faster • Deliver more often • Unblock developers • Grow developers Delivery: 440x faster from commit to deploy Source: 2017 State of DevOps Report (Puppet)
  15. 15. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Why does continuous integration matter? • Find bugs earlier • Fix bugs faster • Deliver faster • Deliver more often • Unblock developers • Grow developers Delivery: 46x more frequent deployments Source: 2017 State of DevOps Report (Puppet)
  16. 16. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Why does continuous integration matter? • Find bugs earlier • Fix bugs faster • Deliver faster • Deliver more often • Unblock developers • Grow skills faster Happy teams: 44% more time spent on new features and code Source: 2017 State of DevOps Report (Puppet)
  17. 17. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Agenda • Introduction to continuous integration • Continuous integration tooling • Three techniques • Definition • How to implement it • What your team will say • How to level-up • Final thoughts, questions
  18. 18. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Sample application Simple Calculator Service Submit
  19. 19. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Sample application Simple Calculator Service 1 2+ Submit
  20. 20. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Sample application Simple Calculator Service 1 2+ Submit Your result is 3
  21. 21. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Sample application Simple Calculator Service 10 2x Submit
  22. 22. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Sample application Simple Calculator Service 10 2x Submit Your result is 20
  23. 23. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. exports.add = function(a, b) { return a + b; }; exports.subtract = function(a, b) { return a - b; }; exports.multiply = function(a, b) { return a * b; }; exports.divide = function(a, b) { return a / b; }; Sample application
  24. 24. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Sample application var assert = require('assert'); var calc = require('../calculator.js'); describe('Calculator Tests', function() { describe('Addition Tests', function() { it('returns 1 + 1 = 2', function(done) { assert.equal(calc.add(1, 1), 2); done(); }); }); describe('Multiplication Tests', function() { it('returns 10 * 2 = 20', function(done) { assert.equal(calc.multiply(10, 2), 20); done(); }); }); });
  25. 25. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Continuous integration tools Developer Shared codebase Automated checks Check in code Get feedback Run checks
  26. 26. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Continuous integration tools Developer Shared codebase Automated checks Check in code Get feedback Run checks Source Code • AWS CodeCommit • GitHub
  27. 27. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Continuous integration tools Developer Shared codebase Automated checks Check in code Get feedback Run checks Build & Test • AWS CodeBuild
  28. 28. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Continuous integration tools Developer Shared codebase Automated checks Check in code Get feedback Run checks Glue • Amazon CloudWatch Events • AWS Lambda
  29. 29. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. • Fully managed build service • Continuous scaling • Pay as you go • Extensible AWS CodeBuild
  30. 30. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
  31. 31. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. CodeBuild Project
  32. 32. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. CodeBuild Project
  33. 33. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. CodeBuild Project
  34. 34. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. version: 0.2 phases: install: commands: - npm install build: commands: - npm test artifacts: files: - '**/*' AWS CodeBuild build spec
  35. 35. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
  36. 36. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. CodeBuild Build
  37. 37. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. CodeBuild Build
  38. 38. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
  39. 39. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. • Build source from Bitbucket • Add builds to GitHub Pull Requests • Notify via Amazon CloudWatch Events • Use secrets from Amazon Parameter Store • Audit configuration in AWS Config AWS CodeBuild: What’s new this year
  40. 40. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. • Connect builds to VPC resources • Cache libraries in Amazon S3 • Display build badges in your repo AWS CodeBuild: What’s new this month
  41. 41. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Agenda • Introduction to continuous integration • Continuous integration tooling • Three techniques • Definition • How to implement it • What your team will say • How to level-up • Final thoughts, questions
  42. 42. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. The continuous integration journey Developer Shared codebase Automated checks Check in code Get feedback Run checks
  43. 43. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. The continuous integration journey 10 mph 65 mph 150 mph
  44. 44. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. The continuous integration journey Nightly checks Branch checks Pull request checks
  45. 45. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. We have our release deadline coming up soon. Are we going to make it? #TeamChat: No integration Clare 9:48 a.m. Well, when’s the last time we did a full build? Nitin 9:50 a.m. Um, probably when we did the last release three months ago? Aashwin 11:01 a.m.
  46. 46. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Technique #1: Nightly checks 1. Nightly checks 2. Branch checks 3. Pull request checks Run a full build and unit tests every night to make sure that application still compiles and that tests still pass
  47. 47. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Nightly checks: How to implement CloudWatch Event Schedule CodeBuild Build Lambda Function Trigger Start
  48. 48. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
  49. 49. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
  50. 50. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
  51. 51. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
  52. 52. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
  53. 53. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
  54. 54. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. 1. Automate codebase maintenance 2. Email notifications Nightly checks: Speed boosts
  55. 55. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. 1. Automate codebase maintenance 2. Email notifications Nightly checks: Speed boosts
  56. 56. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. When was the last time we upgraded our version of the ‘express’ library? #TeamChat: Library upgrades Clare 9:48 a.m. Ummm, I dunno Aashwin 9:50 a.m. Maybe never? Aashwin 11:01 a.m.
  57. 57. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. "dependencies": { "numeral": "^2.0.0", "express": "^4.13.3" } Speed boost: Automate upgrades
  58. 58. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. - {"name":"simple-calculator-service","version":"1.0.0","dependencies":{"chai":{"version":"3.5.0","from":"chai@>=3.5.0<4.0.0","resolved":"https://registry.npmjs.org/chai/-/chai-3.5.0.tgz","dependencies":{"assertion-error":{"version":"1.0.2","from":"assertion-error@>=1.0.1<2.0.0","resolved":"https://registry.npmjs.org/assertion-error/-/assertion-error-1.0.2.tgz"},"deep-eql":{"version":"0.1.3","from":"deep-eql@>=0.1.3<0.2.0","resolved":"https://registry.npmjs.org/deep-eql/-/deep-eql- 0.1.3.tgz","dependencies":{"type-detect":{"version":"0.1.1","from":"type-detect@0.1.1","resolved":"https://registry.npmjs.org/type-detect/-/type-detect-0.1.1.tgz"}}},"type-detect":{"version":"1.0.0","from":"type-detect@>=1.0.0<2.0.0","resolved":"https://registry.npmjs.org/type-detect/-/type-detect-1.0.0.tgz"}}},"chai-http":{"version":"3.0.0","from":"chai-http@>=3.0.0<4.0.0","resolved":"https://registry.npmjs.org/chai-http/-/chai-http- 3.0.0.tgz","dependencies":{"cookiejar":{"version":"2.0.6","from":"cookiejar@>=2.0.0<2.1.0","resolved":"https://registry.npmjs.org/cookiejar/-/cookiejar-2.0.6.tgz"},"is-ip":{"version":"1.0.0","from":"is-ip@1.0.0","resolved":"https://registry.npmjs.org/is-ip/-/is-ip-1.0.0.tgz","dependencies":{"ip-regex":{"version":"1.0.3","from":"ip-regex@>=1.0.0<2.0.0","resolved":"https://registry.npmjs.org/ip-regex/-/ip-regex- 1.0.3.tgz"}}},"methods":{"version":"1.1.2","from":"methods@>=1.1.2<1.2.0","resolved":"https://registry.npmjs.org/methods/-/methods-1.1.2.tgz"},"qs":{"version":"6.5.1","from":"qs@6.5.1","resolved":"https://registry.npmjs.org/qs/-/qs-6.5.1.tgz"},"superagent":{"version":"2.3.0","from":"superagent@>=2.0.0<3.0.0","resolved":"https://registry.npmjs.org/superagent/-/superagent- 2.3.0.tgz","dependencies":{"formidable":{"version":"1.1.1","from":"formidable@>=1.0.17<2.0.0","resolved":"https://registry.npmjs.org/formidable/-/formidable-1.1.1.tgz"},"mime":{"version":"1.4.1","from":"mime@>=1.3.4<2.0.0","resolved":"https://registry.npmjs.org/mime/-/mime-1.4.1.tgz"},"component-emitter":{"version":"1.2.1","from":"component-emitter@>=1.2.0<2.0.0","resolved":"https://registry.npmjs.org/component-emitter/-/component-emitter- 1.2.1.tgz"},"debug":{"version":"2.6.9","from":"debug@>=2.2.0<3.0.0","resolved":"https://registry.npmjs.org/debug/-/debug-2.6.9.tgz","dependencies":{"ms":{"version":"2.0.0","from":"ms@2.0.0","resolved":"https://registry.npmjs.org/ms/-/ms-2.0.0.tgz"}}},"extend":{"version":"3.0.1","from":"extend@>=3.0.0<4.0.0","resolved":"https://registry.npmjs.org/extend/-/extend-3.0.1.tgz"},"form-data":{"version":"1.0.0-rc4","from":"form-data@1.0.0-rc4","resolved":"https://registry.npmjs.org/form-data/- /form-data-1.0.0-rc4.tgz","dependencies":{"async":{"version":"1.5.2","from":"async@>=1.5.2<2.0.0","resolved":"https://registry.npmjs.org/async/-/async-1.5.2.tgz"},"combined-stream":{"version":"1.0.5","from":"combined-stream@>=1.0.5<2.0.0","resolved":"https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz","dependencies":{"delayed-stream":{"version":"1.0.0","from":"delayed-stream@>=1.0.0<1.1.0","resolved":"https://registry.npmjs.org/delayed-stream/-/delayed-stream- 1.0.0.tgz"}}},"mime-types":{"version":"2.1.17","from":"mime-types@>=2.1.10<3.0.0","resolved":"https://registry.npmjs.org/mime-types/-/mime-types-2.1.17.tgz","dependencies":{"mime-db":{"version":"1.30.0","from":"mime-db@>=1.30.0<1.31.0","resolved":"https://registry.npmjs.org/mime-db/-/mime-db-1.30.0.tgz"}}}}},"readable-stream":{"version":"2.3.3","from":"readable-stream@>=2.0.5<3.0.0","resolved":"https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz","dependencies":{"core- util-is":{"version":"1.0.2","from":"core-util-is@>=1.0.0<1.1.0","resolved":"https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz"},"inherits":{"version":"2.0.3","from":"inherits@>=2.0.3<2.1.0","resolved":"https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz"},"isarray":{"version":"1.0.0","from":"isarray@>=1.0.0<1.1.0","resolved":"https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz"},"process-nextick-args":{"version":"1.0.7","from":"process-nextick- args@>=1.0.6<1.1.0","resolved":"https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz"},"safe-buffer":{"version":"5.1.1","from":"safe-buffer@>=5.1.1<5.2.0","resolved":"https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz"},"string_decoder":{"version":"1.0.3","from":"string_decoder@>=1.0.3<1.1.0","resolved":"https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz"},"util-deprecate":{"version":"1.0.2","from":"util- deprecate@>=1.0.1<1.1.0","resolved":"https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz"}}}}}}},"express":{"version":"4.16.2","from":"express@>=4.13.3<5.0.0","resolved":"https://registry.npmjs.org/express/-/express-4.16.2.tgz","dependencies":{"accepts":{"version":"1.3.4","from":"accepts@>=1.3.4<1.4.0","resolved":"https://registry.npmjs.org/accepts/-/accepts-1.3.4.tgz","dependencies":{"mime-types":{"version":"2.1.17","from":"mime- types@>=2.1.15<2.2.0","resolved":"https://registry.npmjs.org/mime-types/-/mime-types-2.1.17.tgz","dependencies":{"mime-db":{"version":"1.30.0","from":"mime-db@>=1.30.0<1.31.0","resolved":"https://registry.npmjs.org/mime-db/-/mime-db-1.30.0.tgz"}}},"negotiator":{"version":"0.6.1","from":"negotiator@0.6.1","resolved":"https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz"}}},"array-flatten":{"version":"1.1.1","from":"array-flatten@1.1.1","resolved":"https://registry.npmjs.org/array- flatten/-/array-flatten-1.1.1.tgz"},"body-parser":{"version":"1.18.2","from":"body-parser@1.18.2","resolved":"https://registry.npmjs.org/body-parser/-/body-parser-1.18.2.tgz","dependencies":{"bytes":{"version":"3.0.0","from":"bytes@3.0.0","resolved":"https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz"},"http-errors":{"version":"1.6.2","from":"http-errors@>=1.6.2<1.7.0","resolved":"https://registry.npmjs.org/http-errors/-/http-errors- 1.6.2.tgz","dependencies":{"inherits":{"version":"2.0.3","from":"inherits@2.0.3","resolved":"https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz"},"setprototypeof":{"version":"1.0.3","from":"setprototypeof@1.0.3","resolved":"https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz"}}},"iconv-lite":{"version":"0.4.19","from":"iconv-lite@0.4.19","resolved":"https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz"},"raw-body":{"version":"2.3.2","from":"raw- body@2.3.2","resolved":"https://registry.npmjs.org/raw-body/-/raw-body-2.3.2.tgz","dependencies":{"unpipe":{"version":"1.0.0","from":"unpipe@1.0.0","resolved":"https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz"}}}}},"content-disposition":{"version":"0.5.2","from":"content-disposition@0.5.2","resolved":"https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz"},"content-type":{"version":"1.0.4","from":"content- type@>=1.0.4<1.1.0","resolved":"https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz"},"cookie":{"version":"0.3.1","from":"cookie@0.3.1","resolved":"https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz"},"cookie-signature":{"version":"1.0.6","from":"cookie-signature@1.0.6","resolved":"https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz"},"debug":{"version":"2.6.9","from":"debug@2.6.9","resolved":"https://registry.npmjs.org/debug/-/debug- 2.6.9.tgz","dependencies":{"ms":{"version":"2.0.0","from":"ms@2.0.0","resolved":"https://registry.npmjs.org/ms/-/ms-2.0.0.tgz"}}},"depd":{"version":"1.1.1","from":"depd@>=1.1.1<1.2.0","resolved":"https://registry.npmjs.org/depd/-/depd-1.1.1.tgz"},"encodeurl":{"version":"1.0.1","from":"encodeurl@>=1.0.1<1.1.0","resolved":"https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.1.tgz"},"escape-html":{"version":"1.0.3","from":"escape- html@>=1.0.3<1.1.0","resolved":"https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz"},"etag":{"version":"1.8.1","from":"etag@>=1.8.1<1.9.0","resolved":"https://registry.npmjs.org/etag/-/etag-1.8.1.tgz"},"finalhandler":{"version":"1.1.0","from":"finalhandler@1.1.0","resolved":"https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.0.tgz","dependencies":{"unpipe":{"version":"1.0.0","from":"unpipe@>=1.0.0<1.1.0","resolved":"https://registry.npmjs.org/unpipe/-/unpipe- 1.0.0.tgz"}}},"fresh":{"version":"0.5.2","from":"fresh@0.5.2","resolved":"https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz"},"merge-descriptors":{"version":"1.0.1","from":"merge-descriptors@1.0.1","resolved":"https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz"},"methods":{"version":"1.1.2","from":"methods@>=1.1.2<1.2.0","resolved":"https://registry.npmjs.org/methods/-/methods-1.1.2.tgz"},"on-finished":{"version":"2.3.0","from":"on- finished@>=2.3.0<2.4.0","resolved":"https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz","dependencies":{"ee-first":{"version":"1.1.1","from":"ee-first@1.1.1","resolved":"https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz"}}},"parseurl":{"version":"1.3.2","from":"parseurl@>=1.3.2<1.4.0","resolved":"https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz"},"path-to-regexp":{"version":"0.1.7","from":"path-to-regexp@0.1.7","resolved":"https://registry.npmjs.org/path-to- regexp/-/path-to-regexp-0.1.7.tgz"},"proxy-addr":{"version":"2.0.2","from":"proxy-addr@>=2.0.2<2.1.0","resolved":"https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.2.tgz","dependencies":{"forwarded":{"version":"0.1.2","from":"forwarded@>=0.1.2<0.2.0","resolved":"https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz"},"ipaddr.js":{"version":"1.5.2","from":"ipaddr.js@1.5.2","resolved":"https://registry.npmjs.org/ipaddr.js/-/ipaddr.js- 1.5.2.tgz"}}},"qs":{"version":"6.5.1","from":"qs@6.5.1","resolved":"https://registry.npmjs.org/qs/-/qs-6.5.1.tgz"},"range-parser":{"version":"1.2.0","from":"range-parser@>=1.2.0<1.3.0","resolved":"https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz"},"safe-buffer":{"version":"5.1.1","from":"safe-buffer@5.1.1","resolved":"https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz"},"send":{"version":"0.16.1","from":"send@0.16.1","resolved":"https://registry.npmjs.org/send/- /send-0.16.1.tgz","dependencies":{"destroy":{"version":"1.0.4","from":"destroy@>=1.0.4<1.1.0","resolved":"https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz"},"http-errors":{"version":"1.6.2","from":"http-errors@>=1.6.2<1.7.0","resolved":"https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz","dependencies":{"inherits":{"version":"2.0.3","from":"inherits@2.0.3","resolved":"https://registry.npmjs.org/inherits/-/inherits- 2.0.3.tgz"},"setprototypeof":{"version":"1.0.3","from":"setprototypeof@1.0.3","resolved":"https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz"}}},"mime":{"version":"1.4.1","from":"mime@1.4.1","resolved":"https://registry.npmjs.org/mime/-/mime-1.4.1.tgz"},"ms":{"version":"2.0.0","from":"ms@2.0.0","resolved":"https://registry.npmjs.org/ms/-/ms-2.0.0.tgz"}}},"serve-static":{"version":"1.13.1","from":"serve-static@1.13.1","resolved":"https://registry.npmjs.org/serve-static/- /serve-static-1.13.1.tgz"},"setprototypeof":{"version":"1.1.0","from":"setprototypeof@1.1.0","resolved":"https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz"},"statuses":{"version":"1.3.1","from":"statuses@>=1.3.1<1.4.0","resolved":"https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz"},"type-is":{"version":"1.6.15","from":"type-is@>=1.6.15<1.7.0","resolved":"https://registry.npmjs.org/type-is/-/type-is-1.6.15.tgz","dependencies":{"media- typer":{"version":"0.3.0","from":"media-typer@0.3.0","resolved":"https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz"},"mime-types":{"version":"2.1.17","from":"mime-types@>=2.1.15<2.2.0","resolved":"https://registry.npmjs.org/mime-types/-/mime-types-2.1.17.tgz","dependencies":{"mime-db":{"version":"1.30.0","from":"mime-db@>=1.30.0<1.31.0","resolved":"https://registry.npmjs.org/mime-db/-/mime-db-1.30.0.tgz"}}}}},"utils-merge":{"version":"1.0.1","from":"utils- merge@1.0.1","resolved":"https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz"},"vary":{"version":"1.1.2","from":"vary@>=1.1.2<1.2.0","resolved":"https://registry.npmjs.org/vary/-/vary-1.1.2.tgz"}}},"mocha":{"version":"4.0.1","from":"mocha@>=4.0.0<5.0.0","resolved":"https://registry.npmjs.org/mocha/-/mocha-4.0.1.tgz","dependencies":{"browser-stdout":{"version":"1.3.0","from":"browser-stdout@1.3.0","resolved":"https://registry.npmjs.org/browser-stdout/-/browser-stdout- 1.3.0.tgz"},"commander":{"version":"2.11.0","from":"commander@2.11.0","resolved":"https://registry.npmjs.org/commander/-/commander-2.11.0.tgz"},"debug":{"version":"3.1.0","from":"debug@3.1.0","resolved":"https://registry.npmjs.org/debug/-/debug-3.1.0.tgz","dependencies":{"ms":{"version":"2.0.0","from":"ms@2.0.0","resolved":"https://registry.npmjs.org/ms/-/ms-2.0.0.tgz"}}},"diff":{"version":"3.3.1","from":"diff@3.3.1","resolved":"https://registry.npmjs.org/diff/-/diff-3.3.1.tgz"},"escape- string-regexp":{"version":"1.0.5","from":"escape-string-regexp@1.0.5","resolved":"https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz"},"glob":{"version":"7.1.2","from":"glob@7.1.2","resolved":"https://registry.npmjs.org/glob/-/glob-7.1.2.tgz","dependencies":{"fs.realpath":{"version":"1.0.0","from":"fs.realpath@>=1.0.0<2.0.0","resolved":"https://registry.npmjs.org/fs.realpath/-/fs.realpath- 1.0.0.tgz"},"inflight":{"version":"1.0.6","from":"inflight@>=1.0.4<2.0.0","resolved":"https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz","dependencies":{"wrappy":{"version":"1.0.2","from":"wrappy@>=1.0.0<2.0.0","resolved":"https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz"}}},"inherits":{"version":"2.0.3","from":"inherits@>=2.0.0<3.0.0","resolved":"https://registry.npmjs.org/inherits/-/inherits- 2.0.3.tgz"},"minimatch":{"version":"3.0.4","from":"minimatch@>=3.0.4<4.0.0","resolved":"https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz","dependencies":{"brace-expansion":{"version":"1.1.8","from":"brace-expansion@>=1.1.7<2.0.0","resolved":"https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz","dependencies":{"balanced-match":{"version":"1.0.0","from":"balanced-match@>=1.0.0<2.0.0","resolved":"https://registry.npmjs.org/balanced-match/-/balanced-match- 1.0.0.tgz"},"concat-map":{"version":"0.0.1","from":"concat-map@0.0.1","resolved":"https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz"}}}}},"once":{"version":"1.4.0","from":"once@>=1.3.0<2.0.0","resolved":"https://registry.npmjs.org/once/-/once-1.4.0.tgz","dependencies":{"wrappy":{"version":"1.0.2","from":"wrappy@>=1.0.0<2.0.0","resolved":"https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz"}}},"path-is-absolute":{"version":"1.0.1","from":"path-is- absolute@>=1.0.0<2.0.0","resolved":"https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz"}}},"growl":{"version":"1.10.3","from":"growl@1.10.3","resolved":"https://registry.npmjs.org/growl/-/growl-1.10.3.tgz"},"he":{"version":"1.1.1","from":"he@1.1.1","resolved":"https://registry.npmjs.org/he/-/he-1.1.1.tgz"},"mkdirp":{"version":"0.5.1","from":"mkdirp@0.5.1","resolved":"https://registry.npmjs.org/mkdirp/-/mkdirp- 0.5.1.tgz","dependencies":{"minimist":{"version":"0.0.8","from":"minimist@0.0.8","resolved":"https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz"}}},"supports-color":{"version":"4.4.0","from":"supports-color@4.4.0","resolved":"https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz","dependencies":{"has-flag":{"version":"2.0.0","from":"has-flag@>=2.0.0<3.0.0","resolved":"https://registry.npmjs.org/has-flag/-/has-flag- 2.0.0.tgz"}}}}},"numeral":{"version":"2.0.6","from":"numeral@>=2.0.0<3.0.0","resolved":"https://registry.npmjs.org/numeral/-/numeral-2.0.6.tgz"},"nyc":{"version":"11.2.1","from":"nyc@>=11.2.0<12.0.0","resolved":"https://registry.npmjs.org/nyc/-/nyc-11.2.1.tgz","dependencies":{"archy":{"version":"1.0.0","from":"archy@>=1.0.0<2.0.0","resolved":"https://registry.npmjs.org/archy/-/archy- 1.0.0.tgz"},"arrify":{"version":"1.0.1","from":"arrify@>=1.0.1<2.0.0","resolved":"https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz"},"caching-transform":{"version":"1.0.1","from":"caching-transform@>=1.0.0<2.0.0","resolved":"https://registry.npmjs.org/caching-transform/-/caching-transform-1.0.1.tgz"},"convert-source-map":{"version":"1.5.0","from":"convert-source-map@>=1.3.0<2.0.0","resolved":"https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.5.0.tgz"},"debug- log":{"version":"1.0.1","from":"debug-log@>=1.0.1<2.0.0","resolved":"https://registry.npmjs.org/debug-log/-/debug-log-1.0.1.tgz"},"default-require-extensions":{"version":"1.0.0","from":"default-require-extensions@>=1.0.0<2.0.0","resolved":"https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-1.0.0.tgz"},"find-cache-dir":{"version":"0.1.1","from":"find-cache-dir@>=0.1.1<0.2.0","resolved":"https://registry.npmjs.org/find-cache-dir/-/find-cache-dir- 0.1.1.tgz"},"find-up":{"version":"2.1.0","from":"find-up@>=2.1.0<3.0.0","resolved":"https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz"},"foreground-child":{"version":"1.5.6","from":"foreground-child@>=1.5.3<2.0.0","resolved":"https://registry.npmjs.org/foreground-child/-/foreground-child-1.5.6.tgz"},"glob":{"version":"7.1.2","from":"glob@>=7.0.6<8.0.0","resolved":"https://registry.npmjs.org/glob/-/glob-7.1.2.tgz"},"istanbul-lib-coverage":{"version":"1.1.1","from":"istanbul-lib- coverage@>=1.1.1<2.0.0","resolved":"https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-1.1.1.tgz"},"istanbul-lib-hook":{"version":"1.0.7","from":"istanbul-lib-hook@>=1.0.7<2.0.0","resolved":"https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-1.0.7.tgz"},"istanbul-lib-instrument":{"version":"1.8.0","from":"istanbul-lib-instrument@>=1.8.0<2.0.0","resolved":"https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-1.8.0.tgz"},"istanbul- lib-report":{"version":"1.1.1","from":"istanbul-lib-report@>=1.1.1<2.0.0","resolved":"https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-1.1.1.tgz","dependencies":{"supports-color":{"version":"3.2.3","from":"supports-color@>=3.1.2<4.0.0","resolved":"https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz"}}},"istanbul-lib-source-maps":{"version":"1.2.1","from":"istanbul-lib-source-maps@>=1.2.1<2.0.0","resolved":"https://registry.npmjs.org/istanbul-lib-source- maps/-/istanbul-lib-source-maps-1.2.1.tgz"},"istanbul-reports":{"version":"1.1.2","from":"istanbul-reports@>=1.1.1<2.0.0","resolved":"https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-1.1.2.tgz"},"md5-hex":{"version":"1.3.0","from":"md5-hex@>=1.2.0<2.0.0","resolved":"https://registry.npmjs.org/md5-hex/-/md5-hex-1.3.0.tgz"},"merge-source-map":{"version":"1.0.4","from":"merge-source-map@>=1.0.2<2.0.0","resolved":"https://registry.npmjs.org/merge-source-map/-/merge-source-map- 1.0.4.tgz"},"micromatch":{"version":"2.3.11","from":"micromatch@>=2.3.11<3.0.0","resolved":"https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz"},"mkdirp":{"version":"0.5.1","from":"mkdirp@>=0.5.0<0.6.0","resolved":"https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz"},"resolve-from":{"version":"2.0.0","from":"resolve-from@>=2.0.0<3.0.0","resolved":"https://registry.npmjs.org/resolve-from/-/resolve-from- 2.0.0.tgz"},"rimraf":{"version":"2.6.1","from":"rimraf@>=2.5.4<3.0.0","resolved":"https://registry.npmjs.org/rimraf/-/rimraf-2.6.1.tgz"},"signal-exit":{"version":"3.0.2","from":"signal-exit@>=3.0.1<4.0.0","resolved":"https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz"},"spawn-wrap":{"version":"1.3.8","from":"spawn-wrap@>=1.3.8<2.0.0","resolved":"https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-1.3.8.tgz"},"test-exclude":{"version":"4.1.1","from":"test- exclude@>=4.1.1<5.0.0","resolved":"https://registry.npmjs.org/test-exclude/-/test-exclude-4.1.1.tgz"},"yargs":{"version":"8.0.2","from":"yargs@>=8.0.1<9.0.0","resolved":"https://registry.npmjs.org/yargs/-/yargs-8.0.2.tgz","dependencies":{"camelcase":{"version":"4.1.0","from":"camelcase@>=4.1.0<5.0.0","resolved":"https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz"},"cliui":{"version":"3.2.0","from":"cliui@>=3.2.0<4.0.0","resolved":"https://registry.npmjs.org/cliui/-/cliui- 3.2.0.tgz","dependencies":{"string-width":{"version":"1.0.2","from":"string-width@>=1.0.1<2.0.0","resolved":"https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz"}}},"read-pkg-up":{"version":"2.0.0","from":"read-pkg-up@>=2.0.0<3.0.0","resolved":"https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz"},"yargs-parser":{"version":"7.0.0","from":"yargs-parser@>=7.0.0<8.0.0","resolved":"https://registry.npmjs.org/yargs-parser/-/yargs-parser-7.0.0.tgz"},"load-json- file":{"version":"2.0.0","from":"load-json-file@>=2.0.0<3.0.0","resolved":"https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz"},"path-type":{"version":"2.0.0","from":"path-type@>=2.0.0<3.0.0","resolved":"https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz"},"read-pkg":{"version":"2.0.0","from":"read-pkg@>=2.0.0<3.0.0","resolved":"https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz"},"strip-bom":{"version":"3.0.0","from":"strip- bom@>=3.0.0<4.0.0","resolved":"https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz"}}},"yargs-parser":{"version":"5.0.0","from":"yargs-parser@>=5.0.0<6.0.0","resolved":"https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.0.tgz","dependencies":{"camelcase":{"version":"3.0.0","from":"camelcase@>=3.0.0<4.0.0","resolved":"https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz"}}},"align-text":{"version":"0.1.4","from":"align- text@>=0.1.3<0.2.0","resolved":"https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz"},"amdefine":{"version":"1.0.1","from":"amdefine@>=0.0.4","resolved":"https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz"},"ansi-regex":{"version":"2.1.1","from":"ansi-regex@>=2.0.0<3.0.0","resolved":"https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz"},"ansi-styles":{"version":"2.2.1","from":"ansi-styles@>=2.2.1<3.0.0","resolved":"https://registry.npmjs.org/ansi-styles/-/ansi- styles-2.2.1.tgz"},"append-transform":{"version":"0.4.0","from":"append-transform@>=0.4.0<0.5.0","resolved":"https://registry.npmjs.org/append-transform/-/append-transform-0.4.0.tgz"},"arr-diff":{"version":"2.0.0","from":"arr-diff@>=2.0.0<3.0.0","resolved":"https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz"},"arr-flatten":{"version":"1.1.0","from":"arr-flatten@>=1.0.1<2.0.0","resolved":"https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz"},"array- unique":{"version":"0.2.1","from":"array-unique@>=0.2.1<0.3.0","resolved":"https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz"},"async":{"version":"1.5.2","from":"async@>=1.4.0<2.0.0","resolved":"https://registry.npmjs.org/async/-/async-1.5.2.tgz"},"babel-code-frame":{"version":"6.26.0","from":"babel-code-frame@>=6.26.0<7.0.0","resolved":"https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz"},"babel-generator":{"version":"6.26.0","from":"babel- generator@>=6.18.0<7.0.0","resolved":"https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.0.tgz"},"babel-messages":{"version":"6.23.0","from":"babel-messages@>=6.23.0<7.0.0","resolved":"https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz"},"babel-runtime":{"version":"6.26.0","from":"babel-runtime@>=6.26.0<7.0.0","resolved":"https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz"},"babel-template":{"version":"6.26.0","from":"babel- template@>=6.16.0<7.0.0","resolved":"https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz"},"babel-traverse":{"version":"6.26.0","from":"babel-traverse@>=6.18.0<7.0.0","resolved":"https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz"},"babel-types":{"version":"6.26.0","from":"babel-types@>=6.18.0<7.0.0","resolved":"https://registry.npmjs.org/babel-types/-/babel-types- 6.26.0.tgz"},"babylon":{"version":"6.18.0","from":"babylon@>=6.18.0<7.0.0","resolved":"https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz"},"balanced-match":{"version":"1.0.0","from":"balanced-match@>=1.0.0<2.0.0","resolved":"https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz"},"brace-expansion":{"version":"1.1.8","from":"brace-expansion@>=1.1.7<2.0.0","resolved":"https://registry.npmjs.org/brace-expansion/-/brace-expansion- 1.1.8.tgz"},"braces":{"version":"1.8.5","from":"braces@>=1.8.2<2.0.0","resolved":"https://registry.npmjs.org/braces/-/braces-1.8.5.tgz"},"builtin-modules":{"version":"1.1.1","from":"builtin-modules@>=1.0.0<2.0.0","resolved":"https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz"},"camelcase":{"version":"1.2.1","from":"camelcase@>=1.0.2<2.0.0","resolved":"https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz"},"center-align":{"version":"0.1.3","from":"center- align@>=0.1.1<0.2.0","resolved":"https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz"},"chalk":{"version":"1.1.3","from":"chalk@>=1.1.3<2.0.0","resolved":"https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz"},"code-point-at":{"version":"1.1.0","from":"code-point-at@>=1.0.0<2.0.0","resolved":"https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz"},"commondir":{"version":"1.0.1","from":"commondir@>=1.0.1<2.0.0","resolved":"https://registry.npmjs.org/commondir/- /commondir-1.0.1.tgz"},"concat-map":{"version":"0.0.1","from":"concat-map@0.0.1","resolved":"https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz"},"core-js":{"version":"2.5.1","from":"core-js@>=2.4.0<3.0.0","resolved":"https://registry.npmjs.org/core-js/-/core-js-2.5.1.tgz"},"cross-spawn":{"version":"4.0.2","from":"cross-spawn@>=4.0.0<5.0.0","resolved":"https://registry.npmjs.org/cross-spawn/-/cross-spawn- 4.0.2.tgz"},"debug":{"version":"2.6.8","from":"debug@>=2.6.8<3.0.0","resolved":"https://registry.npmjs.org/debug/-/debug-2.6.8.tgz"},"decamelize":{"version":"1.2.0","from":"decamelize@>=1.0.0<2.0.0","resolved":"https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz"},"detect-indent":{"version":"4.0.0","from":"detect-indent@>=4.0.0<5.0.0","resolved":"https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz"},"error-ex":{"version":"1.3.1","from":"error- ex@>=1.2.0<2.0.0","resolved":"https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz"},"escape-string-regexp":{"version":"1.0.5","from":"escape-string-regexp@>=1.0.2<2.0.0","resolved":"https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz"},"esutils":{"version":"2.0.2","from":"esutils@>=2.0.2<3.0.0","resolved":"https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz"},"expand-brackets":{"version":"0.1.5","from":"expand- brackets@>=0.1.4<0.2.0","resolved":"https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz"},"expand-range":{"version":"1.8.2","from":"expand-range@>=1.8.1<2.0.0","resolved":"https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz"},"extglob":{"version":"0.3.2","from":"extglob@>=0.3.1<0.4.0","resolved":"https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz"},"filename-regex":{"version":"2.0.1","from":"filename- regex@>=2.0.0<3.0.0","resolved":"https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz"},"fill-range":{"version":"2.2.3","from":"fill-range@>=2.1.0<3.0.0","resolved":"https://registry.npmjs.org/fill-range/-/fill-range-2.2.3.tgz"},"for-in":{"version":"1.0.2","from":"for-in@>=1.0.1<2.0.0","resolved":"https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz"},"for-own":{"version":"0.1.5","from":"for-own@>=0.1.4<0.2.0","resolved":"https://registry.npmjs.org/for-own/-/for-own- 0.1.5.tgz"},"fs.realpath":{"version":"1.0.0","from":"fs.realpath@>=1.0.0<2.0.0","resolved":"https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz"},"get-caller-file":{"version":"1.0.2","from":"get-caller-file@>=1.0.1<2.0.0","resolved":"https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.2.tgz"},"get-stream":{"version":"3.0.0","from":"get-stream@>=3.0.0<4.0.0","resolved":"https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz"},"glob- base":{"version":"0.3.0","from":"glob-base@>=0.3.0<0.4.0","resolved":"https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz"},"glob-parent":{"version":"2.0.0","from":"glob-parent@>=2.0.0<3.0.0","resolved":"https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz"},"globals":{"version":"9.18.0","from":"globals@>=9.18.0<10.0.0","resolved":"https://registry.npmjs.org/globals/-/globals-9.18.0.tgz"},"graceful-fs":{"version":"4.1.11","from":"graceful- fs@>=4.1.11<5.0.0","resolved":"https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz"},"has-ansi":{"version":"2.0.0","from":"has-ansi@>=2.0.0<3.0.0","resolved":"https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz"},"has-flag":{"version":"1.0.0","from":"has-flag@>=1.0.0<2.0.0","resolved":"https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz"},"hosted-git-info":{"version":"2.5.0","from":"hosted-git-info@>=2.1.4<3.0.0","resolved":"https://registry.npmjs.org/hosted-git- info/-/hosted-git-info-2.5.0.tgz"},"imurmurhash":{"version":"0.1.4","from":"imurmurhash@>=0.1.4<0.2.0","resolved":"https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz"},"inflight":{"version":"1.0.6","from":"inflight@>=1.0.4<2.0.0","resolved":"https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz"},"inherits":{"version":"2.0.3","from":"inherits@>=2.0.0<3.0.0","resolved":"https://registry.npmjs.org/inherits/-/inherits- 2.0.3.tgz"},"invariant":{"version":"2.2.2","from":"invariant@>=2.2.2<3.0.0","resolved":"https://registry.npmjs.org/invariant/-/invariant-2.2.2.tgz"},"invert-kv":{"version":"1.0.0","from":"invert-kv@>=1.0.0<2.0.0","resolved":"https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz"},"is-arrayish":{"version":"0.2.1","from":"is-arrayish@>=0.2.1<0.3.0","resolved":"https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz"},"is-buffer":{"version":"1.1.5","from":"is- buffer@>=1.1.5<2.0.0","resolved":"https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.5.tgz"},"is-builtin-module":{"version":"1.0.0","from":"is-builtin-module@>=1.0.0<2.0.0","resolved":"https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz"},"is-dotfile":{"version":"1.0.3","from":"is-dotfile@>=1.0.0<2.0.0","resolved":"https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz"},"is-equal-shallow":{"version":"0.1.3","from":"is-equal- shallow@>=0.1.3<0.2.0","resolved":"https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz"},"is-extendable":{"version":"0.1.1","from":"is-extendable@>=0.1.1<0.2.0","resolved":"https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz"},"is-extglob":{"version":"1.0.0","from":"is-extglob@>=1.0.0<2.0.0","resolved":"https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz"},"is-finite":{"version":"1.0.2","from":"is- finite@>=1.0.0<2.0.0","resolved":"https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz"},"is-fullwidth-code-point":{"version":"1.0.0","from":"is-fullwidth-code-point@>=1.0.0<2.0.0","resolved":"https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz"},"is-glob":{"version":"2.0.1","from":"is-glob@>=2.0.1<3.0.0","resolved":"https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz"},"is-number":{"version":"2.1.0","from":"is- number@>=2.1.0<3.0.0","resolved":"https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz"},"is-posix-bracket":{"version":"0.1.1","from":"is-posix-bracket@>=0.1.0<0.2.0","resolved":"https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz"},"is-primitive":{"version":"2.0.0","from":"is-primitive@>=2.0.0<3.0.0","resolved":"https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz"},"is-stream":{"version":"1.1.0","from":"is- stream@>=1.1.0<2.0.0","resolved":"https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz"},"is-utf8":{"version":"0.2.1","from":"is-utf8@>=0.2.0<0.3.0","resolved":"https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz"},"isarray":{"version":"1.0.0","from":"isarray@1.0.0","resolved":"https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz"},"isexe":{"version":"2.0.0","from":"isexe@>=2.0.0<3.0.0","resolved":"https://registry.npmjs.org/isexe/-/isexe- 2.0.0.tgz"},"isobject":{"version":"2.1.0","from":"isobject@>=2.0.0<3.0.0","resolved":"https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz"},"js-tokens":{"version":"3.0.2","from":"js-tokens@>=3.0.2<4.0.0","resolved":"https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz"},"jsesc":{"version":"1.3.0","from":"jsesc@>=1.3.0<2.0.0","resolved":"https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz"},"kind-of":{"version":"3.2.2","from":"kind- of@>=3.0.2<4.0.0","resolved":"https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz"},"lazy-cache":{"version":"1.0.4","from":"lazy-cache@>=1.0.3<2.0.0","resolved":"https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz"},"lcid":{"version":"1.0.0","from":"lcid@>=1.0.0<2.0.0","resolved":"https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz"},"load-json-file":{"version":"1.1.0","from":"load-json-file@>=1.0.0<2.0.0","resolved":"https://registry.npmjs.org/load-json-file/-/load-json-file- 1.1.0.tgz"},"lodash":{"version":"4.17.4","from":"lodash@>=4.17.4<5.0.0","resolved":"https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz"},"longest":{"version":"1.0.1","from":"longest@>=1.0.1<2.0.0","resolved":"https://registry.npmjs.org/longest/-/longest-1.0.1.tgz"},"loose-envify":{"version":"1.3.1","from":"loose-envify@>=1.0.0<2.0.0","resolved":"https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz"},"lru-cache":{"version":"4.1.1","from":"lru- cache@>=4.0.1<5.0.0","resolved":"https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.1.tgz"},"md5-o-matic":{"version":"0.1.1","from":"md5-o-matic@>=0.1.1<0.2.0","resolved":"https://registry.npmjs.org/md5-o-matic/-/md5-o-matic-0.1.1.tgz"},"mem":{"version":"1.1.0","from":"mem@>=1.1.0<2.0.0","resolved":"https://registry.npmjs.org/mem/-/mem-1.1.0.tgz"},"mimic-fn":{"version":"1.1.0","from":"mimic-fn@>=1.0.0<2.0.0","resolved":"https://registry.npmjs.org/mimic-fn/-/mimic-fn- 1.1.0.tgz"},"minimatch":{"version":"3.0.4","from":"minimatch@>=3.0.4<4.0.0","resolved":"https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz"},"minimist":{"version":"0.0.8","from":"minimist@0.0.8","resolved":"https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz"},"ms":{"version":"2.0.0","from":"ms@2.0.0","resolved":"https://registry.npmjs.org/ms/-/ms-2.0.0.tgz"},"normalize-package-data":{"version":"2.4.0","from":"normalize-package- data@>=2.3.2<3.0.0","resolved":"https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz"},"normalize-path":{"version":"2.1.1","from":"normalize-path@>=2.0.1<3.0.0","resolved":"https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz"},"npm-run-path":{"version":"2.0.2","from":"npm-run-path@>=2.0.0<3.0.0","resolved":"https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz"},"number-is-nan":{"version":"1.0.1","from":"number-is- nan@>=1.0.0<2.0.0","resolved":"https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz"},"object-assign":{"version":"4.1.1","from":"object-assign@>=4.1.0<5.0.0","resolved":"https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz"},"object.omit":{"version":"2.0.1","from":"object.omit@>=2.0.0<3.0.0","resolved":"https://registry.npmjs.org/object.omit/-/object.omit- 2.0.1.tgz"},"once":{"version":"1.4.0","from":"once@>=1.3.0<2.0.0","resolved":"https://registry.npmjs.org/once/-/once-1.4.0.tgz"},"optimist":{"version":"0.6.1","from":"optimist@>=0.6.1<0.7.0","resolved":"https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz"},"os-homedir":{"version":"1.0.2","from":"os-homedir@>=1.0.1<2.0.0","resolved":"https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz"},"os-locale":{"version":"2.1.0","from":"os- locale@>=2.0.0<3.0.0","resolved":"https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz"},"p-finally":{"version":"1.0.0","from":"p-finally@>=1.0.0<2.0.0","resolved":"https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz"},"p-limit":{"version":"1.1.0","from":"p-limit@>=1.1.0<2.0.0","resolved":"https://registry.npmjs.org/p-limit/-/p-limit-1.1.0.tgz"},"p-locate":{"version":"2.0.0","from":"p-locate@>=2.0.0<3.0.0","resolved":"https://registry.npmjs.org/p-locate/-/p-locate- 2.0.0.tgz"},"parse-glob":{"version":"3.0.4","from":"parse-glob@>=3.0.4<4.0.0","resolved":"https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz"},"parse-json":{"version":"2.2.0","from":"parse-json@>=2.2.0<3.0.0","resolved":"https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz"},"path-exists":{"version":"2.1.0","from":"path-exists@>=2.0.0<3.0.0","resolved":"https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz"},"path-is-absolute":{"version":"1.0.1","from":"path-is- absolute@>=1.0.0<2.0.0","resolved":"https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz"},"path-key":{"version":"2.0.1","from":"path-key@>=2.0.0<3.0.0","resolved":"https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz"},"path-parse":{"version":"1.0.5","from":"path-parse@>=1.0.5<2.0.0","resolved":"https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz"},"path-type":{"version":"1.1.0","from":"path-type@>=1.0.0<2.0.0","resolved":"https://registry.npmjs.org/path- type/-/path-type-1.1.0.tgz"},"pify":{"version":"2.3.0","from":"pify@>=2.0.0<3.0.0","resolved":"https://registry.npmjs.org/pify/-/pify-2.3.0.tgz"},"pinkie":{"version":"2.0.4","from":"pinkie@>=2.0.0<3.0.0","resolved":"https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz"},"pinkie-promise":{"version":"2.0.1","from":"pinkie-promise@>=2.0.0<3.0.0","resolved":"https://registry.npmjs.org/pinkie-promise/-/pinkie-promise- 2.0.1.tgz"},"preserve":{"version":"0.2.0","from":"preserve@>=0.2.0<0.3.0","resolved":"https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz"},"pseudomap":{"version":"1.0.2","from":"pseudomap@>=1.0.2<2.0.0","resolved":"https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz"},"read-pkg":{"version":"1.1.0","from":"read-pkg@>=1.0.0<2.0.0","resolved":"https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz"},"regenerator-runtime":{"version":"0.11.0","from":"regenerator- runtime@>=0.11.0<0.12.0","resolved":"https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.0.tgz"},"regex-cache":{"version":"0.4.4","from":"regex-cache@>=0.4.2<0.5.0","resolved":"https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz"},"remove-trailing-separator":{"version":"1.1.0","from":"remove-trailing-separator@>=1.0.1<2.0.0","resolved":"https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz"},"repeat- element":{"version":"1.1.2","from":"repeat-element@>=1.1.2<2.0.0","resolved":"https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz"},"repeat-string":{"version":"1.6.1","from":"repeat-string@>=1.5.2<2.0.0","resolved":"https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz"},"repeating":{"version":"2.0.1","from":"repeating@>=2.0.0<3.0.0","resolved":"https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz"},"require-directory":{"version":"2.1.1","from":"require- directory@>=2.1.1<3.0.0","resolved":"https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz"},"require-main-filename":{"version":"1.0.1","from":"require-main-filename@>=1.0.1<2.0.0","resolved":"https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz"},"right-align":{"version":"0.1.3","from":"right-align@>=0.1.1<0.2.0","resolved":"https://registry.npmjs.org/right-align/-/right-align- 0.1.3.tgz"},"semver":{"version":"5.4.1","from":"semver@>=5.3.0<6.0.0","resolved":"https://registry.npmjs.org/semver/-/semver-5.4.1.tgz"},"set-blocking":{"version":"2.0.0","from":"set-blocking@>=2.0.0<3.0.0","resolved":"https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz"},"shebang-command":{"version":"1.2.0","from":"shebang-command@>=1.2.0<2.0.0","resolved":"https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz"},"shebang- regex":{"version":"1.0.0","from":"shebang-regex@>=1.0.0<2.0.0","resolved":"https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz"},"slide":{"version":"1.1.6","from":"slide@>=1.1.5<2.0.0","resolved":"https://registry.npmjs.org/slide/-/slide-1.1.6.tgz"},"source-map":{"version":"0.5.7","from":"source-map@>=0.5.6<0.6.0","resolved":"https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz"},"spdx-correct":{"version":"1.0.2","from":"spdx- correct@>=1.0.0<1.1.0","resolved":"https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz"},"spdx-expression-parse":{"version":"1.0.4","from":"spdx-expression-parse@>=1.0.0<1.1.0","resolved":"https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz"},"spdx-license-ids":{"version":"1.2.2","from":"spdx-license-ids@>=1.0.2<2.0.0","resolved":"https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz"},"strip- ansi":{"version":"3.0.1","from":"strip-ansi@>=3.0.0<4.0.0","resolved":"https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz"},"strip-bom":{"version":"2.0.0","from":"strip-bom@>=2.0.0<3.0.0","resolved":"https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz"},"strip-eof":{"version":"1.0.0","from":"strip-eof@>=1.0.0<2.0.0","resolved":"https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz"},"supports-color":{"version":"2.0.0","from":"supports- color@>=2.0.0<3.0.0","resolved":"https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz"},"to-fast-properties":{"version":"1.0.3","from":"to-fast-properties@>=1.0.3<2.0.0","resolved":"https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz"},"trim-right":{"version":"1.0.1","from":"trim-right@>=1.0.1<2.0.0","resolved":"https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz"},"uglify-to-browserify":{"version":"1.0.2","from":"uglify-to- browserify@>=1.0.0<1.1.0","resolved":"https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz"},"validate-npm-package-license":{"version":"3.0.1","from":"validate-npm-package-license@>=3.0.1<4.0.0","resolved":"https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz"},"which":{"version":"1.3.0","from":"which@>=1.2.9<2.0.0","resolved":"https://registry.npmjs.org/which/-/which-1.3.0.tgz"},"which- module":{"version":"2.0.0","from":"which-module@>=2.0.0<3.0.0","resolved":"https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz"},"window-size":{"version":"0.1.0","from":"window-size@0.1.0","resolved":"https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz"},"wordwrap":{"version":"0.0.3","from":"wordwrap@>=0.0.2<0.1.0","resolved":"https://registry.npmjs.org/wordwrap/-/wordwrap- 0.0.3.tgz"},"wrappy":{"version":"1.0.2","from":"wrappy@>=1.0.0<2.0.0","resolved":"https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz"},"write-file-atomic":{"version":"1.3.4","from":"write-file-atomic@>=1.1.4<2.0.0","resolved":"https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-1.3.4.tgz"},"y18n":{"version":"3.2.1","from":"y18n@>=3.2.1<4.0.0","resolved":"https://registry.npmjs.org/y18n/-/y18n- 3.2.1.tgz"},"yallist":{"version":"2.1.2","from":"yallist@>=2.1.2<3.0.0","resolved":"https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz"},"cliui":{"version":"2.1.0","from":"cliui@>=2.1.0<3.0.0","resolved":"https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz","dependencies":{"wordwrap":{"version":"0.0.2","from":"wordwrap@0.0.2","resolved":"https://registry.npmjs.org/wordwrap/-/wordwrap- 0.0.2.tgz"}}},"execa":{"version":"0.7.0","from":"execa@>=0.7.0<0.8.0","resolved":"https://registry.npmjs.org/execa/-/execa-0.7.0.tgz","dependencies":{"cross-spawn":{"version":"5.1.0","from":"cross-spawn@>=5.0.1<6.0.0","resolved":"https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz"}}},"handlebars":{"version":"4.0.10","from":"handlebars@>=4.0.3<5.0.0","resolved":"https://registry.npmjs.org/handlebars/-/handlebars-4.0.10.tgz","dependencies":{"source- map":{"version":"0.4.4","from":"source-map@>=0.4.4<0.5.0","resolved":"https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz"}}},"locate-path":{"version":"2.0.0","from":"locate-path@>=2.0.0<3.0.0","resolved":"https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz","dependencies":{"path-exists":{"version":"3.0.0","from":"path-exists@>=3.0.0<4.0.0","resolved":"https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz"}}},"pkg-dir":{"version":"1.0.0","from":"pkg- dir@>=1.0.0<2.0.0","resolved":"https://registry.npmjs.org/pkg-dir/-/pkg-dir-1.0.0.tgz","dependencies":{"find-up":{"version":"1.1.2","from":"find-up@>=1.0.0<2.0.0","resolved":"https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz"}}},"read-pkg-up":{"version":"1.0.1","from":"read-pkg-up@>=1.0.1<2.0.0","resolved":"https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz","dependencies":{"find-up":{"version":"1.1.2","from":"find- up@>=1.0.0<2.0.0","resolved":"https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz"}}},"string-width":{"version":"2.1.1","from":"string-width@>=2.0.0<3.0.0","resolved":"https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz","dependencies":{"is-fullwidth-code-point":{"version":"2.0.0","from":"is-fullwidth-code-point@>=2.0.0<3.0.0","resolved":"https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz"},"strip-ansi":{"version":"4.0.0","from":"strip- ansi@>=4.0.0<5.0.0","resolved":"https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz"},"ansi-regex":{"version":"3.0.0","from":"ansi-regex@>=3.0.0<4.0.0","resolved":"https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz"}}},"uglify-js":{"version":"2.8.29","from":"uglify-js@>=2.6.0<3.0.0","resolved":"https://registry.npmjs.org/uglify-js/-/uglify-js- 2.8.29.tgz","dependencies":{"yargs":{"version":"3.10.0","from":"yargs@>=3.10.0<3.11.0","resolved":"https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz"}}},"wrap-ansi":{"version":"2.1.0","from":"wrap-ansi@>=2.0.0<3.0.0","resolved":"https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz","dependencies":{"string-width":{"version":"1.0.2","from":"string-width@>=1.0.1<2.0.0","resolved":"https://registry.npmjs.org/string-width/-/string-width- 1.0.2.tgz"}}},"randomatic":{"version":"1.1.7","from":"randomatic@>=1.1.3<2.0.0","resolved":"https://registry.npmjs.org/randomatic/-/randomatic-1.1.7.tgz","dependencies":{"is-number":{"version":"3.0.0","from":"is-number@>=3.0.0<4.0.0","resolved":"https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz","dependencies":{"kind-of":{"version":"3.2.2","from":"kind-of@^3.0.2","resolved":"https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz"}}},"kind-of":{"version":"4.0.0","from":"kind- of@>=4.0.0<5.0.0","resolved":"https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz"}}}}}}} Speed boost: Automate upgrades
  59. 59. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Nightly checks: Automate upgrades CloudWatch Event Schedule CodeBuild Build CodeCommit Repository Lambda Function Trigger Start Push Upgrade
  60. 60. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. - rm npm-shrinkwrap.json - npm install - npm test - npm shrinkwrap - git add npm-shrinkwrap.json - git commit –m “Update dependencies!” - git push Nightly checks: Automate upgrades
  61. 61. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Nightly Checks: Update Libraries
  62. 62. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Nightly Checks: Update Libraries
  63. 63. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Nightly Checks: Update Libraries
  64. 64. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. 1. Automate codebase maintenance 2. Email notifications Nightly checks: Speed boosts
  65. 65. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. I can’t compile anything this morning #TeamChat: Nightly checks failing Clare 9:48 a.m. Oh, looks like last night’s build failed Nitin 9:50 a.m. Oh, looks like it’s been failing for a week actually… Nitin 11:01 a.m.
  66. 66. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Speed boost: Email notifications CloudWatch Event + Lambda Function CodeBuild Build Amazon SES Email SendNotify
  67. 67. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
  68. 68. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
  69. 69. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
  70. 70. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. I got the email that last night’s build failed #TeamChat: Failing nightly checks Clare 9:48 a.m. Yeah me too, I guess someone pushed a bad change Aashwin 9:50 a.m. Sorry, everyone, that was me. I’m still working on fixing it Nitin 11:01 a.m.
  71. 71. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Nightly checks summary Implement: Run a build every night at midnight Feedback loop: 16-24 hours Team impact: Broken code can block team for entire days Speed boosts: Automate codebase maintenance; Email notifications
  72. 72. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Technique #2: Branch checks 1. Nightly checks 2. Branch checks 3. Pull request checks Run a full build and unit tests every time someone pushes a new change to a branch in the source code repo.
  73. 73. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Branch checks: AWS CodeCommit CodeBuild Build CodeCommit Repository Team Members Push Notify Start CloudWatch Event + Lambda Function
  74. 74. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Branch Checks: CodeCommit Events
  75. 75. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Branch Checks: CodeCommit Events
  76. 76. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Branch Checks: CodeCommit Events
  77. 77. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Branch Checks: CodeCommit Events
  78. 78. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Branch Checks: CodeCommit Events
  79. 79. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Branch checks: GitHub CodeBuild Build GitHub Repository Team Members Start Report Push
  80. 80. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Branch Checks: GitHub Webhooks
  81. 81. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Branch Checks: GitHub Webhooks
  82. 82. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Branch Checks: GitHub Webhooks
  83. 83. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Branch Checks: GitHub Webhooks
  84. 84. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Aashwin: Dude, you broke the build #TeamChat: Failing branch checks Clare 9:48 a.m. I did? I pushed my last change hours ago though Aashwin 9:50 a.m. Either the CI build just finished or we didn’t notice the failure… Nitin 11:01 a.m.
  85. 85. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. 1. Slack notifications 2. Build badges 3. Caching Branch checks: Speed boosts
  86. 86. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. 1. Slack notifications 2. Build badges 3. Caching Branch checks: Speed boosts
  87. 87. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Speed boost: Slack notifications CodeBuild Build Notify CloudWatch Event + Lambda Function Post Slack Channel
  88. 88. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Branch Checks: Slack Notifications
  89. 89. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Branch Checks: Slack Notifications
  90. 90. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. 1. Slack notifications 2. Build badges 3. Caching Branch checks: Speed boosts
  91. 91. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
  92. 92. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
  93. 93. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
  94. 94. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. 1. Slack notifications 2. Build badges 3. Caching Branch checks: Speed boosts

×