For the sake of this section, we are going to make the assumption that you’re deploying your product to a production environment for the first time. Of course as you make changes and push updates you will need to be doing lots of these things repeatedly.
Deployment Setup
Considering the deployment strategy for your product can be very involved, as there are many options available nowadays. Some of the factors you may want to consider when working with your team include:
- maintainability
- ease of deploying new features
- ability to rollback a bad deployment
- traffic & scalability
- cost
- ...and more
To make some broad simplifications as of the time of this writing there are 3 major camps to choose from:
- Using a Service
If you want to optimize for maintainability and ease of getting up and running using a service that will handle most of your deployment for you might be your best bet. The downsides are that it may be harder to customize and as you scale your application it will cost significantly more. Heroku is a classic example of a service that no matter what your technology tech stack is, you can likely deploy to Heroku with little configuration.
There are some newer players in the deployment services seen that let you auto-deploy a web application, such as a React app and then deploy your backend as a set of functions that run on a service like AWS. This is somewhat newer but again has the appeal of being easy to set up and manage for a development. - Containers
With the advent of docker and containers, there is now the ability to easily both work in local development using a container but also deploying a container that is almost identical to a service like AWS’s Elastic Container Service to run. The benefits here are that costs can be lower, you can scale quite easily but the downsides is that AWS can be quite complicated for a developer who does not have much devops experience. It could take quite a bit of effort to get running and also quite a bit of effort to teach or train future staff members. - Roll Your Own Server
There is still the possibility for a team to just use a hosted server from any cloud server provider and setup the application as they would like. Using certain technologies like Ansible or Puppet you can setup your own server and have full control. The cost of doing something like this might be cheaper and technically you can also scale it but only if your team really has the know-how to do this. As developers seem to have a requirement to understand more and more of not only the backend and frontend of an application they also need to have an understanding of devops which can be a daunting task for someone more junior.
QA Testing
Quality Assurance (QA) is a broad area and can mean different things, especially if you’re on a small team or in a large company that has their own QA department. Let’s break down how it may show up while getting your product off the ground.
- Automated QA
Developers when implementing features or fixing bugs can also add additional code to the project which automatically tests certain parts of it function as intended. This is not foolproof and does not mean the code will be bugless, but it helps as a primary gut check when first implementing the feature, as well as an ongoing check to ensure that someone who has contributed new code hasn’t broken an existing feature.
This is one of the most powerful ways you can feel confident about shipping new code and avoid regressions in your product. However, it is a time trade off as maintaining and contributing to a test suite does take effort, especially at first.
New product teams sometimes decide to skip on testing certain parts of the application that may be changing rapidly over time. It is often easier to add automated tests for business logic and backend code rather than for the frontend of the application.
The automated tests themselves come in many different forms, most popular being: unit tests and integration tests. Respectively, they focus on testing individual pieces of your code or more that an entire flow (such as signing up) works as intended.
- Developer QA
It is expected that developers QA their own tasks and ensure that they work. More junior or less discipled engineers can have a tendency to ship code without fully testing all of the potential use cases of their feature. This is where good development team process and expectations can come into play coupled with some of the other strategies in this section.
- Product/Design Review
Some teams create a “PM Review” step in their process, and even set this up in their ticket tracking tool. When a feature or bug ticket has finished, instead of that item being moved to “Done”, it gets assigned to a PM (or potentially a designer) to review. This acts as both another QA pass on the ticket but also as a way to catch any inconsistencies between what was developed, the intended UX and the given mockups.
- QA Staff
At a large company, there may be a small or large team of people that are solely dedicated to QAing the company’s product(s). They may spend their day manually testing applications based on whatever new features or bug fixes have been worked on or they do a round of QA before any new deployments are shipped out the door. They could also be referred to as QA Engineers which usually means that the team member also works on writing automated tests instead of or as a supplement to the developers working on the application.
You can find lots of offshore QA firms where you can get one part time QA staff member up to a whole team depending on what your needs are. You work with them to create a testing plan and let them know what and when they should be testing your application.
Dealing with Bugs
When a developer receives a ticket for a bug they need to fix, the first thing they will likely try to do is replicate that bug locally in their development environment on their computer. If they cannot replicate the issue, they will either punt the bug ticket back to whoever reported it, or try to make a fix without actually knowing if they fixed the issue. This is why a well written bug report is critical - it shortens this process as much as possible and gives the developer exactly what they need to get right into fixing the issue.
As you can guess, the #1 piece of information that should be included in a good bug report is steps to replicate the issue. These should be detailed and tested by the reporter to make sure they saw the bug again when following their own steps.
After this bit of information, there should be a list of details that give more context to the developer. This could include:
- The specific device and operating system being used
- The specific version of a browser (if on web)
- An account to look at on staging or production that the issue occurred to,
- Screenshots or a video recording of the bug happening, if possible.
The ticket should be well organized with paragraphs, titles, and sections to make it easy to digest. In an ideal world you have established a bug report template that everyone uses in the ticket tracking tool you are utilize. This will keep everything consistent and ensure all of the proper information gets added to the ticket.
Polishing Your Product
When launching a new feature, and especially a new product, for the first time we like to do a pass at “polishing” the product.
As engineers translate designs into pixels, there is a lot of room for interpretation. While some developers are more visually conscious, others are more functionality conscious, and some might be better at complicated business logic. Going through the application with a fine tooth comb and comparing it to the designs is a critical part of the design/product review process to ensure the product feels finished.
One method of this is to use the application and compare side-by-side with the designs. Looking for things such as fonts, font sizes, font weights, margins, padding, width, heights, etc can all “tighten up” the application and give it a certain feeling of completeness.
Another method is to go through the application and confirm all buttons, links and clicks interact as intended by the designer or product manager. Often, with a new product or feature, set things can be misimplemented in a way that may had been obvious to the designer but non-obvious to the developer. Also interactions such as forms, modals, error states, loading states, and empty lists could have been implemented without there being any corresponding designs to go off of.
Continuous Deployment / Continuous Integration
After your first launch, you’re going to want to deploy often. It’s best practice to ship bug fixes and new features once they’re finished instead of letting them pile up. The more code you have that’s not shipped, the less confident you might start to get in pushing that large update.
The same goes for your staging environment. As engineers merge in their code to a `development` branch in your codebase, those changes should be pushed live to your staging environment so that they can be tested there as well. Ideally you would have setup this process before you even got to your first production launch.
Given that we want to be shipping code often, the best way to make this happen is to automate. Continuous Integration (CI) and Continuous Deployment (CD) are terms used to talk about tools and processes that make this happen. CI largely refers to the process of keeping your new code merged and tested while CD refers to actually shipping it to your production environment.
Continuous Integration
Let’s first focus on CI. When a developer has created a new pull request and is ready to merge their changes into the development branch of your codebase, CI will automatically run on that branch. This will do things like running any automated tests you have against the branch, and potentially use some linting tools to ensure the application still builds. If you’re using a service like Github, it will show you the status of CI running against a branch right on the pull request. If anything fails, it will actually warn and block you from merging that pull request into the codebase.
The primary goal here is to catch anything wrong with the new contribution before it even gets merged in. If there’s an issue, the best time for a developer to have to address it is right away before they context switch onto another feature, bug fix, etc. Ultimately it helps you have more confidence in the code you're pushing to your development branch.
When you go to push your work to production you can also ensure that the latest version of your development and main code branches pass CI as well. You never know what might happen and how code may get merged if you have multiple engineers only contributing to the same codebase.
Continuous Deployment
CD is the process of automating deploying your newly merged in code to your staging or production environments. This usually happens directly after the CI process just described, once you know your code has passed whatever testing you have setup. Some people may refer to the whole process as CI or CD and the terms can be used somewhat interchangeably as someone who has implemented CI on their project has likely also implemented the CD part as well.
To automate your deployment process, it depends on what part of the tech stack we’re considering, what technologies you’re using, and what services you’re using for deployment. If we’re considering a frontend application utilizing React, Vue, or Angular then CD could refer to bundling your application and then sending it to something like S3 where you are hosting it. If you’re using a service to host your application, such as Render it could be that they actually handle most of the CD process for you and just listen for when certain branches are updated.
If we’re considering the backend, you may be using a service that interfaces with docker containers and your CD needs to push a new image. You could also be using something like Heroku that helps manage the deployment process and there is little for you to set up.
Services
As discussed above, there are a lot of tools and services that now exist around CI/CD. It largely depends on what you’re using for version control for your code and what you’re using to host the different pieces of your application. Some services to look into include CircleCI, Github Actions, and Codeship.