Skip to content

Latest commit

 

History

History
215 lines (162 loc) · 8.81 KB

README.md

File metadata and controls

215 lines (162 loc) · 8.81 KB

CI Workshop

This workshop guides you through setting continuous integration and delivery in a sample React and Node application. You will learn:

  • How to setup CI/CD with Heroku Pipelines and Review Apps
  • How to write and setup unit and automation tests
    • Unit tests with Jest
    • Automation tests with Puppeteer and Selenium
  • How to setup production monitoring
    • Custom uptime/downtime monitoring with Slack notifications
    • Error monitoring with Rollbar
  • How to keep your dependencies up to date
    • Automatic testing dependency upgrades with Greenkeeper
    • Checking for security issues with Node Security

The goal is to dip your hands in enough aspects of CI/CD, but not go into depth on any one aspect. This workshop consists mostly of reading and copying and pasting, just like real web development ;)

Lessons

  1. Linting
  2. Continuous Integration
  3. Storybook
  4. Code Coverage
  5. React Tests
  6. Server Tests
  7. Continuous Delivery
  8. Monitoring and Notifications
  9. End-to-End Tests
  10. Error Monitoring
  11. Dependency Upgrades and Security Checks
  12. GitHub Status Checks
  13. Dark Launching with Feature Flags
  14. Learn More

Please read the background below before starting on the lessons.

Contact

Contact me:

Reference App

The reference app you will be working on and deploying is here: jonathanong/ci-reference-app. This app is based on my personal reference app IMS, so feel free to explore it. If you wish to cheat, there are solutions in the solution branch.

What is Continuous Integration/Delivery?

There are a lot of blog posts on this topic. Here is one graph that explains it:

We will be implemented continuous integration and delivery, but not continuous deployment. We will also be implementing a barebones version feature flags. See this post and company for more details:

What is the CI/CD workflow in a few bullet points?

  • Deliver small commits often.
    • No gigantic PRs, no gigantic merge conflicts
    • Dark launch code behind a feature flag so you can ship features without enabling it for all users
  • An automated delivery pipeline
    • Automatically going to the next step after tests pass
    • Automatically triggering jobs when a specific event occurs
  • Monitoring in production and elsewhere in your stack to create an automated feedback loop

Why Continuous Integration/Delivery?

  • Scale your code and team - with sufficient testing, monitoring, and automation, you can be confident that new code works as intended and does not break existing features. Existing CI/CD pipeline will be your guide to your engineering culture.
  • Minimize downtime - with sufficient tests and monitors, downtime should be minimal. With sufficient monitors, the time to incident response should be very quick,
  • Pinpoint regressions - with small commits and a robust CI/CD pipeline, if a regression even makes it to production, you can easily find the cause.

Testing Philosophy

There's a lot of testing philosophies on the internet. The most common is the testing pyramid:

The latest philosophy, which I prescribe to, in the JS community is the testing trophy:

What do each of these sections mean? It depends on a lot on the context. Here's one breakdown (actual definitions do not matter in real life):

  • Static Testing - validate that your code is syntactically correct
  • Unit Testing - validate that your components work correctly in isolation
    • React examples:
      • Shallow snapshot tests
      • Testing methods on React components, perhaps with mocking
      • Testing that one reducer works correctly
    • Server examples:
      • Test that a function works correctly
      • Test that a single API call returns a valid response
  • Integration Testing - validate that your components work correctly together
    • React examples:
      • Snapshot tests w/ different props
      • Testing the entire redux store
    • Server examples:
      • Test that multiple models interact with each other correctly
      • Test that multiple API calls work correctly together
  • End-to-End testing:
    • Go through a flow on your actual site with a browser

This list is just a guideline, but definitions could change based on your scenario. The main tenets of the testing trophy is:

  • Lint!
  • Spend time on integration tests instead of unit tests
    • Avoid mocking and spying on functions as it takes a lot of effort to write those tests
  • Focus on tests that fulfill actual acceptance criteria.
    • Unit tests are tests for engineers. End-to-End tests are tests for stakeholders. It's more important to write tests for stakeholders as that's how your work is measured.
  • If your tests become too slow, parallelize and shard your tests!

Here is how our custom setup for monitors and automation differ for us at Dollar Shave Club:

              Unit / Integration face-monitor face-e2e
Speed Fast Moderate Slow
Runs in production No Yes Not Yet
Runs in staging No Yes Not Yet
Runs in review apps No Yes Yes
Supports Selenium No No Yes
Supports Puppeteer No Yes Yes
Supports testing all browsers No No Yes
Supports Sauce Labs No No Yes
Supports retries Maybe Yes Yes
Supports retries on Sauce Labs No No Yes
Supports BDD Yes No Yes
Flakiness (1-5) 2 3 4
Hooked up to Datadog and/or alerts No Yes No
Ability to disable analytics Yes Yes No
Google Timeline Viewer No Yes No
Browser Screenshots Percy Storybook Implemented Not Implemented

face- are our suites of monitors and e2e tests with a lot of customization involved.

Tools

Backend:

Frontend:

Testing:

SaaS:

Setup

Install [email protected] or later:

# If you install via homebrew:
brew install node
# brew upgrade node

# If you install via nvm:
nvm install 8

Install (or upgrade) Selenium and friends:

brew install selenium-server-standalone chromedriver
# brew upgrade selenium-server-standalone chromedriver

Install Heroku's CLI: https://devcenter.heroku.com/articles/heroku-cli

Implicit Steps

  • We expect you to commit small and often. We won't tell you to git commit and git push.