Semantic Versioning

A lot of my work these days is all around web projects, where versions aren’t particularly used.  Code is written, tested, and deployed multiple times a day, rather than once in a while.  But if you are doing scheduled releases with major and minor changes, backward compatibility and so forth, please consider using Semantic Versioning.

In systems with many dependencies, releasing new package versions can quickly become a nightmare. If the dependency specifications are too tight, you are in danger of version lock (the inability to upgrade a package without having to release new versions of every dependent package). If dependencies are specified too loosely, you will inevitably be bitten by version promiscuity (assuming compatibility with more future versions than is reasonable). Dependency hell is where you are when version lock and/or version promiscuity prevent you from easily and safely moving your project forward.

As a solution to this problem, I propose a simple set of rules and requirements that dictate how version numbers are assigned and incremented. For this system to work, you first need to declare a public API. This may consist of documentation or be enforced by the code itself. Regardless, it is important that this API be clear and precise. Once you identify your public API, you communicate changes to it with specific increments to your version number. Consider a version format of X.Y.Z (Major.Minor.Patch). Bug fixes not affecting the API increment the patch version, backwards compatible API additions/changes increment the minor version, and backwards incompatible API changes increment the major version.

wp-config.php and git

If you are storing your WordPress changes in git and then deploy the project between different machines (local, test server, production environment, etc), then you are probably familiar with a problem of wp-config.php file.  WordPress uses it for things like database credentials, which vary from machine to machine.  But you can’t just ignore the file since it’s plays the role in WordPress bootstrap.  The solution that we are using at work is very simple: have an additional configuration file, such as wp-config-local.php, which defines local settings, and which is ignored from git.

Here is how to do this.  First, you need to create the file itself.  Let’s say we want to change the database credentials which WordPress should use on the current machine.  Create a file wp-config-local.php with the following content:

<?php
define('DB_HOST', 'localhost');
define('DB_USER', 'localdev');
define('DB_PASSWORD', 'code15poetry');
define('DB_NAME', 'wp_playground');
?>

Now we need to include the file from the wp-config.php. The local configuration file should be optional, so we only use it on those machines that need it. Here is the code that I’ve added to the top of my wp-config.php:

// Load wp-config-local.php
$localConfig = dirname(__FILE__) 
    . DIRECTORY_SEPARATOR . 'wp-config-local.php';
if (file_exists($localConfig) && is_file($localConfig) 
    && is_readable($localConfig)) {
    require_once $localConfig;
}

If you will have a look at your WordPress website now, it’ll probably be broken. That’s because you are not allowed to redefine constants. We’ve defined that in our wp-config-local.php which loads first, and then they are defined in the wp-config.php as well. We should work around this. For any constant that is defined in wp-config.php and which you want to be able to set from wp-config-local.php, change the line in wp-config.php like so:

// before
// define('DB_USER', 'root');
// after
if (!defined('DB_USER')) { define('DB_USER', 'root'); }

With this, you’ll basically have values in wp-config.php act as defaults. If there is no local configuration, they will be used. Otherwise, the local ones will be utilized.

The last tiny bit that you need to do is add wp-config-local.php to your .gitignore file. That’s it. Now commit, push, and enjoy.

Stash – privately hosted Git repositories

As far as I am concerned, GitHub is the king and queen of applications in the git world.  But it has a downside that is not easy to work around: GitHub Enterprise is expensive.  Keeping code on GitHub infrastructure is not always allowed by authorities and such, and then things get really expensive.  That’s where, I think, Stash can come in.

Stash is a product of Atlassian, the same company that owns Jira, BitBucket, and a few other well-known developer tools.  Given that Stash has only been launched this year, and judging by the screenshots, GitHub probably provides more functionality.  But as I said earlier, GitHub’s price might be simply too high for some companies.

It’s also worth noting that both companies have recently received large investments (Atlassian got $60 million and GitHub got $100 million).  Since private repositories and in-house installations seem to be the primary source of income for both of them, I’m seeing a revved up competition between the two in the nearest future.

Huge, huge thanks to git bisect! With its help, I …

Huge, huge thanks to git bisect! With its help, I just sorted out a huge argument about who removed a piece of code and when.  With an actively developed project among few developers and branches, it’s not trivial to say when the change was introduced.  Unless, of course, you are using git bisect.  Every developer should know how to use it.