Product Name

Versioning & Breaking Changes

MDS uses SemVer semantic versioning. The three types of versions are:

  • Major (X.y.z)
    Major versions contain breaking changes (defined below).
  • Minor (x.Y.z)
    Minor versions add new features or deprecate existing features without breaking changes.
  • Patch (x.y.Z)
    Patch versions fix defects or optimize existing features without breaking changes.

Major

MDS uses major versions for breaking changes. Some breaking-change examples include:

Style

  • A change to style that triggers a layout change in an MDS user’s product, such as:
    • Changes to box model properties:
      • padding, margin, width, height, display, box-sizing, position, left/right/top/bottom
    • Changes to font attributes that cause text to wrap where it previously didn’t wrap
      • font-size, font-weight, line-height, letter-spacing
  • Deleting a shared mixin or placeholder.
  • Altering a hard-coded path to an asset. Examples include:
    @font-face {
      src: url('../fonts/0b8e0455ef09.eot');
    }
    
    Changing that hard-coded path to:
    @font-face {
      src: url('fonts/0b8e0455ef09.eot');
    }
    
    Is a breaking change. Similarly:
    .selector {
      background-image: src('/this/path/file.png’);
    }
    
    Changing that hard-coded path to:
    .selector {
      background-image: src('/that/path/file.png’);
    }
    
    Is a breaking change.

Non-Breaking Style Changes

Changes to box-model properties that affect the internal layout within a component may not be breaking changes. For example, this Menu change was deemed non-breaking because spacing adjustments occurred in a positioned element that doesn’t otherwise impact page layout.

Such changes are reviewed on a case-by-case basis. The MDS team may contact the broader engineering and design communities for additional input.

Markup

  • A markup change that requires MDS users to update markup to align with breaking style change(s).
  • Removing an html attribute or property (like an aria attribute) that destroys text-to-speech, keyboard navigation or other assistive functionality.

Non-Breaking Markup Changes

  • Adding an html attribute or property (like an aria attribute) that improves accessibility is not a breaking change. That is a new feature.
  • Changing an existing html attribute or property (like an aria attribute) that is incorrect is not a breaking change. That is fixing a defect.
  • Adding additional markup that MDS users are not required to include is not a breaking change. For example:
    <button>Text</button>
    
    Inserting an inner-wrapper
    <button><span>Text</span></button>
    
    This is not a breaking change, as long as the first example without the inner wrapper looks visually identical to previous versions of that same markup.

Scripts

  • Changes to the public API of those scripts, such as exposed event triggers or selector expectations. (Currently, 28 Aug 2017, MDS does not ship scripts).

Constants

  • A change of an existing constant key name or removal of a constant.
  • Changing a constant value that is used in styles as a box-model property value may be a breaking change. See the Style section above.
  • Changing a constant value used as a text or background color may be a breaking change if the color change causes color contrast issues in an MDS user’s product.

Icons

  • Removing an icon from MDS.
  • Altering an icon’s pictogram significantly while retaining the icon name. For example, an icon named “alert” changing from:

      to:  

  • Altering icon sizes could be a breaking change if it triggers a layout change in an MDS user’s product.

Non-Breaking Icon Changes

  • Changing an icon’s appearance slightly while preserving the icon’s name and overall size is not a breaking change.

Fonts

Changing to a different font-family may be a breaking change if the new font has drastically different size characteristics that would cause text wrapping to behave differently.

Minor

Minor versions are for non-breaking changes that add features. Some examples include:

  • Adding:
    • a new UI component to the library.
    • a new variation of an existing UI component. For example, adding error states to form fields.
    • attributes to markup that don’t affect the rendering of the markup. For example, adding aria attributes to improve accessibility.
    • new constants.
  • Updating the value of an existing constant when the new value doesn’t create a breaking change. See constants breaking changes above.
  • Deprecating an existing constant value or other feature. Note that this is not the removal of the feature; it’s marking it as deprecated.

Patch

Patch versions fix defects and optimize existing code. Some examples include:

  • Correcting the value of a markup attribute that was incorrect in a code snippet. For example:
    <label class="mds-form__label" for="">Email</label>
    <input id="email" class="mds-form__input"> 
    
    Corrected to:
    <label class="mds-form__label" for="email">Email</label>
    <input id="email" class="mds-form__input"> 
    
  • Altering use of a constant key within the System’s stylesheets:

      Constants.scss
      $mds-text-color-primary-default: #1e1e1e;
      $mds-color-neutral-12: #1e1e1e;
    
      Button.scss
      .mds-button {
          color: $mds-color-neutral-12;
      }
    

    Changed to:

      Button.scss
      .mds-button {
          color: $mds-text-color-primary-default;
      }
    

Incrementing Version Numbers

  • 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.
  • The minor version (Y in x.Y.z) must be incremented if:
    • new, backward-compatible functionality is introduced to the public API.
    • if any public API functionality is marked as deprecated.
  • The minor version may be incremented if substantial new functionality or improvements are introduced within the private code, such as internal refactoring of constant usage in MDS SCSS that doesn’t trigger any breaking changes. It may include patch level changes.
  • Patch version must be reset to 0 when minor version is incremented.

Assigning a Version Number

Version numbers are assigned prior to a release. To assign a version, the team will review the changes that have been made since the last version and assess those changes against the SemVer rules outlined above. It’s imperative that the team adhere to the rules based solely on the way the codebase has changed in order to assign the correct semantic version. The team should not consider the following when assigning a version:

  • How much time has passed since the last major/minor/patch release.
  • How many presumed users there are of any previous version, which can lead to discussions of “Is this really a breaking change if no one’s using it?” that are irrelevant in semantic versioning.
  • The perception or “marketing” value of a particular release number.
    • “Why are we at 2.0 already? I thought 1.0 just came out?”
    • If there’s a strong need for “marketing” labels for releases, then a separate version structure should be used publicly (cat names, locations in California, types of candy/sweets), even if the team will internally adhere to SemVer.

A frequently asked question from newcomers to SemVer is this:

If even the tiniest backward-incompatible changes to the public API require a major version bump, won’t I end up at version 42.0.0 very rapidly?*

*from SemVer.org’s FAQ

This is a question of responsible development and foresight. Incompatible changes should not be introduced lightly to software that has a lot of dependent code. The upgrade cost (incurred by users of MDS) can be significant. Having to bump major versions to release incompatible changes means you’ll think through the impact of your changes and evaluate the cost/benefit ratio involved.

Accidental Release of Breaking Changes

If a backward-incompatible change is released unintentionally, the MDS team will follow the process outlined on semver.org:

As soon as the team realizes that we’ve released a breaking change as part of a minor release, we will release a new minor version that corrects the problem and restores backward compatibility.

Even under this circumstance, we will not modify versioned releases (i.e. if we release a breaking change in 1.5, we will not simply overwrite version 1.5; we will release a new version 1.6 that fixes the breaking change).

We will document the offending version and inform MDS users of the problem. We will also remove download links to the breaking version and, if possible, remove the broken package from MSNexus NPM and Bower.

©2017 Morningstar, Inc. All rights reserved. Terms of Use