Pragmatic Versioning

Version: 1.0.0.0

Summary

This specification describes a set of rules and requirements that dictate how versions 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 with the release or the build can be appended, taking the respective forms -RELEASE.METADATA and +BUILD.METADATA.

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

Artifacts

A versioned artifact MUST comprise a set of public features or characteristics that represents a public contract between the publishers and the subscribers 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.
  • A database schema, a logical entity–relationship model, or a conceptual data model.

Features

  • The nature of the features MAY depend on the type of the 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 backward-compatibility.
  • The rules that determine the backward-compatibility level of the modifications MAY depend on the type of the artifact.
  • If the implications are not completely obvious, then the publishers of the artifact SHOULD explain them in detail.

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

Backward-Compatible Corrections

  • Also known as fixing changes.
  • The modified artifact SHALL only include modifications that rectify incorrect features.
  • Looking from the outside, the modified artifact SHALL be indistinguishable from the unmodified artifact, or interchangeable.
Examples
  • Fixing a bug in a software library.
  • Removing some typos from a protocol specification.
  • Styling the document that defines a technical standard.

Backward-Compatible Alterations

  • Also known as internal changes.
  • The modified artifact MAY as well include corrections but MUST include other alterations.
  • Looking from the outside, the modified artifact SHALL be 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.

Backward-Incompatible Modifications

  • Also known as external changes.
  • Looking from the outside, the modified artifact SHALL be 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 SHALL be 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.

Versions

Versions are unique, textual identifiers composed of a REQUIRED core and an OPTIONAL metadata that MUST be assigned to releases so that they can be clearly tracked down and distinguished from one another.

Core

  • The core of a version 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
  • Versions containing both GRADE and MAJOR numbers equal to zero are not valid and MUST NOT be assigned to any releases.

    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

  • Two types of metadata MAY be appended to the core (immediately following PATCH number) to convey additional information.
  • When both of them are appended, release metadata MUST precede build metadata.

Release Metadata

Release metadata MAY be denoted by appending a hyphen - and a series of dot-separated, non-empty identifiers:

  • Numeric identifiers SHALL comprise only ASCII numbers [0-9] and MUST NOT include leading zeroes.
  • Textual identifiers SHALL comprise only ASCII alphanumerics and hyphen [0-9A-Za-z-].
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, non-empty identifiers:

  • Textual identifiers 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

Precedence

Precedence refers to how versions are compared to each other when ordered.

  • Before comparing two versions, they SHALL be split into GRADE, MAJOR, MINOR, PATCH, and release metadata.

  • Precedence MUST be determined by the first difference when comparing each of the numbers from left to right: GRADE, MAJOR, MINOR, and PATCH.

    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 the numbers are equal, a version that includes release metadata SHALL have lower precedence.

    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 versions that have the same numbers and include release metadata MUST be determined by comparing each dot-separated identifier, from left to right, until a difference is found:
    • Numeric identifiers SHALL be compared numerically.
    • Textual identifiers 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
  • 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.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

Bumping Rules

  • Each new release SHALL be assigned to a unique version that will depend on two factors:
    • The version core of the previous release SHALL be used as the base.
    • The backward-compatibility level of the modifications introduced by the new release SHALL determine the bump type.
  • Each numeric element SHALL either increase numerically or reset to zero.
  • Release metadata and build metadata MAY be arbitrarily modified.

Grade Bump

  1. GRADE number MUST be incremented if the release introduces any disruptive modifications.
  2. PATCH, MINOR, and MAJOR numbers SHALL be reset to zero.

Major Bump

  1. MAJOR number MUST be incremented if the release introduces any backward-incompatible modifications.
  2. PATCH and MINOR numbers SHALL be reset to zero.
  3. GRADE number SHALL be left unchanged.

Minor Bump

  1. MINOR number MUST be incremented if the release introduces any backward-compatible alterations.
  2. PATCH number SHALL be reset to zero.
  3. MAJOR and GRADE numbers SHALL be left unchanged.

Patch Bump

  1. PATCH number MUST be incremented if the release introduces only backward-compatible corrections.
  2. MINOR, MAJOR, and GRADE numbers SHALL be left unchanged.

Publishers

The publishers of an artifact are committed to publishing new releases with a version that follows the rules described in this specification.

Examples
  • Maintainers of a software library.
  • Authors and editors of a protocol, specification or other type of technical standard.
  • Publishers of an artifact SHALL be in charge of publishing new releases and MAY also be the ones who develop and integrate corrections and alterations.

  • Publishers SHOULD strive to publish stable releases.

  • Publishers MUST declare that they adhere to Pragmatic Versioning and SHOULD provide a link to this specification.

    Example

Releases

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

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

Initial Stages

  • During the first iterations of the development process, the releases MAY be unstable, which means that artifacts MAY:
    • Contain mistakes or errors.
    • Not be ready to be used in production environments.
    • Suffer continuous changes.
  • The publishers MUST convey this situation to subscribers by using a GRADE of zero.
  • The first unstable release MUST be assigned to version 0.1.0.0 (additional metadata MAY be appended).
  • The next version will be bumped normally, as per the rules described earlier in this specification. Eventually, the releases will progress to maturity and the first stable release will be published.

Stable Releases

  • After the first iterations of the process, the releases SHOULD be stable:
    • Releases MUST NOT contain mistakes or errors, to the best of publishers 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 version 1.0.0.0 (additional metadata MAY be appended).
  • The next version 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 or Beta. 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 core.

Subscribers

Subscribers of an artifact depend on its releases to achieve their goals and they usually have to be extra careful when backward-incompatible modifications are introduced.

Examples
  • Developers of a software application that depends on a third-party library.
  • Implementors of a protocol, specification or other type of technical standard.
  • Subscribers MUST make sure that the versioned artifact adheres to Pragmatic Versioning.

  • They MAY react to new releases by deciding whether to use or not new versions of the artifact:
    • Most subscribers SHOULD define a subscription to express a subset of the releases in which they are interested.
    • Some others MAY decide to stay locked on a specific version.
    • And some others might want to use any newly released version (NOT RECOMMENDED).
  • They SHOULD rely on automated tools such as dependency managers to keep their upstream dependencies up to date.
    • Those tools SHALL determine the most appropriate release available according to the subscription.

Subscriptions

Subscriptions provide a systematic way of finding the most up-to-date release in which a subscriber is interested.

  • A subscription MUST be represented as a character string.
  • Whitespace SHALL be ignored.
  • It MUST be denoted as a list of zero or more double-pipe-separated || selectors.
  • Given a list of released versions of an artifact, the most suitable one MUST be selected as follows:

    • If the subscription contains any selectors:
      1. All selectors MUST evaluate all the available versions.
      2. Each selector SHALL nominate at most one candidate version.
      3. The one with the greatest precedence MUST be selected.
      4. In case there are several of them with the greatest precedence, the one nominated by the leftmost selector SHALL be selected.
    • If the selector list is empty (NOT RECOMMENDED):
      1. The version with the greatest precedence of all available releases (excluding pre-releases) MUST be selected.
      2. In case there are several of them with the greatest precedence, the one without build metadata SHOULD be selected.

Selectors

Selectors help evaluate a list of versions and nominate one possible choice.

Core Comparators

Core comparators match versions depending on their core.

Comparison Operators
  • ==VERSION MUST be satisfied by a version whose core has equal precedence to VERSION.

  • !=VERSION MUST be satisfied by a version whose core has not equal precedence to VERSION.

  • >VERSION MUST be satisfied by a version whose core has greater precedence than VERSION.

  • >=VERSION MUST be satisfied by a version whose core has greater than or equal precedence to VERSION.

  • <VERSION MUST be satisfied by a version whose core has less precedence than VERSION.

  • <=VERSION MUST be satisfied by a version whose core has less than or equal precedence to VERSION.

  • FROM_VERSION - TO_VERSION MUST be satisfied by a version whose core has greater than or equal precedence to FROM_VERSION and less precedence than TO_VERSION.

  • ~VERSION MUST be satisfied by a version whose core has greater than or equal precedence to VERSION and less precedence than the result of performing a minor bump on VERSION.

  • ^VERSION MUST be satisfied by a version whose core has greater than or equal precedence to VERSION and less precedence than the result of performing a major bump on VERSION.

Shorthand Versions

A shorthand version is a shortened representation of a version core.

  • They MUST NOT contain any metadata.
  • Any occurrence of rightmost dot-separated zeroes .0 MAY be omitted.
Examples
  • 1.2 is equivalent to 1.2.0.0
  • 1.2.3 is equivalent to 1.2.3.0
  • 1.2.3.4
  • 1.2.3.4-alpha
  • 1.2.3.4+linux
Release Comparators

Release comparators allow for the inclusion of some pre-releases.

  • A list of release comparators MUST be preceded by a hyphen -.

  • Each release comparator MUST be denoted by a non-empty, dot-separated, textual identifier comprising only alphanumerics and hyphen [0-9A-Za-z-].

  • A release comparator MUST be satisfied by a version whose release metadata:

    • is absent, or
    • contains a textual identifier equal to this comparator.
Examples
  • -alpha is satisfied by 1.2.3.4
  • -alpha is satisfied by 1.2.3.4+linux
  • -alpha is satisfied by 1.2.3.4-alpha.foo
  • -alpha is not satisfied by 1.2.3.4-beta
  • -beta.foo is not satisfied by 1.2.3.4-beta
  • -beta.foo is satisfied by 1.2.3.4-beta.foo
Build Comparators

Build comparators favor some releases over others, depending on their build metadata.

  • A list of build comparators MUST be preceded by a plus sign +.

  • Each build comparator MUST be denoted by a non-empty, dot-separated, textual identifier comprising only alphanumerics and hyphen [0-9A-Za-z-].

  • A release comparator is always satisfied by any version but it SHALL influence the nomination if and only if there are several versions with the greatest precedence:

    • The version whose release metadata contains more textual identifiers equal to these comparators MUST be nominated.

Appendix

Backus-Naur Form Grammars

Grammars
  • Backus-Naur Form Grammar for Versions
    <Version> ::= <Core>
                | <Core> "-" <Release>
                | <Core>               "+" <Build>
                | <Core> "-" <Release> "+" <Build>
    
    <Core> ::= <Grade> "." <Major> "." <Minor> "." <Patch>
    
    <Grade> ::= <Number>
    <Major> ::= <Number>
    <Minor> ::= <Number>
    <Patch> ::= <Number>
    
    <Number> ::= <Digit>
               | <Positive Digit> <Digits>
    
    <Digits> ::= <Digit>
               | <Digit> <Digits>
    <Digit> ::= "0" | <Positive Digit>
    <Positive Digit> ::= "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
    
    <Release> ::= <Metadata>
    <Build>   ::= <Metadata>
    
    <Metadata> ::= <Name>
                 | <Number>
                 | <Name>   "." <Metadata>
                 | <Number> "." <Metadata>
    
    <Name> ::= <Alphanumeric>
             | <Alphanumeric> <Name>
    
    <Alphanumeric> ::= "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"
                     | "-"
                     | <Digit>
    
  • Backus-Naur Form Grammar for Subscriptions
    <Subscription> ::= ""
                     | <Selectors>
    
    <Selectors> ::= <Selector>
                  | <Selector> "||" <Selectors>
    
    <Selector> ::= <Core Comparators>
                 | <Core Comparators> <Release Comparators>
                 | <Core Comparators> <Release Comparators> <Build Comparators>
                 | <Core Comparators>                       <Build Comparators>
                 |                    <Release Comparators>
                 |                    <Release Comparators> <Build Comparators>
                 |                                          <Build Comparators>
    
    <Core Comparators> ::= <Comparator>
                         | <Comparator> "&&" <Core Comparators>
                         | <Comparator>      <Core Comparators>
    
    <Comparator> ::= <Operator> <Shorthand>
                   |            <Shorthand>
                   |            <Shorthand> "-" <Shorthand>
    
    <Operator> ::= "==" | "!=" | ">" | ">=" | "<" | "<=" | "~" | "^"
    
    <Shorthand> ::= <Grade>
                  | <Grade> "." <Major>
                  | <Grade> "." <Major> "." <Minor>
                  | <Grade> "." <Major> "." <Minor> "." <Patch>
    
    <Release Comparators> ::= "-" <Names>
    <Build Comparators>   ::= "+" <Names>
    
    <Names> ::= <Name>
              | <Name> "." <Names>
    

Railroad Diagrams

Diagrams
  • Version Diagram

  • Core Diagram

  • Metadata Diagram

  • Number Diagram

  • Name Diagram

  • Subscription Diagram

  • Shorthand Version Diagram

  • Operator Diagram

Perl-Compatible Regular Expressions

Regular Expressions
  • PCRE for Versions
    (?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-])+)*))?
    
  • PCRE for Subscription:
    \s*(?![\s&])(?P<selector>[\s\!\&\+\-\.0-9\<\=\>A-Z\^a-z\~]+(?<![&\s]))\s*(?:$|(?:\|\|\s*(?!$)))
    
  • PCRE for Selector:
    ^\s*(?P<core>(?:\s*(?:&&)?\s*(?:(?:(?:\d+(?:\.\d+(?:\.\d+(?:\.\d+)?)?)?)\s*\-\s*(?:\d+(?:\.\d+(?:\.\d+(?:\.\d+)?)?)?))|(?:(?:==|=|!=|>|>=|<|<=|^|~)?\s*(?:\d+(?:\.\d+(?:\.\d+(?:\.\d+)?)?)?))))*)\s*(?:\-\s*(?![\s\.])(?P<release>[\s\-\.0-9A-Za-z]*(?<![\s\.])))?\s*(?:\+\s*(?![\s\.])(?P<build>[\s\-\.0-9A-Za-z]*(?<![\s\.])))?\s*$
    
  • PCRE for Core Comparators
    (?:&&)?(?:(?:(?P<from>\d+(?:\.\d+(?:\.\d+(?:\.\d+)?)?)?)\s*\-\s*(?P<to>\d+(?:\.\d+(?:\.\d+(?:\.\d+)?)?)?))|(?:(?P<op>==|!=|>|>=|<|<=|^|~)?(?P<version>\d+(?:\.\d+(?:\.\d+(?:\.\d+)?)?)?)))
    
  • PCRE for Release/Build Comparators
    \s*(?<name>[\-\dA-Za-z]+)\s*(?:$|\.\s*(?=[^$\s\.]))
    

Decision Tree

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