Blogs / Software Mechanics: A Guide to Semantic Versioning

Software Mechanics: A Guide to Semantic Versioning

August 17, 2023 • Matthew Duong • Software Engineering • 2 min read

Software Mechanics: A Guide to Semantic Versioning

The Problem

Software, akin to a car, depends on components (dependencies) that require consistent upkeep. Unlike a car, though, software must often be updated without interruption, a process comparable to performing maintenance on a car engine while it's still running.

Cars break down due to wear and tear. Software breaks down due to newly discovered security vulnerabilities, as well as changes in its internal dependencies (akin to a car's gears) and external dependencies (resembling the "suppliers or supply chain" in automotive manufacturing).

Upstream Dependencies: The Software Supply Chain

In software engineering, upstream dependencies are like the suppliers in a car's manufacturing chain. If the supplier of a specific part makes a change, it could affect the final product. Similarly, changes in a library or external API that your software relies on directly can have a ripple effect, requiring you to adapt your code to maintain smooth operation. Generally you want to avoid having any external dependencies or libraries for the reasons above, however this is not always possible.

The Need for Semantic Versioning

Managing these dependencies can be a complex task. This is where Semantic Versioning comes into play. Just as cars have specific models and versions to signify differences in features or specifications, software utilises versions to communicate changes and updates.

What is Semantic Versioning?

Semantic Versioning, or SemVer, is a versioning scheme that conveys meaning about the underlying changes with each new release. It follows a structured format of three numbers: MAJOR.MINOR.PATCH.

MAJOR: Indicates changes that may require significant adjustments to the connecting software. Upgrading a major package often necessitates overhauls.

MINOR: Adds new features without breaking existing functionality. Upgrading to a minor version should typically be a drop-in replacement, though some risk may exist.

PATCH: Focuses on fixes to existing features without adding new ones. Switching out a dependency that only differs in patch version is usually low risk.

Why Semantic Versioning is Essential

Semantic Versioning provides clarity and predictability in the software development lifecycle. By understanding the versioning, software engineers and users can make informed decisions about when and how to update dependencies.

Clarity: It informs the software engineers and users what exactly has changed between versions.

Predictability: It allows teams to plan and manage dependencies with minimal disruptions.

Compatibility Assurance: It helps ensure that updates and changes don't unexpectedly break existing functionalities.

My Strategy to Software Upgrades

Managing upgrades across multiple dependencies is a complex but essential aspect of software engineering. Here's the generalised strategy I often employ:

  1. Bump All Minor Versions: I start by upgrading minor versions to their latest. Though generally intended to add features without breaking existing behaviour, thorough testing is still essential, as exceptions can occur.
  2. Handle Major Upgrades Individually: Major version upgrades are treated with caution and handled one by one to isolate and understand their impact, minimising potential issues.
  3. Testing and Validation: Continuous testing ensures stability, with rigorous validation to detect any unexpected problems.
  4. Continuous Monitoring: Post-upgrade, ongoing monitoring identifies and corrects latent issues quickly. This approach, rooted in careful planning and execution, leverages Semantic Versioning principles to navigate the complexity of upgrades. It reflects a systematic method I use in my software engineering practice to ensure robust and resilient systems.

The Takeaway

Upgrading software is a complex task fraught with challenges, akin to maintaining a car's intricate mechanics. By employing a strategic approach of handling major and minor versions, and adhering to Semantic Versioning principles, software engineers can navigate these challenges to create resilient and reliable software systems.

© 2023-2024 Matthew Duong