One of our core values at Chromatic is to “delight our clients”. There are numerous ways that we try to bring delight, but as developers and designers one of our most frequent deliverables is code; our particular development and quality assurance (QA) workflow helps us deliver high-quality code to our clients’ production environments more frequently, in smaller change-sets. This results in our clients seeing their requested changes more quickly, and when a bug does slip through (nobody’s perfect), we are able to identify it and squash it in record time. We attempt to automate as much of this process as possible saving more time for the pieces that require human touch.
Note: We use GitHub so there are references to GitHub-specific concepts that may be slightly different on other services. The general concepts should all still apply.
- Branches are made off of
main, usually one branch corresponding to one ticket. The branch name should include the ticket number for easy reference.
- Once the ticket is complete, a pull request is made and code review/QA occurs.
- Automated checks are configured to run at this time and should pass before reviews are requested.
- Any changes needed/requested are made and pushed to the branch.
- Once all checks pass and approval is granted by one or more team members and a client product owner, the code is merged into
mainand deployed to production.
By following this process, we deploy code to production more often, but in smaller change-sets. This is beneficial for a number of reasons, not the least of which being that if a bug ever does make it to production, it is significantly easier to track down which commit contains the offending change. More frequent deploys also allow the client more visibility into the ongoing work.
No commits are made directly to the
main branch. We create a branch off of
main to encompass any changes. We use descriptive names for branches; if there is a ticket associated with it, we reference that number in the branch name.
The Chromatic QA process is an extension of our development process; they work together to ensure that we are delivering high-quality experiences to our clients. This process begins when we create a pull request. When we have completed our code changes and believe they are ready to be merged to
main, they will be reviewed with a pull request.
Pull Request Descriptions
Creating a pull request shines a spotlight on a branch and signals to others that you have changes you would like to merge and deploy. Writing a detailed PR description is one of the first and most important steps in ensuring that we are delivering quality work to our clients. All Chromatic repositories have a pull request template configured that will pre-populate the PR with sections to complete such as description, motivation, testing instructions, and screenshots. A good pull request must accomplish the following:
- Communicate the context of the changes to anyone that might be reviewing the pull request.
- Demonstrate via screenshots and testing instructions both that you have verified your work and how others may verify it.
- Reference the issue or ticket from the pull request.
If additional changes are needed due to the feedback, the commit/push process detailed in The Basics can be repeated and the pull request will automatically update to include these new changes; there is no need to create a new PR.
Draft Pull Requests
It is common for our team to create a pull request that is still a work in progress to receive early feedback. We use draft pull requests to signify that work is still in progress and the developer creating the PR will specify in the description what they are looking for feedback on. When the PR is ready for final review, the description is updated, reviews are re-requested as necessary, and finally, the pull request is marked as "ready for review" to make it no longer a "draft".
Our team utilizes Tugboat to generate a testing environment for every pull request. Tugboat automatically generates a full environment with the code changes from a pull request, which can be easily accessed by anyone to validate the changes proposed in that PR.
Every Chromatic project has automated testing and/or linting set up to help catch issues like functional and visual regressions, or departures from our chosen code style. Other types of checks may be relevant as well such as linting via PHP_CodeSniffer, eslint, or stylelint, unit tests, visual regression testing via Percy or Diffy, or end-to-end tests using a tool like Puppeteer. These will vary depending on the needs of the project. Automated checks should be set up to run on every pull request, and more times than not, set in the repo settings to be required before the PR can be merged.
Our team selects at least one, but usually more, people to review their pull request in the PR’s "Reviewers" section. It is these team members’ responsibility to review and provide feedback on your code as well as validate the testing the PR author has already done in Tugboat.
The “product owner” should be requested as a reviewer as well so that they can sign off on the functional changes once they have verified them in Tugboat.
We always “assign” pull requests to the person who will be responsible for shepherding the PR through the process of getting it reviewed, approved, and most importantly, deployed. In most cases, the person who creates the PR should be the "assignee".
Merging a Pull Request
Once a pull request has been reviewed/approved, and all automated checks are passing, the branch can be merged into the
main branch. Better yet, we prefer to squash pull requests to ensure that it results in a single commit on the main branch. When squashing, the pull request title and description will be used as the new commit message. All the more reason to create a descriptive pull request (see above). At this point, the merged code will be deployed to production automatically.
At the end of the day, this process is in service of our clients. It can be adapted or modified as needed on a project to project basis, but the important thing to keep in mind is what we are trying to achieve: client delight. If we can use and evolve this process to continue to deliver products to our client at a level and pace that raises their eyebrows, and blows their hair back, then we are doing our job. If we can do it in a way that challenges our own team to continually improve, while handling the majority of the more monotonous pieces with automation, then we have really found the true path forward.