The previous articles discussed WordPress best practices for enterprise sites and other sites that have high traffic. The best practices entailed developing better methods of security, how to optimally customize your site to tailor it to your audience, and how to become familiar with utilizing Amazon Web Services (AWS).
This article will discuss how to have an ideal development workflow with numerous developers on the same project. This pertains to you when working on enterprise and high traffic sites because you are likely to have a whole team of developers dedicated to the same project. This article will help you better understand how to balance the workload and execute optimal developmental workflow for your website.
A Guide to Version Control
Version Control is an important tool for any developer. Version Control (VC) can make your life so much easier, especially once you’ve gotten the basics of it down. Since most of you reading this are already familiar with the basics, let us continue on. VC is very helpful in regards to improving your workflow. This can be achieved by learning to code in branches.
Coding in branches is an easy tactic that allows you to have your work organized more efficiently. Branches allow you to separate your “in-progress” projects from your finalized, tested, and stable code. This is method makes it easy to collaborate with other developers. It also helps you to systematize the timing of updates and/or fixes to your servers.
Coding Master Branches
You may not know how to utilize branching in your development workflow process, but little did you know that you have already been using a branch all along! This is done by committing your code to VC. In most major version control systems, each repo has at the minimum one branch by default. This is your working branch:
- in Subversion this is a folder called trunk,
- in Git this is a branch called master.
Even without constructing anything, your first commit to any repository will be made to this working branch.
Each version control system has a diverse method to creating, merging, and deleting branches. Now we will investigate the overall development process of vision control systems and branches.
Branches take some time to get used to using. By focusing on the two specific uses for branches, building features and fixing bugs, this will certainly help you become familiar with using them.
Building Features & Fixing Bugs
- Usually coding goes into one of two categories: either you are building new features or fixing bugs that come from a current codebase. Trouble can arise if these two areas need addressed at the same time.
- Pretend that you and your team are about to launch Feature Y. Everything is going smoothly and you move down your to-do list to look at Feature X. You begin coding and committing changes to your repository, but all of a sudden, an issue that demands your immediate attention comes up with Feature Y. What do you do?
- If your work is being completed in the default working branch of your repository, then you must come up with a way to save the work you’ve done so far on Feature X. Then you will have to revert your repository to the state it was in doing the launch of Feature Y and make your fix. After that you’ll have to re-introduce your work from Feature X. This whole situation sounds messy, doesn’t it? Not to mention the plausibility of losing your work or getting new bugs.
- A solution to a possible nightmare would be to complete all the work in a feature or bug-fix branches. Then let the version control system (VCS) do all the work for you! You would branch your repository from the point where Feature Y was deployed and make another working copy for yourself so that you can complete new work on it. Your Feature X branch includes the entire repository’s history and code but has its own separate history. This allows you to work on the Feature X branch without interrupting the code that you deployed to deploy Feature Y. Once the feature is tried and tested, then you are ready for deployment and can combine the branch back into the main working branch.
This also allows you to move between a feature branch to the default working branch at any time to create new branches from the “starting” point. After moving back to the working branch, you could make a bug-fix branch which would protect you from potential future bug problems.
Best Practices: Feature & Bug Branches
- Avoid committing incomplete work to your repository’s default working branch.
- Produce a branch any time you begin features and complex bug-fixes work.
- Always delete feature branches once they are combined into stable branch. This will keep your repository clean.
Benefits of Branching: Environment Branches
Version control allows you to use your repository as the source to deploy code to your servers. Similar to feature and bug-fix branches, environment branches make it simple to detach your in-progress code from your stable code. Using environment branches and deploying from them will ensure you to always know what code is running on your servers in each environment.
A default working branch is also known as a development environment branch. Know that it is important to keep the branch clean, which can be achieved by using feature and bug-fix branches. Then you merge them back to your development branch, containing only stable code. When using the word “stable: we will now mean a reference to this branch.
Utilizing Production and Staging Branches
Additionally, developers will have at least one more environment: production. This is where your enterprise site will run. Making a production environment branch the only source of code that goes to production will guarantee that you have an accurate picture of what is on your production server at all times. This also means you will have a history of what has been added to production.
For the most part, developers will have a staging environment as well. This environment is where the team or clients can review changes together and collaborate. Having a staging environment branch will confirm you to possess an environment with the same benefits as a production branch.
After your development environment has been updated with features and bug-fixes that are tested, you can use your VCS to do a diff between your stable branch and staging branch. This will allow you to examine what would be deployed that’s not presently on staging. It is also an opportunity to investigate for low quality or incomplete code, debug code, and other development errors that shouldn’t be deployed. This diff can also be accommodating in writing your release notes.
Do Not Merge to Environment Branches Without Deploying
To keep your environment branches in sync with the environments, a best practice to follow is to only implement a merge into an environment branch at the time you plan on deploying. If you complete a merge without deploying, your environment branch will be out of whack with your actual production environment. Also with environmental branches, you never want to commit changes straight to the branch. When a developer only merges code from their stable branch into staging or production branches, they guarantee that changes are flowing in one direction. The direction is from feature and bug-fix branches to stable and staging environments, and then from stable to production.
Best Practices with Environment Branches
- Use your repository’s default working branch as your “stable” branch.
- Make a branch for each environment.
- Only merge into an environment branch if you are ready to deploy to that environment.
- Always complete a diff between branches before merging. This will prevent merging something that wasn’t supposed to merge and can also assist with writing release notes.
- Merges should only flow in one directional pattern: first from feature to staging for testing; then from feature to stable once tested; then from stable to production to ship.
Deployment and Best Practices with Ideal Development Workflow
This section will help developers conceive how to accurately address deployments in their development workflow and also provide best practices with deployments. A bad production deployment can cause devastation to all the efforts your team produces in a development process. A solid deployment workflow can become a great asset to your team.
A Quick Note on Development Branch
In this section you will see a lot of references to a branch called development. In your repository you can use master (Git), trunk (Subversion) or default (Mercurial) for the same purpose, there’s no need to create a branch specifically called “development”.
Deployments should be treated as part of a development workflow, and not as an addendum. If you are developing an enterprise or high traffic site, your workflow will usually consist of at least three environments: Development, Staging and Production. In that case the workflow might look like this:
- Developers work on bugs and features in separate branches. Very small updates can be committed directly to the stable development branch.
- Once features are applied, they are combined into the staging branch and sent to the staging environment for quality testing.
- After testing is satisfactory, feature branches are merged into the development branch.
- On the release date, the development branch is merged into production and then deployed to the production environment.
If you make web applications, you don’t need a remote development environment. Every developer should have a local setup of their own.
During a case study of a program called Beanstalk, it was determined that some teams have development environments set up with automatic deployments on every commit or push. This may give developers a minor advantage of not installing the site or the application on their computers to perform testing locally, but it is mostly a huge waste of time. It considers every tiny change, which then must be committed, pushed, and deployed. Only then it can be verified. If the change was made by mistake, a developer will have to revert it, push it, then redeploy. Again, so much time wasted!
Testing on a local computer removes the need to commit, push and deploy completely. Every change can be verified locally first, and then it can be moved into a staging environment for proper quality assurance testing.
Once the features are implemented and found fairly stable, they are combined into the staging branch. From there they are automatically deployed to the staging environment. Quality assurance takes place and testers go to staging servers to verify that the code works as planned.
Be sure to have an isolated branch called staging to signify your staging environment. This will allow developers to deploy multiple branches to the same server at one time. This is done by condensing everything that needs to be deployed to the staging branch. This also assists testers to understand what exactly is on staging servers at the moment, just by examining inside the staging branch.
- Once the feature is implemented and tested, it can be deployed to production. If the feature was implemented in a separate branch, it should be merged into a stable development branch first. The branches should be removed after they are merged to dodge any potential confusion between team members.
- The following step is to make a diff between the production and development branches to take a quick peek at the code that will be sent to production.
- Once the diff review is finished, you can merge the development branch into production and then prepare a deployment of the production branch to your Production environment manually. Be sure to create a meaningful message for your deployment so that your team knows exactly what you deployed. Better to be specific then to create confusion.
- Make sure to only merge development branch into production when start to prepare for deploy. Do not merge anything into production in advance. Stick to the plan and merge on time. This will make the files in your production branch match files on your actual production servers. With everything matching up, this will make sure that the team better comprehends the state of your production environment.
- It is recommended to always deploy major releases to production following a scheduled and agreed upon time. Be sure to find the time when your enterprise site is least active and use that time to roll out updates (pay attention to your traffic history for this). Plan around a time that isn’t too late either because someone will need to be on the clock for a few hours to monitor the deployment and make sure it didn’t come with any problems.
- When deployment finishes, be sure to verify it. A good way is to check all the features or fixes that you deployed to make sure they are functioning correctly in production. Kudos to you and your team if your deployment tool can send an email to all team members with a summary of changes after every deployment. This tool keeps everyone on track and is a great source of communication to clients.
When deployments don’t go according to plan, as in if things break, then all your hard work is seemingly thrown out the window. In these cases, you have the possibility to rollback. Tip: always be as careful with rollbacks as with the production deployments themselves. Sometimes a rollback may bring more cause more problems then intended. To avoid unforetunate mishaps, be sure to ask the following questions before a rollback:
- Did it break because of the code that I deployed, or did something else break?
- You can only rollback files that you deployed, so if the source of the issues is something else a rollback will not help the situation.
- Is it possible for me to rollback this release?
- Not all releases can be rolled back. This can be due to a release introducing a new database structure that is unsuited with the previous release. In that case, if you rollback your application will break.
If the answer to both questions is “yes”, you can rollback safely. After rollback is done, be sure to fix the bug that you discovered and commit it to either the development branch (if it was minor) or a detached bug-fix branch. Then proceed with the regular bug-fix branch → staging; bug-fix → development → production integration workflow direction.
Deploying Urgent Fixes
There may be a time when you have to deploy a bug-fix to production rapidly, when your development branch is not ready for release yet. The workflow in that case stays the same as mentioned above, but instead of merging the development branch into production, you will merge your bug-fix branch first into the development branch. Then separately into production (without merging development into production). After that, deploy the production branch as usual. This will make sure that only your bug-fix will be sent to the production environment without all the uncompleted items from the development branch.
A word to the wise: it is necessary to merge the bug-fix branch to both the development and production branches in this case. This is crucial because your production branch should never include anything that is not a part of your stable development branch. The development branch is where developers spend most of their time, so if your fix is only in the production branch then it can cause confusion since the team would most likely not see it in that branch.
Automatic Deployments to Production
An important part of all of this is for all production deployments to be performed and verified by a qualified human being. Avoid using automatic deployments for production environment; this is dangerous and can lead to confusing results. If every commit is deployed to your production site automatically, imagine what happens if someone commits something by mistake? Using automatic deployments makes your production environment very susceptible to such problems.
Every developer should have access to deploy to the Staging environment. However, they need to make sure that they don’t override or overwrite their teammates’ changes when they do. The staging branch is a great help for this because all changes from the team developers are merged into it and therefore it contains all of them.
Your team’s production environment should only be available to a limited number of experienced developers. These individuals should always be equipped to fix the servers immediately after a deployment caused problems.
Building a workflow that suites your development team takes time, patience and some experimentation. If you are in a hurry and need results quickly, get in touch with us for your enterprise WooCommerce or enterprise WordPress projects.