Skip to main content

Notice: this Wiki will be going read only early in 2024 and edits will no longer be possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.

Jump to: navigation, search

Difference between revisions of "Version Numbering"

m
m
Line 1: Line 1:
These guidelines are based on the Eclipse 3.2 [http://www.eclipse.org/equinox/documents/plugin-versioning.html plugin versioning proposal].  These guidelines have been [[Version_Numbering_Europa_Update | revised]] for the [[Europa Simultaneous Release]].
+
These guidelines are based on the Eclipse 3.2 [http://www.eclipse.org/equinox/documents/plugin-versioning.html plug-in versioning proposal].  These guidelines have been [[Version_Numbering_Europa_Update | revised]] for the [[Europa Simultaneous Release]].
  
<h3>Guidelines on versioning plug-ins</h3>
+
== Guidelines on versioning plug-ins ==
 
This document contains a set of guidelines expressing how to evolve plug-in version numbers in a way that captures the nature
 
This document contains a set of guidelines expressing how to evolve plug-in version numbers in a way that captures the nature
 
of the changes that have been made.
 
of the changes that have been made.
Line 13: Line 13:
 
* the qualifier segment indicates a particular build
 
* the qualifier segment indicates a particular build
 
 
<h4>When to change the major segment</h4>
+
=== When to change the major segment ===
 
<p>The major segment number should be increased when a plug-in changes in a non binary compatible way. When the major segment is changed the minor and service segments are reset to 0.
 
<p>The major segment number should be increased when a plug-in changes in a non binary compatible way. When the major segment is changed the minor and service segments are reset to 0.
  
Line 19: Line 19:
 
By definition, such changes should not be made when working in a maintenance stream.
 
By definition, such changes should not be made when working in a maintenance stream.
  
<h4>When to change the minor segment</h4>
+
=== When to change the minor segment ===
 
The minor segment number should be incremented when a plug-in changes in an "externally visible" way. Examples of externally visible changes include binary compatible API changes, significant performance changes, major code rework, etc. Another way to know when this version number should be changed is by exclusion: it should indicate changes that are neither bug fixes (indicated by the service segment) nor breaking API changes (indicated by the major segment). When the minor segment is changed, the service segment is reset to 0.
 
The minor segment number should be incremented when a plug-in changes in an "externally visible" way. Examples of externally visible changes include binary compatible API changes, significant performance changes, major code rework, etc. Another way to know when this version number should be changed is by exclusion: it should indicate changes that are neither bug fixes (indicated by the service segment) nor breaking API changes (indicated by the major segment). When the minor segment is changed, the service segment is reset to 0.
  
Line 26: Line 26:
 
<span id="minor_segment_in_maintenance">The minor segment is not typically changed when working in a maintenance stream. If API changes are required in a maintenance stream, be sure to make this fact well known to your community.  Plug-ins in downstream projects that have expressed a tight bound on the version of your plug-in may no longer be resolvable at runtime, so they must have a chance to update their required version range accordingly. Also, when the minor segment is incremented in a maintenance stream, you must increment the minor segment again in the next stream.  For example, if plug-in P has version 2.2.7 in the 1.0 product release, it would increment to 2.3.0 in the 1.0.1 product release, and 2.4.0 in the 1.1 product release.  Incrementing the minor segment in a maintenance release after there has been a release in a future stream cannot be done unless you have left a gap in your version numbers to leave room for it.</span>
 
<span id="minor_segment_in_maintenance">The minor segment is not typically changed when working in a maintenance stream. If API changes are required in a maintenance stream, be sure to make this fact well known to your community.  Plug-ins in downstream projects that have expressed a tight bound on the version of your plug-in may no longer be resolvable at runtime, so they must have a chance to update their required version range accordingly. Also, when the minor segment is incremented in a maintenance stream, you must increment the minor segment again in the next stream.  For example, if plug-in P has version 2.2.7 in the 1.0 product release, it would increment to 2.3.0 in the 1.0.1 product release, and 2.4.0 in the 1.1 product release.  Incrementing the minor segment in a maintenance release after there has been a release in a future stream cannot be done unless you have left a gap in your version numbers to leave room for it.</span>
  
<h4>When to change the service segment</h4>
+
=== When to change the service segment ===
 
The service segment number must be incremented whenever there have been changes to a plug-in between releases that are not visible in its API. For example, a bug has been fixed in the code, the plug-in manifest has changed, documentation has changed, compiler settings have changed, etc. In addition, incrementing the version number by one hundred (100) indicates a change of development stream. This increment must be done when the first change is made in a new development stream. This practice makes it easy to manage one line of descent after a release and still guarantee that plug-ins coming in the next release will have a higher version number than ones from maintenance releases (thus enabling the usage of update manager from maintenance releases to the new releases).
 
The service segment number must be incremented whenever there have been changes to a plug-in between releases that are not visible in its API. For example, a bug has been fixed in the code, the plug-in manifest has changed, documentation has changed, compiler settings have changed, etc. In addition, incrementing the version number by one hundred (100) indicates a change of development stream. This increment must be done when the first change is made in a new development stream. This practice makes it easy to manage one line of descent after a release and still guarantee that plug-ins coming in the next release will have a higher version number than ones from maintenance releases (thus enabling the usage of update manager from maintenance releases to the new releases).
  
Line 33: Line 33:
 
<span id="multiple_maintenance_branches"/>Note that extra care must be taken when a plug-in is involved in multiple active maintenance streams.  In this case you must increment the service segment by 100 for each active maintenance branch.  Say plug-in P version 1.0.0 exists in version 1.0, 1.5, and 2.0 of some "Internet utensils" project.  The owner of plug-in P wants to fix a bug in versions 1.0.1, 1.5.1, and 2.0.1 of the "Internet utensils" project. To ensure separate lines of descent in each maintenance stream, the version of plug-in P must be incremented to 1.0.1 in the 1.0.1 release, 1.0.100 in the 1.5.1 release, and 1.0.200 in the 2.0 release. In other words, the service segment must increment by a hundred for each new line of descent.</span>
 
<span id="multiple_maintenance_branches"/>Note that extra care must be taken when a plug-in is involved in multiple active maintenance streams.  In this case you must increment the service segment by 100 for each active maintenance branch.  Say plug-in P version 1.0.0 exists in version 1.0, 1.5, and 2.0 of some "Internet utensils" project.  The owner of plug-in P wants to fix a bug in versions 1.0.1, 1.5.1, and 2.0.1 of the "Internet utensils" project. To ensure separate lines of descent in each maintenance stream, the version of plug-in P must be incremented to 1.0.1 in the 1.0.1 release, 1.0.100 in the 1.5.1 release, and 1.0.200 in the 2.0 release. In other words, the service segment must increment by a hundred for each new line of descent.</span>
  
<h4>Overall example</h4>
+
=== Overall example ===
 
This example shows how the version of a plug-in reacts to changes (indicated in parenthesis) in the context of different development stream. Both the text and the diagram illustrate the same example.
 
This example shows how the version of a plug-in reacts to changes (indicated in parenthesis) in the context of different development stream. Both the text and the diagram illustrate the same example.
  
Line 57: Line 57:
 
[[Image:Plugin-versioning-fig1.jpg]]
 
[[Image:Plugin-versioning-fig1.jpg]]
  
<h4> When to change the qualifier segment</h4>
+
===  When to change the qualifier segment ===
 
Because changing the version number of a plug-in on every commit can be burdensome to the development team, we recommend only applying the previous guidelines once per release cycle. However, since we want to enable the use of the update manager by the development teams, we will use the qualifier segment to indicate changes between builds.
 
Because changing the version number of a plug-in on every commit can be burdensome to the development team, we recommend only applying the previous guidelines once per release cycle. However, since we want to enable the use of the update manager by the development teams, we will use the qualifier segment to indicate changes between builds.
  
Line 67: Line 67:
 
Deriving the qualifier from the build input offers the advantage that if the plug-in code has not changed, no new version will be created and therefore update manager won't download the plug-in again.
 
Deriving the qualifier from the build input offers the advantage that if the plug-in code has not changed, no new version will be created and therefore update manager won't download the plug-in again.
  
<h3>How to specify plug-in requirements</h3>
+
== How to specify plug-in requirements ==
 
Plug-ins that require other plug-ins must qualify their requirements with a version range since the absence of a version range means that any version can satisfy the dependency. Given that all the changes between the version x.0.0 and the version x+1.0.0 excluded must be compatible (given the previous guidelines); the recommended range includes the minimal required version up-to but not including the next major release.
 
Plug-ins that require other plug-ins must qualify their requirements with a version range since the absence of a version range means that any version can satisfy the dependency. Given that all the changes between the version x.0.0 and the version x+1.0.0 excluded must be compatible (given the previous guidelines); the recommended range includes the minimal required version up-to but not including the next major release.
  
Line 75: Line 75:
 
<b>Example</b>: A plug-in using basic functions from the job API, may express a dependency on runtime 3.0.0 ( [3.0.0, 4.0.0) ) instead of 3.1.0 ( [3.1.0, 4.0.0) ).
 
<b>Example</b>: A plug-in using basic functions from the job API, may express a dependency on runtime 3.0.0 ( [3.0.0, 4.0.0) ) instead of 3.1.0 ( [3.1.0, 4.0.0) ).
  
<h4>How to specify versions when plug-ins re-export other plug-ins</h4>
+
=== How to specify versions when plug-ins re-export other plug-ins ===
 
When a plug-in exports a range of versions for another plug-in, it is promising that some version in that range will be available. Specifically, it provides the guarantee that at least the version specified by the lower bound will be available. Therefore, whenever a plug-in changes the version range of an exported plug-in, it must change its own version number as follows:
 
When a plug-in exports a range of versions for another plug-in, it is promising that some version in that range will be available. Specifically, it provides the guarantee that at least the version specified by the lower bound will be available. Therefore, whenever a plug-in changes the version range of an exported plug-in, it must change its own version number as follows:
  
Line 93: Line 93:
 
Exporting a version range that spans multiple major versions of a plug-in is not recommended, because it forces downstream plug-ins to support versions with arbitrary breaking changes between them. Therefore, the most common change to a version range will be increasing the minor or service segment of one of the bounds, or incrementing both bounds up to a range within the next major version.
 
Exporting a version range that spans multiple major versions of a plug-in is not recommended, because it forces downstream plug-ins to support versions with arbitrary breaking changes between them. Therefore, the most common change to a version range will be increasing the minor or service segment of one of the bounds, or incrementing both bounds up to a range within the next major version.
  
<h4>How to version packages</h4>
+
=== How to version packages ===
 
Exported packages being used as service APIs must have a version number. The guidelines to evolve those version numbers are the same as for plug-ins. For plug-ins importing individual packages, you should follow the same guidelines as when requiring a plug-in to specify the version range of packages being imported.
 
Exported packages being used as service APIs must have a version number. The guidelines to evolve those version numbers are the same as for plug-ins. For plug-ins importing individual packages, you should follow the same guidelines as when requiring a plug-in to specify the version range of packages being imported.
  
<h4>Which version to use in javadoc tags</h4>
+
=== Which version to use in javadoc tags ===
 
In the javadoc, @since tags are used to indicate the version of a <b>plug-in</b> in which a specific API has been added. Because javadoc describes API, only the first two segment of the plug-in version number should be used. This represents a change from the previous practice where @since indicated the development stream. In addition to using the plug-in version, we recommend to prefix
 
In the javadoc, @since tags are used to indicate the version of a <b>plug-in</b> in which a specific API has been added. Because javadoc describes API, only the first two segment of the plug-in version number should be used. This represents a change from the previous practice where @since indicated the development stream. In addition to using the plug-in version, we recommend to prefix
 
the version number by the plug-in id. This allows tracking of APIs moving from one plug-in to another (this can happen when a plug-in is split into multiple plug-ins but the package names are kept).
 
the version number by the plug-in id. This allows tracking of APIs moving from one plug-in to another (this can happen when a plug-in is split into multiple plug-ins but the package names are kept).
Line 112: Line 112:
 
</pre>
 
</pre>
  
<h3>Versioning features</h3>
+
== Versioning features ==
Features are a grouping mechanism that supports reasoning in terms of sets of plug-ins. Therefore, features hide the plug-in boundaries of the plug-ins they contain and act as if their API was the set of all the APIs of all the consituting plug-ins. Because of this, features are akin to plug-ins re-exporting other plug-ins and should follow the same versioning guidelines.
+
Features are a grouping mechanism that supports reasoning in terms of sets of plug-ins. Therefore, features hide the plug-in boundaries of the plug-ins they contain and act as if their API was the set of all the APIs of all the constituting plug-ins. Because of this, features are akin to plug-ins re-exporting other plug-ins and should follow the same versioning guidelines.
  
 
To avoid the brittleness caused by version changes in required features, we recommend feature authors favor the expression of their dependencies at the plug-in level, rather than at the feature level. To be more precise, all the immediate plug-ins required by the plug-ins included in a feature should be listed as plug-in prerequisite of the feature. This approach has the benefit of isolating feature authors from changes that do not impact them.
 
To avoid the brittleness caused by version changes in required features, we recommend feature authors favor the expression of their dependencies at the plug-in level, rather than at the feature level. To be more precise, all the immediate plug-ins required by the plug-ins included in a feature should be listed as plug-in prerequisite of the feature. This approach has the benefit of isolating feature authors from changes that do not impact them.

Revision as of 15:56, 3 November 2006

These guidelines are based on the Eclipse 3.2 plug-in versioning proposal. These guidelines have been revised for the Europa Simultaneous Release.

Guidelines on versioning plug-ins

This document contains a set of guidelines expressing how to evolve plug-in version numbers in a way that captures the nature of the changes that have been made.

Reminder: In Eclipse, version numbers are composed of four (4) segments: 3 integers and a string respectively named major.minor.service.qualifier.

Each segment captures a different intent:

  • the major segment indicates breakage in the API
  • the minor segment indicates "externally visible" changes
  • the service segment indicates bug fixes and the change of development stream (the semantics attached to development stream is new to this proposal, see below)
  • the qualifier segment indicates a particular build

When to change the major segment

The major segment number should be increased when a plug-in changes in a non binary compatible way. When the major segment is changed the minor and service segments are reset to 0. Example: From the version 2.2.7, an incompatible change would lead to 3.0.0. By definition, such changes should not be made when working in a maintenance stream.

When to change the minor segment

The minor segment number should be incremented when a plug-in changes in an "externally visible" way. Examples of externally visible changes include binary compatible API changes, significant performance changes, major code rework, etc. Another way to know when this version number should be changed is by exclusion: it should indicate changes that are neither bug fixes (indicated by the service segment) nor breaking API changes (indicated by the major segment). When the minor segment is changed, the service segment is reset to 0.

Example: From the version 2.2.7, a minor change would lead to 2.3.0.

The minor segment is not typically changed when working in a maintenance stream. If API changes are required in a maintenance stream, be sure to make this fact well known to your community. Plug-ins in downstream projects that have expressed a tight bound on the version of your plug-in may no longer be resolvable at runtime, so they must have a chance to update their required version range accordingly. Also, when the minor segment is incremented in a maintenance stream, you must increment the minor segment again in the next stream. For example, if plug-in P has version 2.2.7 in the 1.0 product release, it would increment to 2.3.0 in the 1.0.1 product release, and 2.4.0 in the 1.1 product release. Incrementing the minor segment in a maintenance release after there has been a release in a future stream cannot be done unless you have left a gap in your version numbers to leave room for it.

When to change the service segment

The service segment number must be incremented whenever there have been changes to a plug-in between releases that are not visible in its API. For example, a bug has been fixed in the code, the plug-in manifest has changed, documentation has changed, compiler settings have changed, etc. In addition, incrementing the version number by one hundred (100) indicates a change of development stream. This increment must be done when the first change is made in a new development stream. This practice makes it easy to manage one line of descent after a release and still guarantee that plug-ins coming in the next release will have a higher version number than ones from maintenance releases (thus enabling the usage of update manager from maintenance releases to the new releases).

Example: At the end of the development stream N, the version of the plug-in P is 2.4.8. When P makes its first change in the development stream N+1, then the version should be changed to 2.4.108. If P version 2.4.8 needs to receive a bug fix in the maintenance stream started from N, then its version number will be 2.4.9.

<span id="multiple_maintenance_branches"/>Note that extra care must be taken when a plug-in is involved in multiple active maintenance streams. In this case you must increment the service segment by 100 for each active maintenance branch. Say plug-in P version 1.0.0 exists in version 1.0, 1.5, and 2.0 of some "Internet utensils" project. The owner of plug-in P wants to fix a bug in versions 1.0.1, 1.5.1, and 2.0.1 of the "Internet utensils" project. To ensure separate lines of descent in each maintenance stream, the version of plug-in P must be incremented to 1.0.1 in the 1.0.1 release, 1.0.100 in the 1.5.1 release, and 1.0.200 in the 2.0 release. In other words, the service segment must increment by a hundred for each new line of descent.</span>

Overall example

This example shows how the version of a plug-in reacts to changes (indicated in parenthesis) in the context of different development stream. Both the text and the diagram illustrate the same example.

First development stream
 - 1.0.0

Second development stream
 - 1.0.100 (indicates a bug fix)
 - 1.1.0 (a new API has been introduced)
 The plug-in ships as 1.1.0

Third development stream
 - 1.1.100 (indicates a bug fix)
 - 2.0.0 (indicates a breaking change)
 The plug-in ships as 2.0.0

Maintenance stream after 1.1.0
 - 1.1.1
 The plug-in ships as 1.1.1

Plugin-versioning-fig1.jpg

When to change the qualifier segment

Because changing the version number of a plug-in on every commit can be burdensome to the development team, we recommend only applying the previous guidelines once per release cycle. However, since we want to enable the use of the update manager by the development teams, we will use the qualifier segment to indicate changes between builds.

Since Eclipse 3.1, PDE Build can automatically derive the value of the qualifier from the tag associated with the plug-in in the map file that has been fed as input to the build. This leaves the responsibility to the developer preparing the input for the build to tag their plug-ins with a value that is lexicographically higher than the previous one. To facilitate this, we recommend using the date formatted as vYYYYMMDD (year, month day). If you have multiple builds in a day, you can add "-HHMM" (hour, minute) to ensure it is unique.

It is also recommended that you prefix the tag on a maintenance branch with a unique branch identifier to ensure that builds on that branch can be distinguished from builds on the main development branch. For example, a branch for maintenance of the 1.0 release can use a prefix of "R10x_" so that all builds on that branch for the 1.0.x maintenance releases are grouped together.

Example: The map file for the plug-in P indicates v20050506, and P's version is 4.2.3. The resulting fully qualified version number would be 4.2.3.v20050506. Deriving the qualifier from the build input offers the advantage that if the plug-in code has not changed, no new version will be created and therefore update manager won't download the plug-in again.

How to specify plug-in requirements

Plug-ins that require other plug-ins must qualify their requirements with a version range since the absence of a version range means that any version can satisfy the dependency. Given that all the changes between the version x.0.0 and the version x+1.0.0 excluded must be compatible (given the previous guidelines); the recommended range includes the minimal required version up-to but not including the next major release.

Example: JFace 3.1.0 should probably express the following requirement on SWT: [3.1.0, 4.0.0).

Also, while setting values for prerequisites, watch for opportunities to widen the set of plug-ins against which a plug-in can work. Example: A plug-in using basic functions from the job API, may express a dependency on runtime 3.0.0 ( [3.0.0, 4.0.0) ) instead of 3.1.0 ( [3.1.0, 4.0.0) ).

How to specify versions when plug-ins re-export other plug-ins

When a plug-in exports a range of versions for another plug-in, it is promising that some version in that range will be available. Specifically, it provides the guarantee that at least the version specified by the lower bound will be available. Therefore, whenever a plug-in changes the version range of an exported plug-in, it must change its own version number as follows:

  • Any change to upper bound: increase service segment
  • Decrease service segment of lower bound: increase service segment
  • Decrease major or minor segment of lower bound: increase major segment
  • Increase lower bound: increase version by the same magnitude

Example: JFace 8.4.2 re-exports SWT [1.1.1,2.0)

  • If the next version of JFace re-exports SWT [1.1.1,1.5), JFace version must increase to at least 8.4.3.
  • If the next version of JFace re-exports SWT [1.1,2.0), JFace version must increase to at least 8.4.3.
  • If the next version of JFace re-exports SWT [1.0,2.0), JFace version must increase to at least 9.0.0.
  • If the next version of JFace re-exports SWT [1.1.2,2.0), JFace version must increase to at least 8.4.3.
  • If the next version of JFace re-exports SWT [1.2,2.0), JFace version must increase to at least 8.5.0.
  • If the next version of JFace re-exports SWT [2.0,3.0), JFace version must increase to 9.0.0

Exporting a version range that spans multiple major versions of a plug-in is not recommended, because it forces downstream plug-ins to support versions with arbitrary breaking changes between them. Therefore, the most common change to a version range will be increasing the minor or service segment of one of the bounds, or incrementing both bounds up to a range within the next major version.

How to version packages

Exported packages being used as service APIs must have a version number. The guidelines to evolve those version numbers are the same as for plug-ins. For plug-ins importing individual packages, you should follow the same guidelines as when requiring a plug-in to specify the version range of packages being imported.

Which version to use in javadoc tags

In the javadoc, @since tags are used to indicate the version of a plug-in in which a specific API has been added. Because javadoc describes API, only the first two segment of the plug-in version number should be used. This represents a change from the previous practice where @since indicated the development stream. In addition to using the plug-in version, we recommend to prefix the version number by the plug-in id. This allows tracking of APIs moving from one plug-in to another (this can happen when a plug-in is split into multiple plug-ins but the package names are kept). Example: In the 3.2 development stream, the API of the new plug-in org.eclipse.core.filesystem should be tagged as follows:

/**
 * This class is the main entry point for clients of the Eclipse file system API.  This
 * class has factory methods for obtaining instances of file systems and file
 * stores, and provides constants for option values and error codes.
 * 
 * This class is not intended to be instantiated or subclassed.
 * 
 * @since org.eclipse.core.filesytem 1.0
 */

Versioning features

Features are a grouping mechanism that supports reasoning in terms of sets of plug-ins. Therefore, features hide the plug-in boundaries of the plug-ins they contain and act as if their API was the set of all the APIs of all the constituting plug-ins. Because of this, features are akin to plug-ins re-exporting other plug-ins and should follow the same versioning guidelines.

To avoid the brittleness caused by version changes in required features, we recommend feature authors favor the expression of their dependencies at the plug-in level, rather than at the feature level. To be more precise, all the immediate plug-ins required by the plug-ins included in a feature should be listed as plug-in prerequisite of the feature. This approach has the benefit of isolating feature authors from changes that do not impact them.

Example:

 Case 1: Today the feature org.eclipse.gef is as follows:
    requires feature org.eclipse.platform	3.1.0
    contains plugins:
      org.eclipse.draw2d	3.1.0
      org.eclipse.gef		3.1.0
 
 Case 2: In the new model it should be:
     contains plugins:
       org.eclipse.draw2d	3.1.0
       org.eclipse.gef		3.1.0  
     requires plugins:
       org.eclipse.core.runtime [3.1.0, 4.0.0)
       org.eclipse.ui.views     [3.1.0, 4.0.0)
       org.eclipse.ui.workbench [3.1.0, 4.0.0)
       org.eclipse.jface        [3.1.0, 4.0.0)
       org.eclipse.swt		[3.1.0, 4.0.0)

In case 1, if the version of the org.eclipse.platform feature changes to 4.0.0 (because org.eclipse.core.resources changes its major version number), org.eclipse.gef is required to deliver a new version of its features. In case 2, such changes are transparent to the author of GEF.

Eclipse Plugin Version Table

Back to the top