Pragmatic Versioning

Version: 0.1.0.0-alpha

Summary

This specification describes a set of rules and requirements that dictate how each version identifier must be bumped and assigned to releases, in a way that communicates the kind of modifications that were done to a versioned artifact.

A minimal version identifier takes the form GRADE.MAJOR.MINOR.PATCH and is bumped by incrementing:

Optional Metadata containing additional information associated to the release or the build take the respective forms -RELEASE.METADATA and +BUILD.METADATA and can be appended to a minimal version identifier.

Requirement Levels

The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “NOT RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in BCP 14 RFC 8174 when, and only when, they appear in all capitals, as shown here.

Scope

Pragmatic Versioning MUST be applied only to versionable artifacts that can evolve over time and meet the following requirements.

Artifacts

  • A versioned artifact MUST comprise a set of features or characteristics that represents a public contract between the providers and the consumers of the artifact.

    Examples
    • A public API, a software package or library in either source code or binary format.
    • A text document describing a protocol, specification or other type of technical standard.
  • The providers of the artifact MUST declare that it is using Pragmatic Versioning and SHOULD provide a link to this specification.

    Example

Features

  • The nature of the features MAY depend on the type of artifact, but they SHOULD be as precise and comprehensive as possible.
  • The features SHALL be modified by means of:
    • Corrections: modifications that SHALL only fix incorrect features.
    • Alterations: any other modifications that MAY replace or remove existing features from the artifact, or add new features to it.

Modifications

  • The modifications MUST be describable in terms of backwards-compatibility:

    • Backwards-compatible modifications (also known as internal changes): the outside of the modified artifact is indistinguishable from the unmodified artifact, or interchangeable.

      Examples
      • Adding a new public interface in an API.
      • Renaming a local variable in a private method of an application.
      • Removing a private method of a software library.
      • Marking any public functionality as deprecated.
    • Backwards-incompatible modifications (also known as external changes): the outside of the modified artifact is easily distinguishable from the unmodified artifact, or not completely interchangeable.

      Examples
      • Renaming a public method of a software library.
      • Removing a public class in an API.
    • Disruptive modifications (also known as structural changes): the modified artifact is totally different from the unmodified artifact, or not at all interchangeable.

      Examples
      • Making a big change of semantics in a software library.
      • Changing the paradigm of a software framework.
      • A change of the releasing policy.
      • A complete overhaul of the codebase.
  • The rules that determine the backwards-compatibility level of the modifications MAY depend on the type of the artifact. If the implications are not completely obvious, then the providers of the artifact SHOULD explain them in detail, next to the declaration of use of Pragmatic Versioning.

    Examples
    • The document “Requirements Analysis” uses Pragmatic Versioning:
      • Fixing typos or styling the document are considered backwards-compatible corrections.
      • Adding new optional requirements or recommendations are considered backwards-compatible alterations.
      • Rephrasing or altering in any way existing requirements are considered backwards-incompatible changes.
      • Adding new requirements or prohibitions, or removing existing ones are considered disruptive changes.

Releases

Releases are the only mechanism by which any modifications of the artifact MUST be published.

  • Each new release MUST be assigned a new, unique version identifier.
  • Releases MUST be immutable: once a release has been published, its contents MUST NOT be modified.

Initial Stages

  • During the first iterations of the process, the releases MAY be unstable:
    • Releases could contain mistakes or errors.
    • Releases could not be ready to be used in production environments.
    • Releases could suffer continuous changes.
  • The providers of the artifact MUST convey such situation to consumers by using a Grade Number of zero.
  • The first unstable release MUST be assigned to a version identifier 0.1.0.0 (additional metadata MAY be appended).
  • The next version identifier will be bumped normally, as per the rules described later in this specification. Eventually, the releases will progress to maturity and the first stable release will be published.

Stable Releases

  • The providers of the artifact SHOULD strive to publish stable releases:
    • Releases MUST NOT contain mistakes or errors, to the best of their knowledge.
    • Releases MUST be ready to be used in production environments.
    • Releases MUST carefully evolve the versioned artifact.
  • The first stable release MUST be assigned to a version identifier 1.0.0.0 (additional metadata MAY be appended).
  • The next version identifier will be bumped normally, as per the rules described later in this specification.

Pre-releases

Pre-releases are useful for demonstration and preview purposes before an actual release is published. Typically they have names such as Alpha, Beta, etc. and they are considered unstable by definition.

  • Pre-releases MUST include Release Metadata to indicate that they MAY not satisfy the intended compatibility requirements as denoted by their associated minimal version identifier.

Version Identifiers

Version identifiers are unique, textual values that MUST be assigned to releases so that they can be easily tracked down and distinguished from one another.

Minimal Format

  • A minimal version identifier MUST take the form GRADE.MAJOR.MINOR.PATCH where GRADE, MAJOR, MINOR and PATCH are dot separated, non-negative integers, and MUST NOT contain leading zeroes.

    Examples
    • 1.2.3.4
    • 8.16.0.64
    • 3.14.1.592
    • 1.02.3.4
    • 1.2.-3.4
    • 1.00.3.4
  • Each element SHALL either increase numerically or reset to zero.

    Examples
    • 1.9.3.5 can be bumped to 1.9.3.6
    • 1.9.3.6 can be bumped to 1.9.4.0
    • 1.9.4.0 can be bumped to 1.10.0.0
    • 1.10.0.0 cannot be bumped to 1.12.0.0
    • 1.10.0.0 cannot be bumped to 1.10.5.5
    • 1.10.0.0 cannot be bumped to 1.9.0.0
  • Identifiers containing both Grade Number and Major Number equal to zero are reserved and MUST NOT be assigned to releases, neither stable nor unstable.

    Examples
    • 0.1.0.0
    • 0.8.0.0
    • 1.0.0.0
    • 0.0.0.0
    • 0.0.0.1
    • 0.0.1.1

Metadata Format

There are two types of metadata that MAY be appended to a minimal version identifier to convey additional information:

Release Metadata

  • Release Metadata MAY be denoted by appending a hyphen and a series of dot separated identifiers to a minimal version identifier (immediately following the Patch Number):
    • Textual identifiers MUST NOT be empty and SHALL comprise only ASCII alphanumerics and hyphen [0-9A-Za-z-].
    • Numeric identifiers MUST NOT include leading zeroes.
    Examples
    • 1.0.0.0-alpha
    • 1.0.0.0-ALPHA.1
    • 1.2.3.4-1.beta.0.32
    • 1.2.3.4-SNAPSHOT.128.develop-branch
    • 1.0.0.0=alpha.1
    • 1.0.0.0-alpha;1
    • 1.0.0.0-@lpha.1

Build Metadata

  • Build Metadata MAY be denoted by appending a plus sign and a series of dot separated identifiers immediately following the Patch Number or Release Metadata:
    • Textual identifiers MUST NOT be empty and SHALL comprise only ASCII alphanumerics and hyphen [0-9A-Za-z-].
    Examples
    • 1.0.0.0+linux
    • 1.0.0.0-alpha+linux
    • 1.2.3.4-beta.512+linux-386.desktop.1024
    • 1.2.3.4+linux.zaragoza.19980425-123000
    • 1.0.0.0#linux
    • 1.0.0.0-alpha+linux!
    • 1.0.0.0-alpha+linux:386

Bumping Rules

Each new release SHALL be assigned to a unique version identifier that will depend on two factors:

  • The version identifier of the previous release, which will be used as the base.
  • The backwards-compatibility level of the modifications introduced by the new release.

Grade Number

  1. Grade Number MUST be incremented if any disruptive modifications are introduced.
  2. Patch Number, Minor Number and Major Number SHALL be reset to zero when Grade Number is incremented.

Major Number

  1. Major Number MUST be incremented if any backwards-incompatible modifications are introduced.
  2. Patch Number and Minor Number SHALL be reset to zero when Major Number is incremented.
  3. Grade Number SHALL be left unchanged.

Minor Number

  1. Minor Number MUST be incremented if any backwards-compatible alterations are introduced.
  2. Patch Number SHALL be reset to zero when Minor Number is incremented.
  3. Major Number and Grade Number SHALL be left unchanged.

Patch Number

  1. Patch Number MUST be incremented if only backwards-compatible corrections are introduced.
  2. Minor Number, Major Number and Grade Number SHALL be left unchanged.

Precedence

Precedence refers to how version identifiers are compared to each other when ordered.

  • Precedence MUST be calculated by separating (and ordering) the version identifier into:
    1. Grade Number
    2. Major Number
    3. Minor Number
    4. Patch Number
    5. Release Metadata
  • Build Metadata SHOULD be ignored when determining version precedence. Thus two version identifiers that differ only in the Build Metadata, have the same precedence.

    Examples
    • 1.0.0.0+debian.amd64 has the same precedence as 1.0.0.0+debian.x86
    • 1.0.0.0-alpha+100 has the same precedence as 1.0.0.0-alpha+999
  • Precedence is determined by the first difference when comparing each of these identifiers from left to right as follows: Grade Number, Major Number, Minor Number and Patch Number are always compared numerically.

    Examples
    • 1.0.0.0 comes before 2.0.0.0
    • 2.0.0.0 comes before 2.1.0.0
    • 2.1.0.0 comes before 2.1.1.0
  • When Grade Number, Major Number, Minor Number and Patch Number are equal, a version identifier that includes Release Metadata SHALL have lower precedence than its associated minimal version identifier.

    Examples
    • 1.0.0.0-alpha comes before 1.0.0.0
    • 1.0.0.0-1 comes before 1.0.0.0
  • Precedence for two version identifiers that include Release Metadata and with the same Grade Number, Major Number, Minor Number and Patch Number MUST be determined by comparing each dot separated identifier, from left to right, until a difference is found as follows:
    • Numeric identifiers (consisting of only digits) SHALL be compared numerically
    • Textual identifiers (with letters or hyphens) SHALL be compared lexically in ASCII sort order.
    • Numeric identifiers SHALL have lower precedence than textual identifiers.
    • A smaller set of Release Metadata identifiers SHALL have lower precedence than a larger set, provided that all of the preceding identifiers are equal.
    Examples
    • 1.0.0.0-alpha comes before 1.0.0.0-alpha.1
    • 1.0.0.0-alpha.1 comes before 1.0.0.0-alpha.beta
    • 1.0.0.0-alpha.beta comes before 1.0.0.0-beta
    • 1.0.0.0-beta comes before 1.0.0.0-beta.2
    • 1.0.0.0-beta.2 comes before 1.0.0.0-beta.11
    • 1.0.0.0-beta.11 comes before 1.0.0.0-rc.1
    • 1.0.0.0-rc.1 comes before 1.0.0.0

Appendix

Glossary

Providers

The providers of an artifact are in charge of publishing new releases. Typically they are the ones who develop and integrate corrections and alterations.

Examples
  • Maintainers of a software library.
  • Authors and editors of a protocol, specification or other type of technical standard.

By adhering to Pragmatic Versioning, they express their commitment to publish new releases with a version identifier that follows the rules described in this specification.

Consumers

The consumers of a versioned artifact depend on it to achieve their goals. Typically they react to releases by deciding whether to use the new version of the artifact or not.

Examples
  • Developers of a software application that depends on a third-party library.
  • Implementors of a protocol, specification or other type of technical standard.

They have to be extra careful when backwards-incompatible modifications are introduced, that’s why it is so crucial that published releases follow the rules specified in Pragmatic Versioning.

Backus-Naur Form Grammar

Backus-Naur form grammar for valid PragVer version identifiers:

<Version Identifier> ::= <Minimal Version Identifier>
                       | <Minimal Version Identifier> "-" <Release Metadata>
                       | <Minimal Version Identifier> "+" <Build Metadata>
                       | <Minimal Version Identifier> "-" <Release Metadata> "+" <Build Metadata>

<Minimal Version Identifier> ::= <Grade Number> "." <Major Number> "." <Minor Number> "." <Patch Number>

<Grade Number> ::= <Number>
<Major Number> ::= <Number>
<Minor Number> ::= <Number>
<Patch Number> ::= <Number>

<Number> ::= "0"
           | <Positive Digit>
           | <Positive Digit> <Any Numeric Characters>

<Positive Digit> ::= "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
<Any Numeric Characters> ::= <Digit>
                           | <Digit> <Any Numeric Characters>
<Digit> ::= "0" | <Positive Digit>

<Release Metadata> ::= <Metadata>
<Build Metadata> ::= <Metadata>

<Metadata> ::= <Name>
             | <Number>
             | <Name> "." <Metadata>
             | <Number> "." <Metadata>

<Name> ::= <Any Alphanumeric Characters>

<Any Alphanumeric Characters> ::= <Alphanumeric Character>
                                | <Alphanumeric Character> <Any Alphanumeric Characters>

<Alphanumeric Character> ::= <Digit> | <Letter> | "-"

<Letter> ::= "a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "i" | "j" | "k" | "l" | "m"
           | "n" | "o" | "p" | "q" | "r" | "s" | "t" | "u" | "v" | "w" | "x" | "y" | "z"
           | "A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | "I" | "J" | "K" | "L" | "M"
           | "N" | "O" | "P" | "Q" | "R" | "S" | "T" | "U" | "V" | "W" | "X" | "Y" | "Z"

Railroad Diagrams

Version Identifier Diagram

Minimal Version Identifier Diagram

Metadata Diagram

Number Diagram

Name Diagram

Decision Tree

The next diagram helps determine which number must be incremented when bumping a new version identifier, by reasoning about the type of modifications that will be released and their backwards-compatibility level:

Perl Compatible Regular Expression

PCRE for valid PragVer version identifiers:

(?P<grade>0|[1-9]+\d*)\.(?P<major>0|[1-9]+\d*)\.(?P<minor>0|[1-9]+\d*)\.(?P<patch>0|[1-9]+\d*)(?:-(?P<release_metadata>(?:[A-Za-z0-9-])+(?:\.(?:[A-Za-z0-9-])+)*))?(?:\+(?P<build_metadata>(?:[A-Za-z0-9-])+(?:\.(?:[A-Za-z0-9-])+)*))?