zowe / zowe-cli

Zowe CLI
Eclipse Public License 2.0
113 stars 88 forks source link

Revise Versioning Scheme #77

Closed ChrisBoehmCA closed 5 years ago

ChrisBoehmCA commented 5 years ago

This would probably require us to manually bump the version before merging pull requests into master, but would make versions easier to identify and understand by the community. This would require some work on our CICD to avoid adding the -next<date> part of the tag

JTonda commented 5 years ago

Relevant Personas: Michelle, Ravi, Emily, Nick

Canonical

As an end user I want access to leading-edge features, but want to avoid crash-and-burn failures on each new snapshot.

As a plugin developer I need time to integrate with Zowe-CLI and Imperative before the products are made widely available.

Tasks

gejohnston commented 5 years ago

This comment is a change log for updates to the proposal for this issue. The actual proposal is contained in the next comment below.

Items concluded during Nov 15 review

Items concluded during Nov 30 review

Items added after Nov 30 review to address logistics

gejohnston commented 5 years ago

Version Numbering and Release Scheme for Zowe-CLI and Imperative

The current Zowe/Imperative versioning scheme was an attempt at semantic versioning. However, as implemented, our use of a pre-release string to create a differentiating version number complicates the specification of a Zowe dependency with the proper semantic version number string. Equally important, we have no stage between our ever-changing pre-release snapshots and our rarely-changing long-term snapshots. This document proposes changes to our versioning scheme to address such shortcomings.

The existing versioning document, MaintainerVersioning, will be modified with the conclusions resulting from the review of this document.

The main change to our existing release scheme is to create a third release category. Our version numbers themselves would not change. We will simply provide an early access snapshot that does not have pre-release strings in their version numbers.

Below, we layout a restructured release scheme. Then we will articulate how we expect that new scheme to resolve various shortcomings with the current scheme.

Beta Release Early Access Release Long Term Support Releases
Purpose Used to test features before being exposed to the full user community. Provides early access to new features. New releases will be introduced frequently. Provides products that remain stable. One product version only receives non-breaking changes and one version only receives bug fixes.
Target audience Plugin developers can verify any breakage that was introduced in this release before this version is advertized to the full user community. Select end-users can validate bug fixes or new features of interest to that user before full release. Customers who want to augment their applications with the latest Zowe capabilities. Customers who want to use the product in a production environment and want to minimize changes and breakage.
NPM tags in current release scheme next Does not exist latest
NPM tags in new release scheme daily - Each merge to master is automatically published. We assign the daily tag to prevent NPM from automatically moving its latest tag to this release.
beta - We assign this tag when a feature set is ready for integration testing and/or validation. We intend to do this at the end of every sprint and keep that release as beta until the end of the next sprint.
latest - This provides early access to validated functionality. Since this is the NPM default tag, customers will most likely retrieve this release, which is what we want. LTS-incremental - When a new release is first promoted to LTS, it is tagged as incremental. It receives non-breaking features and bug fixes.
LTS-stable - When a new release is tagged as LTS-incremental, the previous LTS-incremental is tagged as LTS-stable. We typically fix bugs on the LTS-stable release for one more year.
Version numbering
See example after table.
major.minor.patch-timestamp
Each merge to master is published and tagged as daily, until we decide that we are ready to tag a version as beta.
Same version number as most recent beta version minus the timestamp Same version number as most recent latest version.
Git Branch name master - a single static branch name. latest - a single branch name. Branches named incremental and stable.
Release Creation The 3 digits of the version number are manually changed within a development branch. When a development branch is merged to master, we update the timestamp, and publish the release with the NPM daily tag. When a such a release is targeted for beta, we create a Git beta tag and publish with the NPM beta tag. When a beta release has been validated we use a combination of Git merge, delete, rename, and/or create operations to copy source from the beta tag within master into the latest branch. Then, we must remove the timestamp from the version number, build the release, and publish the release. No updates are typically made in latest until the next beta tag from master is copied into latest. When desired, we use a combination of Git merge, delete, rename, and/or create operations to eliminate the old stable branch, move the old incremental branch to stable, and copy the source from the latest branch into the incremental branch. There is no need to initially change the version number, build, or publish the release. Instead, we point the NPM tag LTS-stable to LTS-incremental, and then point LTS-incremental to latest. For a temporary time, latest and LTS-incremental may point to the same version. When a fix is made, we increase the patch version number, rebuild the release, and publish the release.
Frequency of release Every time a story is merged into master, we publish a daily release. Typically once a sprint, we publish a beta release. Typically, every sprint we publish a latest release. We anticipate a new LTS release at most once per year. We fix bugs on an LTS release for 1 year after the introduction of a newer LTS release. With each new LTS release, we announce that bug fixing on the previous LTS release will end in 1 year.
Patching Typically fixes for Git issues are made within a separate fix branch. In that case, we increment only the patch number. Fixes needed to implement a feature branch can be made within that feature branch. In that case, we would only increment the minor number and leave the patch at zero. Our pipeline automatically updates the timestamp, so uniqueness is always guaranteed. The third digit should typically not be changed within this branch. We should only patch due to a catastrophic error. Reported bugs should typically be made in the beta release, since that will be moved to latest soon enough. Patches are created as needed to fix customer problems.

Example time-line to show how this versioning process will work

The version numbering below is not an exact sequence, it just represents possible sequences.

These versions occurred before this proposed scheme was used. The newest patches would have been labeled LTS-stable in the past.

- 1.0.0
    - 1.0.1
    - 1.0.2
    - ...
    - 1.0.10

A breaking change is a trigger for a new LTS release. Thereafter, the newest non-breaking enhancement or bug fix would have been tagged with LTS-incremental.

- 2.0.0
    - 2.0.1
- 2.1.0
    - 2.1.1
    - 2.1.2
    - 2.1.3
- 2.2.0
    - 2.2.1
    - 2.2.2
    - 2.2.3
    - 2.2.4

Product Management (and the passing of another calendar year) determined that 1.0 should be decommissioned. Version 2.3.0 became LTS-incremental. Version 2.2.2 could have been tagged as LTS-stable. Thereafter, the LTS-stable tag would have moved forward with the newest 2.2.x patch above, and the LTS-incremental tag would have moved forward with the newest 2.x.x version below.

- 2.3.0
    - 2.3.1
    - 2.3.2
- 2.4.0
- 2.5.0

Assume that this is our current point in time. Assume that 2.x has been decommissioned, and the 3.2.0 release is tagged as LTS-stable. Only patches (3.2.x) will be delivered for this LTS release. The LTS-stable tag will move to each such new patch release.

- 3.0.0
    - 3.0.1
    - 3.02
- 3.1.0
    - 3.1.1
    - 3.1.2
- 3.2.0      @LTS-stable

When 4.0.0 was delivered, it was tagged as LTS-incremental. Thereafter, each new non-breaking enhancement or bug fix was tagged as LTS-incremental. At this point in time, the 4.1.3 version is tagged as LTS-incremental. Additional non-breaking enhancements and bug fixes may be introduced in the future, and LTS-incremental will move to that new version.

- 4.0.0
    - 4.0.1
- 4.1.0
    - 4.1.1
    - 4.1.2
    - 4.1.3   @LTS-incremental

New development is also in progress on a 5.x feature-set which includes breaking changes. With each merge to our master branch, a new version with a pre-release string is published. It will be tagged as @daily to prevent NPM from automatically moving the latest tag to this new version. At the end of each sprint, the newest pre-release version produced in that sprint is tagged as @beta. To provide an opportunity for validation of that new beta release, we wait for one sprint (2 weeks). At the end of each sprint, we republish the previous beta release with no pre-release string (5.6.0 in the example below) and label that release as @latest. We then move the @beta label to the newest pre-release produced in the just-completed sprint.

- 5.0.0
    - Numerous pre-releases
- 5.1.0
    - Numerous pre-releases
    - 5.1.1
- 5.2.0
    - Numerous pre-releases
- 5.3.0
    - Numerous pre-releases
- 5.4.0
    - Numerous pre-releases
- 5.5.0                         @latest - Was assigned at the end of sprint N.
- 5.6.0-FirstDateInSprintN
- 5.6.0-SecondDateInSprintN
- 5.6.0-DateAtEndOfSprintN      @beta - Was assigned at end of sprint N.
- 5.7.0-FirstDateInSprintN+1
- 5.7.0-SecondDateInSprintN+1
- 5.7.0-DateAtEndOfSprintN+1    Now move @beta to 5.7.0-DateAtEndOfSprintN+1
- 5.6.0                         Version 5.6.0 is published at the end of sprint N+1
                                Now move @latest to 5.6.0

How the proposed scheme will correct issues

  1. Currently, for plugin writers to target our next release (which uses a pre-release string), they must specify the exact versions of @brightside/core and @brightside/imperative pre-release strings. Because the pre-release string changes by date, the plugin often specifies our long-term version number or an overly vague string that matches every future release. One choice results in a version mismatch warning which must be ignored. The other choice provides no real guard against pairing a plugin with an incompatible version of Zowe.

    Resolution: Plugin writers can target a future Zowe release with version numbers from the latest release. Since those versions do not contain pre-release strings, plugin writers can use meaningful version-matching strings (like ~2.1.3). Such a plugin version string will not have to change with each snapshot. Further, it would not necessarily change when Zowe and the plugin becomes long-term releases. This should avoid the warnings and confusion that occurs, when plugin developers do not constantly update their dependencies' version strings.

  2. Our current versioning scheme restricts our customers' choices to either a long-term unchanging release or an non-validated pre-release, which could change daily.

    Resolution: Once a latest snapshot exists, we should point most users to that location for the newest software. We would only point consumers to the beta version to validate that a new feature (for which the consumer was waiting) solved the intended problem, or to confirm a bug fix.

  3. Our current practice of using a pre-release for all early access releases, obscures the line between a relatively stable early access version and a beta build that may be introducing unstable behavior. Currently, a customer who wants to try some new feature (which might be a year away from being a included in a supported version) obtains the '@next' version of Zowe. (S)he gets the most recent software merged to master. The desired feature may be relatively stable from several versions back, but the customer will get additional, non-validated features and fixes. Although our automated tests have been run, no consumer has had an opportunity to validate the very latest changes.

    Resolution: The new latest category will be the primary location from which customers obtain leading-edge product. The newest version in that category may contain more new features than the one which is desired by the customer, but all features will be validated as stable.

  4. Pointing customers to a beta release involves a verbose version number like 2.3.0-next.201810182147. It is unique and correct, but it is somewhat complicated to communicate.

    Resolution: Most customers will use the latest version which will have a version number like 2.3.0. Only a customer who must validate a specific new feature or fix will have to use the more complicated version number.

  5. Long-standing CA (now Broadcom) Support practices expect the major number of supported releases to occur in sequential order (1.x.x, 2.x.x, 3.x.x, 4.x.x). However, semantic versioning requires the major number to increase for each new breaking change introduced into the release. This could result in a sequence like 1.x.x, 3.x.x, 7.x.x. This is an obvious conflict.

    Resolution: The semantic versioning of Zowe-CLI, Imperative, and any Zowe plugin are under the control of the Open Mainframe Project. Thus, Broadcom corporate versioning rules do not directly apply to them. Also, Broadcom product offerings will be bundles of Zowe and Broadcom components. Each component will have a different version number. The version of such a Broadcom product is a version number assigned to the bundle. That bundle version can adhere to Broadcom versioning guidelines, while the underlying components can follow semantic versioning. It is advisable to create a list of component versions that comprise a Broadcom product bundle version.

ChrisBoehmCA commented 5 years ago

I guess this issue is resolved now that we have moved to the new versioning scheme, right?

MikeBauerCA commented 5 years ago

Thanks @ChrisBoehmCA. Closing.