How to maintain scalable code version control in WordPress?
Keeping a well-structured version control management system and tracking the progress and evolution of code over time are the main differences between WordPress pros and amateurs. In this article, we’ll explore the basics of our version control methodologies and provide some good practices for WordPress developers to take advantage of.
By Sebastian Portesi
10 Min read
In WordPress, version control is the management of the changes made to code related to plugins, pages, and all other components of your website.
Keeping a well-structured version control management system and being able to track the progress and evolution of code over time is one of the main differences between WordPress pros and amateurs.
In fact, at White Canvas, we believe that great and scalable version control is the cornerstone of our efficiency. Without a sound version control system, we would not be able to deliver our projects as reliably and consistently as we do.
In this article, we’ll explore the basics of our version control methodologies and provide some good practices for WordPress developers to take advantage of.
Disclaimer: the rest of the article assumes that you are familiar with Git, so we will not spend much time delving into its fundamentals. If you want to develop good version control practices, Git is the world’s leading version control system and probably the best alternative for you to explore due to how widespread it is.
Since this is a guide for using Git, “Git” and “version control system” will be used interchangeably.
The benefits of version control
As a refresher, these are the main benefits of maintaining a sound version control management system.
With Git, you can make changes to files while retaining all progress made up to that point in the previous version.
Individual developers can progress in isolation without affecting the work of others.
When developers push their commits, other developers in the team will have access to their code within Git.
Git allows you to manage copies of the main code (branches) to edit them in isolation and then merge them into the main code to incorporate the changes. Many WordPress developers (like our team) use GitFlow, an alternative Git branching model, as a universal branching solution.
Reviewing code is essential for quality assurance, and Git offers integration with code review solutions. Gerrit is one of the most popular, enforcing code standards and quality for large teams in a decentralized manner. Some cloud hosting solutions like GitLab has integrated code review solutions.
Continuous integration is the automated practice of merging feature branches into the main branch and testing them immediately. By leaning into CI, developers can quickly determine whether the changes made failed or succeeded and act accordingly.
The pillars of version control
To master your team’s version control strategies, you must familiarize yourself with the fundamentals and learn good practices for implementation. For us, the 3 pillars of version control are cloud repositories, branching strategies, and CI/CD strategies.
Let’s explore how to optimize each of them.
There are several cloud hosting alternatives for your WordPress code, such as GitLab, GitHub, and Bitbucket. In addition to hosting versions of our code, these hosting systems offer multiple other functions. To determine which is best for your team, you must compare the features with your specific needs.
For example, if your team or your client contracted Jira for project management, it makes the most sense to use Bitbucket due to its direct integration to manage issues, branches, pull requests, etc. If your team uses Jira, Bitbucket is pretty much the go-to.
If Jira integration is not a concern and the project will require complicated CI/CD pipeline integrations, GitHub and its community actions may be convenient for your team. Community actions allow your team to save resources by using the tried-and-true prior work of others to perform complex processes like creating AWS instances and much more.
Finally, if your project requires flexibility, integrations, pipelines, issue management, projects within the same version control host, and, in short, the Swiss army knife of version control, GitLab is the solution.
The following table breaks down some of the main benefits of each cloud platform.
Git Cloud Platforms
• The most popular repository, with a thriving, growing community. • The team’s commit history is visible. • Pull requests. • Issue tracking. • Email notifications for pull requests, pipeline failures, mentions, and more. • Rich APIs with excellent documentation. • Free team plan with unlimited private repositories and collaborators. • GitHub Actions offer various workflow automation and CI/CD tool options. • Great for documentation and commonly used for collaboration. • GitHub can be a great starting point for a team of developers choosing their repository.
• Visible commit history. • Pull requests. • Issue tracking. • User-friendly interface. • Email notifications. • Robust CI/CD pipelines and workflow automation. • Great for technical teams that aren’t planning to collaborate outside their organization.
• Free plan for private repositories, with a limit of 5 collaborators. • Includes a REST API to build 3rd party applications. • Email notifications. • Commit history. • Pull requests • Issue tracking. • More features geared towards managers and analytics. • Potentially the best option for teams using JIRA or other Atlassian products.
Once you’ve chosen a Git cloud hosting solution, you must determine the branching strategy.
If you have any experience with version control and reading “branching strategy”, it probably brings the image below into your mind, which corresponds to a branching strategy Vincent Driessen came up with over 10 years ago in his post “A successful Git branching model”.
This model has become extremely popular in the past decade, to the point that some teams consider it the de facto standard for modern branching strategies. The reality is that for some projects, their branching strategy may look like this, while for others, it may not. Nevertheless, remember that this strategy was not built for modern or agile solutions.
Git is most commonly used for web apps, which are continuously delivered and not rolled back. Developers don’t have to support multiple versions of their web apps, which is contrary to the strategy Driessen devised. This strategy works wonders for some teams; for others, it won’t work.
All of this is to say: when choosing a branching strategy, you have to consider the needs of your team to avoid falling into the trap of chasing one-size-fits-all strategies. Think about the team’s needs in terms of branches, merging strategies, pull requests, and how you’ll manage deployments.
Over time, team members will need to use a combination of theory and experience to create the perfect solution for the project.
Here are 3 good practices we use for optimizing our branching strategy.
Keep only one main branch.
Having multiple “main” branches (DEV, STG, PROD, main) creates long-term maintenance problems. They’ll eventually suffer offsets and conflicts, and it’ll be hard to tell what features are part of each branch without dedicating time and energy to document them. In short, a mess.
What we do is keep a single main branch and multiple feature branches, which contain a single task or feature each.
Minimize how long branches are active.
Keeping branches alive for too long also causes maintenance issues. Smaller branches with smaller merges are easier to manage. Get into the habit of committing and often merging rather than letting branches grow too big for too long. Make atomic progress.
For us, most branches stay active for less than one week.
Merge and deploy from pull requests.
Always merge from pull requests, not locally. This way, everyone can track the merge’s origin. The same goes for deployments: deploy from pull requests or feature branches.
When you’ve confirmed that everything is working correctly, then merge. Otherwise, you risk introducing bugs into the main branch.
Defining how your team will upload their code into the PROD, STG, and DEV environments is essential. What we do is set up continuous integration and continuous delivery (CI/CD) pipelines. You’ll be able to configure these pipelines from any of the cloud platforms we’ve explained before.
These are 5 of the good practices we use for optimizing our CI/CD pipelines:
Use pipeline-specific commands.
Most teams use installable dependencies through npm or Yarn. Many of them will issue npm install on the pipeline, ignoring the much more efficient npm ci command. npm ci uses “package-lock.json” to install dependencies, which makes it about one-third faster and will not try to update any reliance in the process.
Configure the cache and artifacts.
It’s a great way to reduce pipeline computing times and keep cached copies of the artifacts each pipeline produces.
Whenever possible, deploy via Git.
Make deploying via Git a priority. You can, for example, connect via SSH to the server and update the branch. Or you can check out the commit you want to deploy via Git. At all costs, avoid deploying with the SCP or RSYNC commands, as they lack the functionality to tell team members what’s been modified and what stayed the same.
Get used to rebase, revert and cherry-pick.
These are the three most useful commands to maintain branches. If you use them daily, though, something is wrong with the team’s CI/CD strategy.
When handling merge conflicts, be practical.
Merge conflicts happen, but how you manage them is crucial to the efficiency of the CI/CD pipeline. As a rule of thumb, choose already-productive code over code in development and older code over newer code. You can always go back to and solve bugs, but breaking something that’s already working causes all sorts of issues you want to avoid.
Additionally, we recommend automating the pipeline’s dependencies and asset builds for pull request optimization and requiring manual confirmation to deploy into the various environments.
For WordPress precisely, we can follow two main roads: versioning the entire WordPress installation and versioning only the theme. Let’s explore both.
Versioning the entire WordPress installation
With this strategy, you’ll use a very permissive .gitignore file to version the entire WordPress installation, such as plugins, core files (wp-includes, wp-admin, etc.), and the rest of the necessary project files, while ignoring everything else.
You’ll ignore unnecessary directories, such as uploads and other folders that shouldn’t be included in the version, like node_modules or the vendor folder generated by PHP Composer.
For an idea of how to structure this file, use this WPEngine-recommended .gitignore file.
This method doesn’t require much explanation. It’s the most used method and only requires you to ignore uploads and development dependencies.
Versioning only the theme
The second strategy involves only versioning the essential theme files while ignoring the overall WordPress installation. In addition to the core files, we’ll be ignoring directories such as wp-content/uploads, node_modules, and vendor.
If you plan to use this strategy, you likely already have versioned your project. At this point, you need to start ignoring specific files and directories.
First, create your .gitignore file or modify the existing one based on your needs. Then issue this command on your project’s root directory:
$ git rm -rf --cached
This will leave a local copy ready for a commit. And that’s it.
For the next version, we need to start honoring the limitations of our new .gitignore. From now on, we’ll only commit these changes, leaving us with a commit in which there’s only one modified file (.gitignore) and several deleted files (the ones we ignored).
$ git add .; git commit -m “Updated .gitignore”;
For this strategy, remember to have WordPress’ core files in place before applying the theme we saved. You can download WordPress’ core file here and separately download your repository.
Now create a symbolic link leading from the directory where the core files will be to the wp-content directory inside your repository, replacing the WordPress’ original wp-content.
The bottom line
Git is the world’s leading version control solution, and all WordPress developers should become familiar with it. Combined with an excellent remote code hosting solution, they make up the perfect duo your team needs to maximize efficiency and get projects done.
The key to using Git in combination with cloud hosting is understanding their inner workings and having a solid plan in place. Using it without proper guidelines for who can commit or without clear branching strategies or CI/CD management is a recipe for disaster.
With this guide, we hope to have provided a good introduction to the ongoing process of developing an excellent version control management system that supports the team’s needs and guarantees the project is always moving forward.