Recently I began ruminating on the many years of developing software especially for WordPress environments. There are as many development life cycle schemes as there are languages in which to craft your code. Ok that may not be exactly correct but let’s face it there are a lot of different strategies for getting the code from development into production.
Releasing code to production can simply be thought of a set of rules governing the process. It does not matter if you have a complex build pipeline with a series of testing stages or a manual floppy disk based sneaker net to SFTP delivery system. In order to release your code and remain gainfully employed you need to follow some sort of rules.
In this article I would like to focus on the what I call the classic release ladder because it works exceptionally well with WordPress development. In addition this process scales from a single site installation to the more complex WordPress MultiSite configuration. It can even handle the network of networks which is something not for the faint of heart.
The brings us to our first rule. The production database is the source of truth for all data. What this means is that the data entered via the CMS or various APIs into the production database is your golden standard. Personally I say it’s your platinum standard. Breaking the production data should be treated as if it’s a RGE (resume generating event). Which means that when you need to alter table definitions or reorganize content you are deliberate and you have tested the operation many times to insure the integrity of the production environment’s data upon completion.
The production database is the source of truth for all data
Rule number two is simply an extension of the first rule. Data may travel down the ladder from production into any of the lower environments but NEVER up the ladder into the production environment. Ideally you would routinely synchronize prod to staging during off hours and from staging to the other development environments as needed. This helps to minimize the routine maintenance load on your production environment.
Data travels down the ladder never up.
A word of caution when synchronizing data from production to alternative environments. Be certain to consider the repercussions of personal user data migrating from production to these alternative spaces. Depending upon your industry it may be illegal to transport this information. Just don’t do it. Whenever possible this data should be purged form the destination. The rule of thumb is to retain the personal information only when it is absolutely necessary. It is far better to use pseudo data to simulate people than to use data that can be traced back to actual people.
Third rule expunge personal user information from the production data exports.
This naturally segues into a discussion about code. Unlike data code moves up the ladder through a series of stages. All code changes begin with some sort of ticket outlining the requirements, goals and metrics for success. If we are not deliberate in our changes with a business goal and benefit attached then why are we expending the effort? From this starting point we need to prepare a feature branch linked to the ticket.
All code changes begin life in a feature branch attached to the requisition ticket.
Feature branches are the building blocks of releases. The code climbs the various stages of the ladder when it passes review process and the changes have been approved. So let’s begin.
In the above you see that I am using GitLab, and I assume that you are using some for of git. Most git based systems default to master as being the production branch; therefore, we can establish our second rule of code.
The master branch in the git repository is the source of truth for ALL code.
This rule means that the release, develop and feature branches are ALL derivatives of master. However there are subtle distinctions that we shall touch upon along the way. Upon completing your code changes in your local environment within the appropriate feature branch you need to push these to origin so that you may create a merge request (or pull request as they are called on GitHub). Regardless of the repository management solution you are using if it supports this kind of code review request workflow then USE it. The destination or merge target is the RELEASE branch.
This MR (merge request) will serve as your record of discussion relating to code quality and usability.
Here’s the tricky part. It’s developer slight of hand or what I call magick. We manually merge the feature branch into the DEVELOP branch. The develop branch is the integration environment and many QA and product people get hung up on nomenclature. Their heads usually explode because they can not disconnect the develop branch name from it’s purpose. There is also the concept that many falsely believe that they should only see a feature once it is production ready. This could not be further from the truth.
The develop integration branch is where your code changes commingle with other feature branch changes likely from other developers. You will likely encounter mergeflicts which must be resolved in order to start the automatic environment rebuild..
This is also where to showcase the work to QA and product owners so that they can collaborate and iterate over the final result. They have an opportunity to correct any assumptions you made during development on your local environment or deficiencies of their original ticket request. QA has the opportunity to refine the acceptance criteria.
If you need to make adjustments to code, simply check out your existing feature branch to your local again and make the necessary changes then commit them then manually merge into the DEVELOP branch, restarting the iteration process.
I would like to point out that in our GitLab we have set an automatic build on change pipeline for the develop branch. Each time new changes are push into the branch the pipeline automatically starts a rebuild of the integration environment. Note: build pipe lining is way out of scope for this article.
Once your feature has been approved for release meaning that you have QA/PO sign off on the ticket as well as peer review sign off on the MR. Merging the request into the RELEASE branch simply adds your code to the next potential release candidate. After resolving any mergeflicts this is generally the point that development is complete. The only caveat may be third party stakeholder (outside your company) review. Hopefully this level of UAT is rare as it can hold up a deployment.
Only approved features may be merged into the RELEASE branch to assenble the candidate
Whomever your team has elected as the release captain would assemble the release candidate and rebuild the staging environment accordingly. What this means is that in order to proceed the RELEASE branch needs a new merge request with MASTER as it’s target destination. Then as feature branches are merged into RELEASE their subject or summary line should be added to the MR for this release. I also recommend that you consider using semantic versioning notation for numbering your releases. The following is an example of this:
As you can see this release MR has a list of every item (i.e. feature) that was included. It gives us a very clear record of what we intend to ship during the release. In addition it also has a link back to the ticket request which just makes record keeping clearer. The staging environment is rebuilt, via a manual pipeline trigger, with all of the approved changes and everything is confirmed one more time. This provides the release captain with the confidence that things are working as expected. In addition it facilitates a fixed comparison point for after the deployment.
When the release captain merges this release it becomes part of MASTER and must be pulled then tagged with the appropriate release number accordingly prior to initiating the build process.
Once the build has completed and the deployment shipped to production the release captain needs to review server logs, as well as the production sites to confirm that all systems pass the appropriate deployment check list.
Always pull master and properly tag it before you start the build.
At this point I would like to point out that if your team is following more of a continuous integration and continuous delivery model your post production deployment review will probably be far less intrusive. That being said as extensive as this process is it can be used for a CI/CD SDLC with minimal modification.
I have skipped over the testing process especially automated testing. Automated testing is a philosophy in an of itself. Let me suggest that this should be part of your build pipeline and I strongly recommend that the heaviest routines should be part of your release candidate staging build process. Since this is where you are preparing your next release all heavy system tests as well as documentation generation should occur here and not during your production deployment. Unit testing should have occurred during the local dev before the code even gets committed and if you have integration tests then they should have been completed during the integration testing of the development phase.
A release is not complete until the master mergebacks have been done.
Finally, after a successful production deployment before you celebrate your success you must complete master mergebacks. This is the process of merging the new state of master back into both the RELEASE and DEVELOP branches.
Thou shalt not release to production on FRIDAY or any day prior to a holiday…
I hope that you have enjoyed this article and for your convenience I present an info-graphic of the release ladder below.