Use Semantic Versioning and Give Your Version Numbers Meaning

It's pretty amazing that in 2017 I still find plenty of projects with no versioning, a random version scheme, or stuck perpetually at 0.1.x. Figuring out the maturity of these projects or the scope of changes between two versions can be terribly difficult. Versioning without any guidelines produces meaningless versions, so we need to follow common guidelines that can make our version numbers meaningful.

Luckily, we have a standard for versioning our software that works quite well: Semantic Versioning (SemVer for short). You've probably seen the SemVer "triple" (e.g. 2.7.0) in your software journeys.

SemVer can be summarized quite simply. Your version is composed of three components: MAJOR.MINOR.PATCH.

There are simple rules that indicate when you must increment each of these versions:

  • MAJOR is incremented when you make breaking API changes
  • MINOR is incremented when you add new functionality without breaking the existing API or functionality
  • PATCH is incremented when you make backwards-compatible bug fixes

Getting Started with SemVer

Semantic Versioning is not complicated, and you can get started by following a small number of guidelines:

  1. New projects start at version 0.1.0
    • You are starting with a set of features, not bug fixes
    • Increment the minor version for each subsequent release
  2. Start versioning at 1.0.0 if:
    • Your software is already used in production
    • Other users depend on your software and care when the API changes
    • You are worrying about backwards compatibility
  3. The initial development phase is represented by MAJOR version 0
    • Make as many breaking changes as you want before v1.0.0
  4. Once you have released v1.0.0, API adjustments or other breaking changes are not acceptable without a new MAJOR version change
  5. If you are adding new features without breaking the existing API or functionality, increment the MINOR number.
  6. If you are fixing bugs, increment the PATCH number.
  7. Avoid making frequent breaking changes unless you absolutely need to!
    • Batch major changes together on a branch until you have enough to justify a new major release

Note well: Keeping a system that's in production or being heavily used at a pre-1.0.0 version is a bad practice. You might as well not be using SemVer at all.

But what if I need additional labels, like "alpha"?

It's pretty common to want to add labels to our builds, to indicate something like a pre-release, alpha, or beta software version.

Semantic versioning supports labels and build metadata as an extension to the MAJOR.MINOR.PATCH format. Simply add a hyphen and identifier to the version number.

For example, say you have a version 1.0.0 candidate ready but want to test it before you make your release. You could label the pre-release versions as follows:

1.0.0-alpha.1
1.0.0-alpha.2

Once you are happy with the stability of 1.0.0, you can make the official release and drop the alpha.x label.

The Semantic Versioning Specification

The Semantic Versioning web page contains the complete specification and answers common questions, so I recommend taking a few minutes to read through it.

Since you're already here, I've included v2.0.0 of the SemVer specification:

The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 2119.

  1. Software using Semantic Versioning MUST declare a public API. This API could be declared in the code itself or exist strictly in documentation. However it is done, it should be precise and comprehensive.

  2. A normal version number MUST take the form X.Y.Z where X, Y, and Z are non-negative integers, and MUST NOT contain leading zeroes. X is the major version, Y is the minor version, and Z is the patch version. Each element MUST increase numerically. For instance: 1.9.0 -> 1.10.0 -> 1.11.0.

  3. Once a versioned package has been released, the contents of that version MUST NOT be modified. Any modifications MUST be released as a new version.

  4. Major version zero (0.y.z) is for initial development. Anything may change at any time. The public API should not be considered stable.

  5. Version 1.0.0 defines the public API. The way in which the version number is incremented after this release is dependent on this public API and how it changes.

  6. Patch version Z (x.y.Z | x > 0) MUST be incremented if only backwards compatible bug fixes are introduced. A bug fix is defined as an internal change that fixes incorrect behavior.

  7. Minor version Y (x.Y.z | x > 0) MUST be incremented if new, backwards compatible functionality is introduced to the public API. It MUST be incremented if any public API functionality is marked as deprecated. It MAY be incremented if substantial new functionality or improvements are introduced within the private code. It MAY include patch level changes. Patch version MUST be reset to 0 when minor version is incremented.

  8. Major version X (X.y.z | X > 0) MUST be incremented if any backwards incompatible changes are introduced to the public API. It MAY include minor and patch level changes. Patch and minor version MUST be reset to 0 when major version is incremented.

  9. A pre-release version MAY be denoted by appending a hyphen and a series of dot separated identifiers immediately following the patch version. Identifiers MUST comprise only ASCII alphanumerics and hyphen [0-9A-Za-z-]. Identifiers MUST NOT be empty. Numeric identifiers MUST NOT include leading zeroes. Pre-release versions have a lower precedence than the associated normal version. A pre-release version indicates that the version is unstable and might not satisfy the intended compatibility requirements as denoted by its associated normal version. Examples: 1.0.0-alpha, 1.0.0-alpha.1, 1.0.0-0.3.7, 1.0.0-x.7.z.92.

  10. Build metadata MAY be denoted by appending a plus sign and a series of dot separated identifiers immediately following the patch or pre-release version. Identifiers MUST comprise only ASCII alphanumerics and hyphen [0-9A-Za-z-]. Identifiers MUST NOT be empty. Build metadata SHOULD be ignored when determining version precedence. Thus two versions that differ only in the build metadata, have the same precedence. Examples: 1.0.0-alpha+001, 1.0.0+20130313144700, 1.0.0-beta+exp.sha.5114f85.

  11. Precedence refers to how versions are compared to each other when ordered. Precedence MUST be calculated by separating the version into major, minor, patch and pre-release identifiers in that order (Build metadata does not figure into precedence). Precedence is determined by the first difference when comparing each of these identifiers from left to right as follows: Major, minor, and patch versions are always compared numerically. Example: 1.0.0 < 2.0.0 < 2.1.0 < 2.1.1. When major, minor, and patch are equal, a pre-release version has lower precedence than a normal version. Example: 1.0.0-alpha < 1.0.0. Precedence for two pre-release versions with the same major, minor, and patch version MUST be determined by comparing each dot separated identifier from left to right until a difference is found as follows: identifiers consisting of only digits are compared numerically and identifiers with letters or hyphens are compared lexically in ASCII sort order. Numeric identifiers always have lower precedence than non-numeric identifiers. A larger set of pre-release fields has a higher precedence than a smaller set, if all of the preceding identifiers are equal. Example: 1.0.0-alpha < 1.0.0-alpha.1 < 1.0.0-alpha.beta < 1.0.0-beta < 1.0.0-beta.2 < 1.0.0-beta.11 < 1.0.0-rc.1 < 1.0.0.

Further Reading

Embedded Artistry README Template

In the previous post I shared tips for writing a better README. Today I'd like to share my README template with you.

This template is probably much more involved that other README files that you have seen. This template is meant for developers who are committed to a standard of excellence and want to provide quality documentation for their projects. Our goal is to anticipate users' questions before they encounter them and make our documentation as comprehensive as possible. By putting effort into your documentation, you make it much easier for other developers to use and contribute to your projects.

You can always find this README template in the embedded-resources GitHub repository.

README Template (Markdown)

# Project Title

Provide an introductory paragraph, describing:

* What your project does
* Why people should consider using your project
* Link to project home page

## Table of Contents

1. [About the Project](#about-the-project)
1. [Project Status](#project-status)
1. [Getting Started](#getting-started)
    1. [Dependencies](#dependencies)
    1. [Building](#building)
    1. [Installation](#installation)
    1. [Usage](#usage)
1. [Release Process](#release-process)
    1. [Versioning](#versioning)
    1. [Payload](#payload)
1. [How to Get Help](#how-to-get-help)
1. [Further Reading](#further-reading)
1. [Contributing](#contributing)
1. [License](#license)
1. [Authors](#authors)
1. [Acknowledgements](#acknowledgements)

# About the Project

Here you can provide more details about the project
* What features does your project provide?
* Short motivation for the project? (Don't be too long winded)
* Links to the project site

```
Show some example code to describe what your project does
Show some of your APIs
```

**[Back to top](#table-of-contents)**

# Project Status

Show the build status if you have a CI server:

[![Build Status](http://your-server:12345/job/badge/icon)](http://your-server:12345/job/http://your-server:12345/job/badge/icon/)

Describe the current release and any notes about the current state of the project. Examples: currently compiles on your host machine, but is not cross-compiling for ARM, APIs are not set, feature not implemented, etc.

**[Back to top](#table-of-contents)**

# Getting Started

This section should provide instructions for other developers to

These instructions will get you a copy of the project up and running on your local machine for development and testing purposes. See deployment for notes on how to deploy the project on a live system.

## Dependencies

Describe what software and libraries you will need to install in order to build and use this project. Provide details on how to resolve these dependencies.

Remember: git-lfs is a dependency that developers will need to resolve before they can get started with a repo using LFS.

```
Examples should be included
```

## Getting the Source

Include a link to your github reposistory (you have no idea how people will findy our code), and also a summary of how to clone.


This project is [hosted on GitHub](https://github.com/embeddedartistry/embedded-resources). You can clone this project directly using this command:

```
git clone git@github.com:embeddedartistry/embedded-resources.git
```

## Building

Instructions for how to build your project

```
Examples should be included
```

## Running Tests

Describe how to run unit tests for your project.

```
Examples should be included
```

### Other Tests

If you have formatting checks, coding style checks, or static analysis tests that must pass before changes will be considered, add a section for those and provide instructions

## Installation

Instructions for how to install your project's build artifacts

```
Examples should be included
```

## Usage

Instructions for using your project. Ways to run the program, how to include it in another project, etc.

```
Examples should be included
```

If your project provides an API, either provide details for usage in this document or link to the appropriate API reference documents

**[Back to top](#table-of-contents)**

# Release Process

Talk about the release process. How are releases made? What cadence? How to get new releases?

## Versioning

This project uses [Semantic Versioning](http://semver.org/). For a list of available versions, see the [repository tag list](https://github.com/your/project/tags).

## Payload

**[Back to top](#table-of-contents)**

# How to Get Help

Provide any instructions or contact information for users who need to get further help with your project.

# Contributing

Provide details about how people can contribute to your project. If you have a contributing guide, mention it here. e.g.:

We encourage public contributions! Please review [CONTRIBUTING.md](docs/CONTRIBUTING.md) for details on our code of conduct and development process.

**[Back to top](#table-of-contents)**

# Further Reading

Provide links to other relevant documentation here

**[Back to top](#table-of-contents)**

# License

Copyright (c) 2017 Embedded Artistry LLC

This project is licensed under the MIT License - see [LICENSE.md](LICENSE.md) file for details.

**[Back to top](#table-of-contents)**

# Authors

* **[Phillip Johnston](https://github.com/phillipjohnston)** - *Initial work* - [Embedded Artistry](https://github.com/embeddedartistry)

See also the list of [contributors](https://github.com/your/project/contributors) who participated in this project.

**[Back to top](#table-of-contents)**

# Acknowledgments

Provide proper credits, shoutouts, and honorable mentions here. Also provide links to relevant repositories, blog posts, or contributors worth mentioning.

Give proper credits. This could be a link to any repo which inspired you to build this project, any blogposts or links to people who contributed in this project. If you used external code, link to the original source.

**[Back to top](#table-of-contents)**

Your README Probably Sucks: It's Time to Make it Better

I can't recall how many times I've stumbled across an interesting project, been excited to start using it, and opened up the README to see… nothing.

Often it's just a simple initial one-liner that GitHub auto-generates for your repository. In better cases there may be some basic (out-of-date) instructions, but mostly I'm still left with more questions than answers:

  • How am I supposed to build your project correctly?
  • What if I need a static library instead of a dynamic library?
  • How should I use your project?
  • How do I satisfy this weird dependency?
  • How can I cross-compile your code?
  • What is this actually doing to make my life better?

A wonderful project with poor documentation is worthless to me. You spent hundreds of hours on your project, so make it easy for users to get started with your project, understand how it will help them, and find answers when they run into problems.

Let's take a look at the information a good README should provide.

First: A Note about "Readiness"

You may be waiting to write your README until your project is finished. This is a mistake.

I recommend a different approach: write as much of your README as you can before you start your project. A great post covering this topic is "README driven development". I highly recommend reading it if you need some motivation to get started.

Writing READMEs can be pretty dull and monotonous, and it's easy to skip your README altogether once you've finished your project. Without a framework in place for you to make updates as you work, you will likely lose track of critical details like important dependencies, setup steps, and solutions to problems that you encountered.

Now that we've gotten that out of the way, let's take a look at the elements of a high-quality README.

Formatting

That's right, I'm putting formatting at the top of the list. If your README is disorganized and poorly formatted, nobody is going to give it the time of day.

Most readers in our present era will be viewing your README in their web browser. Organizing your README into well-organized sections, formatting text so it stands out, and including a table of contents should be a priority.

Familiarize yourself with basic Markdown syntax to properly format your document. Add links to other documents and include images. You can even create a table of contents by using anchor links:

## Table of Contents
1. [About the Project](#about-the-project)
1. [Project Status](#project-status)
1. [Getting Started](#getting-started)

# About the Project

## Project Status

# Getting Started

Length

You want your README to be as short as possible while still explaining basic functionality and setup steps to your user. Long-winded background sections, detailed instructions, or other non-typical documentation should be provided separately and linked to within your README.

We don't want to scare our new users away with a great tome!

By having a well-formatted README, your readers won't immediately run away from a wall of unformatted text.

The Introduction

Your introduction may be the only chance you have to engage with someone who comes across your project. Include a well-crafted introductory paragraph to grab your reader's attention. Provide a high-level summary of what your project accomplishes and how others will benefit from using your project. Emphasize why your project is valuable and how it makes someone's life easier.

I generally include the table of contents in my introduction so readers can jump to a relevant section.

About your project

Include a section which describes your project in more detail than the introduction. Aim to answer these questions:

  • What is your project?
  • What is the intended use of your project?
  • How does it work?
  • Who uses it?
  • How can others benefit from using your project?

Project Status

While the previous section highlighted the goals of your project, we haven't always gotten around to completing those goals. You can include a section describing the current state of your project. This will give your readers a sense of the maturity of your project and areas where they might be able to help you.

Aim to include details regarding:

  • Build status (e.g. status widget from your CI server)
  • Health of the project
  • Information about the current release and how to find it (or link to the RELEASE file)
  • Known issues
  • Items you haven't been able to implement/fix yet
  • Things you're currently working on
  • Whether or not you want to accept contributions

Getting Started on your Project

Most of us only read a project's README in order to figure out how to start using a project. This section should be the bulk of your README contents. Keep in mind that many people start reading documentation only when they encounter a problem. Have you anticipated problems users may have? Are you recording solutions to common problems in an accessible place for new developers?

The easiest way to fill out this section is to help someone who has never used your project get set up, and write down the exact instructions. One you have those instructions ready, ask another person to follow them to see if you missed any critical steps.

You want to cover the following topics:

  • Dependencies that need to be installed for building/using your project,
    • Instructions for installing the dependencies
  • How to configure your project, and information on configuration options
  • How to build your project
  • How to install your project
  • How to run tests
  • How to use your project, or API usage information

Make sure to provide working code and command-line examples for each of these sections. And keep this section up to date!

Contributing

While the previous section covered how to start using your project, this section should provide information for people who are interested in developing on your project.

If you have a CONTRIBUTING file, provide a short blurb mentioning you welcome contributions and link to the file.

If you don't have a CONTRIBUTING file, provide instructions to help other developers get started.

Make sure to cover:

  • Additional setup steps that are specific for development
  • How users can contribute to your project
  • What kinds of assistance you are looking for
  • Information about your development and review process
  • Whether commits should be squashed before merging
  • Information on coding standards
  • Details on whether there are any requirements for contribution (e.g. a Contributor License Agreement)
  • Code of conduct for contributors

If you don't want contributors for your project, explicitly say so!

Other Important Details

There are many other useful details that you should include in your README file.

Release Process

You may also want to include notes on your project's release process:

  • What is your project's release cycle?
  • How can someone find the latest release?
  • What branches are used in the development process? (master, stable, etc.)
  • When are new releases made?

How to get help

Your documentation may not cover all of the problems that a user might have. Provide instructions for users to get more help. Include the best method of contact or a link to a relevant user group.

Further Reading

Your README is just a starting point for your project. Provide links to other references that people can refer to, such as:

  • Library documentation
  • Architecture references
  • FAQ
  • INSTALL file
  • CONTRIBUTING guidelines
  • CODEOWNERS
  • Related blog posts or white papers

Authors

Provide some information on the folks creating and maintaining your project. Include website links, GitHub profile links, and any contact information you want to share.

Acknowledgements

Did you use someone else's code?

Do you want to thank someone explicitly?

Did someone's blog post spark off a wonderful idea or give you a solution to nagging problem?

Provide a shoutout and a link in your README. We are all in this together, and giving credit where it is due is a great way to generate goodwill. And referencing external code also helps users track down the original source for use in their own projects.

License

Provide a summary of the software's license and a link to your detailed LICENSE file.

Also include relevant licenses from any external code that you have included.

Putting it All Together

These are simply guidelines for writing a good README. In my next post, I'll share the README template that I've developed for my own projects.

You can also learn more by looking at other high quality READMEs. Here are a few:[ Also add links to my own projects!]

Remember, your README is the first piece of your project that most people will encounter. If your project is great, your README should be great too.

Further Reading