modelica / ModelicaSpecification

Specification of the Modelica Language
https://specification.modelica.org
Creative Commons Attribution Share Alike 4.0 International
97 stars 41 forks source link

MCP-0016: Semantic Versions for Libraries #1728

Open modelica-trac-importer opened 5 years ago

modelica-trac-importer commented 5 years ago

Modified by dietmarw on 2 Dec 2015 10:08 UTC We identified several potential “levels” of semantics. The first level was the idea that all libraries must use semantic versions syntax. This would have the basic benefit that it would address issues about how to express things like pre-release versions. It also provides a basis for defining ordering as well.

This MCP is about how to deal with semantics of version numbers. By this we mean conclusions that could be drawn about compatibility between different versions (e.g., something that uses 3.2.1 should be able to use 3.2.2). One of the topics that come up was the idea of bugs and bug fixes. It might be that API compatibility may be present, but that the actual implementations have issues.

Based on this, it was felt that the uses annotation was still useful because it allows a level of explicit dependencies. For this reason it was felt that library developers should be able to utilize semantic version compatibility but also to explicitly override it.

Document location

Current members of the working group


Modified by dietmarw on 18 Sep 2015 07:56 UTC We identified several potential “levels” of semantics. The first level was the idea that all libraries must use semantic versions syntax. This would have the basic benefit that it would address issues about how to express things like pre-release versions. It also provides a basis for defining ordering as well.

This MCP is about how to deal with semantics of version numbers. By this we mean conclusions that could be drawn about compatibility between different versions (e.g., something that uses 3.2.1 should be able to use 3.2.2). One of the topics that come up was the idea of bugs and bug fixes. It might be that API compatibility may be present, but that the actual implementations have issues.

Based on this, it was felt that the uses annotation was still useful because it allows a level of explicit dependencies. For this reason it was felt that library developers should be able to utilize semantic version compatibility but also to explicitly override it.

Document location

Current members of the working group


Reported by mtiller on 9 Jun 2015 14:35 UTC We identified several potential “levels” of semantics. The first level was the idea that all libraries must use semantic versions syntax. This would have the basic benefit that it would address issues about how to express things like pre-release versions. It also provides a basis for defining ordering as well.

This MCP is about how to deal with semantics of version numbers. By this we mean conclusions that could be drawn about compatibility between different versions (e.g., something that uses 3.2.1 should be able to use 3.2.2). One of the topics that come up was the idea of bugs and bug fixes. It might be that API compatibility may be present, but that the actual implementations have issues.

Based on this, it was felt that the uses annotation was still useful because it allows a level of explicit dependencies. For this reason it was felt that library developers should be able to utilize semantic version compatibility but also to explicitly override it.

Document location


Migrated-From: https://trac.modelica.org/Modelica/ticket/1728

modelica-trac-importer commented 5 years ago

Modified by dietmarw on 9 Jun 2015 14:51 UTC

modelica-trac-importer commented 5 years ago

Comment by mwetter on 10 Jun 2015 17:19 UTC As a library author, I am fully supportive of the semantic versioning (and started using it for Buildings).

As not all library developers may be aware of what a backward compatible change is, and because it may quickly happen that a non-backward compatible change gets on the development branch inadvertently, I think robustness of library versioning could be increased if developers had access to a script, or at the minimum a checklist, that can be used to verify whether a library is indeed backwards compatible.

A (likely still incomplete test) could be that

As I doubt that all library developers will use semantic versioning, a keyword would be useful that indicates that a library indeed uses semantic versioning. I suggest a library should opt-in to use semantic versioning.

modelica-trac-importer commented 5 years ago

Comment by hansolsson on 24 Jun 2015 08:32 UTC Replying to [comment:2 mwetter]:

As a library author, I am fully supportive of the semantic versioning (and started using it for Buildings).

As not all library developers may be aware of what a backward compatible change is, and because it may quickly happen that a non-backward compatible change gets on the development branch inadvertently, I think robustness of library versioning could be increased if developers had access to a script, or at the minimum a checklist, that can be used to verify whether a library is indeed backwards compatible.

I also tried to investigate how to best do this (i.e. planning to actually implement the feature), and then I got stuck since I realized that we haven't clearly defined what is allowed in various versions - and it is not even clear that it is possible (see below). (I tried to look through the documents for this MCP and couldn't find anything.)

A (likely still incomplete test) could be that

  • all classes are still present,
  • all public instances are still present,
  • all parameters still have either the same default value or the same start attribute set,
  • no new parameter is introduced that has neither a default value nor its start attribute set, and
  • no parameter is converted from non-final to final.

These restrictions on minor version are similar to "plug compatibility" (in section 6.4 of the specification) - which is basically to say that a user could redeclare a component of the old class with the new one.

(Additionally you require that the same value shall be used; that is problematic to check - and additionally I assume some want to allow minor tweaks of values.)

Similarly the restriction on patch-releases can be compared to the restriction in MSL for updates of the maintenance branch. (Alternatively that you can redeclare in either direction.)

However, the restrictions on the maintenance-branch in MSL are not 100% safe.

And with current Modelica I don't see how we can have 100% safe restrictions on non-major releases that allow current development. The changes in Modelica Specification to allow 100% safe realistic changes in libraries seems major (with realistic I mean usual minor changes for current modeling-building paradigms), and I am not certain of the exact details - or even if it is possible.

However, the unsafe cases are (a bit) farfetched, and we could accept that some things may break in rare cases - similarly as the restrictions on the maintenance branch of MSL (and of course a bug-fix can also break the behavior of some user models).

Note that I'm not saying that this makes it impossible to have semantic versioning in any form in Modelica, only that we need to define it clearly - and have realistic goals.

A minimum goal would be to use semantic version numbers without the semantics of semantic versions would be a solution, but it hardly feels like progress.

modelica-trac-importer commented 5 years ago

Comment by sjoelund.se on 24 Jun 2015 08:44 UTC Replying to [comment:2 mwetter]:

As not all library developers may be aware of what a backward compatible change is, and because it may quickly happen that a non-backward compatible change gets on the development branch inadvertently

A development branch is not the same thing as a release. It is possible to use pre-release version numbers on the development branch.

modelica-trac-importer commented 5 years ago

Comment by hansolsson on 24 Jun 2015 09:14 UTC Replying to [comment:4 sjoelund.se]:

Replying to [comment:2 mwetter]:

As not all library developers may be aware of what a backward compatible change is, and because it may quickly happen that a non-backward compatible change gets on the development branch inadvertently

A development branch is not the same thing as a release. It is possible to use pre-release version numbers on the development branch.

I would more strongly say that one should use a pre-release version on the development branch (as soon there is any development).

However, that doesn't solve M. Wetter's problem, since it depends on what pre-release is it! A pre-release of a patch-version should not contain new functionality. A pre-release of a minor-version should not contain non-backward compatible changes (with regards to the functionality present in the previous released version).

modelica-trac-importer commented 5 years ago

Comment by sjoelund.se on 24 Jun 2015 09:20 UTC Replying to [comment:5 hansolsson]:

A pre-release of a patch-version should not contain new functionality. A pre-release of a minor-version should not contain non-backward compatible changes (with regards to the functionality present in the previous released version).

Not according to semantic versioning:

A pre-release version indicates that the version is unstable and might not satisfy the intended compatibility requirements as denoted by its associated normal version

It is probably a good thing if pre-releases do satisfy these requirements, but they do not need to.

modelica-trac-importer commented 5 years ago

Comment by hansolsson on 24 Jun 2015 09:38 UTC Replying to [comment:6 sjoelund.se]:

Replying to [comment:5 hansolsson]:

A pre-release of a patch-version should not contain new functionality. A pre-release of a minor-version should not contain non-backward compatible changes (with regards to the functionality present in the previous released version).

Not according to semantic versioning:

A pre-release version indicates that the version is unstable and might not satisfy the intended compatibility requirements as denoted by its associated normal version

It is probably a good thing if pre-releases do satisfy these requirements, but they do not need to.

Are you sure?

The semantic version specification both state that the minor version number MUST be incremented for any new functionality (without any exception for pre-release versions), and that pre-release versions MAY be indicated with additional information and it might be unstable and not satisfy the requirements on released versions.

Only the requirement for minor version is a "MUST" which is clearly defined.

My interpretation is that pre-release versions ideally should satisfy the requirements, but since they are not fully tested it is less guaranteed than for released versions. (Even released versions may break compatibility by mistake, that is covered in the semver-faq.)

Added: However, the main point from M.Wetter is how to avoid releasing this breaking change by mistake; and for that case I say that not adding the changes at all seems the safest choice. (Which can then be combined by verifying it afterwards.)

modelica-trac-importer commented 5 years ago

Comment by sjoelund.se on 24 Jun 2015 09:46 UTC I am sure. It was a direct quote from semver.org. You are correct that they should ideally satisfy the requirements, but they do not need to. I guess so you can start development not knowing if the next release will be a major, minor, or patch release.

modelica-trac-importer commented 5 years ago

Comment by hansolsson on 24 Jun 2015 12:00 UTC Replying to [comment:8 sjoelund.se]:

I am sure. It was a direct quote from semver.org. You are correct that they should ideally satisfy the requirements, but they do not need to.

And still the spec states that you MUST increment the version number, not merely that you should do it.

A simple conclusion is that SemVer spec is inconsistent, which has been reported by others (primarily regarding released versions that were incorrect):

https://github.com/mojombo/semver/issues/229

Which contains the following about violating the "MUST" for incrementing versions: "The violation exists forever, so any project which has ever violated rule 8 (or 6, 7, etc.) is not SemVer compliant and will never again be SemVer compliant."

I guess so you can start development not knowing if the next release will be a major, minor, or patch release.

See also https://github.com/mojombo/semver/issues/124

Added: However, regardless of this we are in agreement that the pre-release versions SHOULD NOT contain incompatibilities that would be incorrect for the corresponding released version.

The term 'SHOULD NOT' (using RFC 2119 as in SemVer) is a recommendation where exception can occur - and "user made an error that will be corrected" would be a valid exception in my opinion - but still something that we should try to avoid.

modelica-trac-importer commented 5 years ago

Modified by dietmarw on 18 Sep 2015 07:56 UTC

modelica-trac-importer commented 5 years ago

Comment by henrikt on 23 Sep 2015 10:37 UTC In order to bring the discussion back to the ticket, I'll try to summarize the main problems that need to be resolved.

Before going to the problems, however, I'll state some things that seem clear to me at this point.

  1. I consider a (Modelica) language version header (MCP-0015) a widely accepted prerequisite for the semantic versioning of libraries. In the discussion below, let's assume that semantic versioning of libraries is introduced in Modelica language version 3.S ("S" for "Semantic").

  2. The semantics of a a version number is a property of the library, not a property of the model that uses the library. That is, even if a model uses Modelica version 3.S, not all its uses annotations are necessarily refering to semantic version numbers. Conversely, a tool that is able two handle multiple versions of the language at the same time may allow a model using language version 3.3 (as can be seen by the absence of a language version header) to have uses annotations pointing to libraries with semantic version numbers, and resolve these version numbers as such.

  3. If the language specification mandates that library version numbers are semantic as of language version 3.S, I think that the way we define semantics must be able to rely on version numbers following the semantic rules. To support this, we must find ways to deal with the scenarios where the semantic rules have been violated.

  4. The discussion about semantic versioning of libraries should not be mixed up with the need for versioning of non-top level packages.

  5. The most popular form of a semantic version number seems to be X.Y.Z, where X is called 'major version', Y is called 'minor version', and Z is called 'patch version'.

Main problems

  1. Expressiveness of single version uses annotations. With semantic version numbers, it seems sufficient to only have uses annotations that are basically in the form of valid semantic version numbers. The special case of version numbers with build metadata is discussed separately below. (The need for having multiple version numbers will also be discussed below.) When multiple versions of a library are available, a version number in a uses annotation is resolved to the one of highest precedence (according to semver.org) among those that are compatible with the uses annotation. Possible use cases (SemVerLib is some library using language version 3.S):

    • uses(SemVerLib(version="1.0.0")) — may be resolved by any SemVerLib of major version 1 (except development versions like 1.0.0-alpha)
    • uses(SemVerLib(version="1.2.0")) — may be resolved by any SemVerLib of major version 1 and minor version at least 2.
    • uses(SemVerLib(version="1.2.3")) — may be resolved by any SemVerLib of major version 1, and minor version greater than 2, or minor version equal to 2 with patch version at least 3. The simplicity of this level of expressiveness makes it trivial to merge multiple uses of the same library: If all uses annotations point to the same major version, it is always correct to only consider the one with the highest precedence. For example, if one uses annotation points to 3.2.1 and another points to 3.3.2, they can only be resolved jointly if there is an available version that is compatible with 3.3.2. If multiple versions are allowed in the uses annotation, each major version can be considered separately, and the version can be resolved if there is at least one major version available that is compatible with each use of the library. If some uses annotations disagree on the major version, there is no resolution unless the tool is able to handle multiple versions of a library at the same time. Things that cannot be expressed:
    • Major version at least 1. (Only exact matching of major version makes sense in view of semantic versioning rules.)
    • Version 1.2.3 and nothing else. (Not being interested in other compatible versions according to the rules of semantic versioning doesn't make sense. This kind of library dependency is the very problem we are trying to solve by specifying semantics of version numbers. Of course, a user shouldn't be forced to have other versions than 1.2.3 on his/her system, thereby having the freedom to get version 1.2.3 and nothing else for his/her own models. However, once such a model is given to another user, there is clearly no guarantee anymore that some other compatible version 1.2.3 is not installed on the other user's system.)
    • Varsion 1.2.3 or any compatible version except 1.2.5. (Not being interested in version 1.2.5 doesn't make sense in view of semantic versioning rules. However, in case a mistake was made and rules were broken in version 1.2.5, ways to address the situation must be discussed.)
    • More advanced variants of the above, like version ranges or more general patterns, etc.
  2. Implications for conversion annotations. For a library that is developed entirely using semantic version numbers (first release was using language version 3.S or later), it is clear that conversion annotations should only specify conversions between major versions of the library. Hence, library version 4.3.2 will typically include all the conversions below and no other:

    conversion(from(version={"1"}, ...),
           from(version={"2"}, ...),
           from(version={"3"}, ...))

    When library version 5.0.0 is released, backward incompatible changes can hopefully be addressed with conversion scripts, so from(version={"4"}, ...) is added, and the conversions then remain unchanged until library version 6.0.0 is released.

The difficult part is how to handle conversions for libraries that started out using non-semantic version numbers. For the sake of discussion, consider a variant of conversion annotations that specify both a source and target version, and let's say that version 4.0.0 of the library was the first version using semantic version numbering:

conversion(from(version={"1.0.0", "1.0.1"}, toVersion="1.1.0", ...),
           from(version={"1.1.0"}, toVersion="2.0.0", ...),
           from(version={"2.0.0", "2.1.0", "3.0.0"}, toVersion="3.0.1", ...),
           from(version={"3.0.1"}, toVersion="4.0.0", ...))

Since the library is now using semantic version numbering, no new conversions will be needed when releasing 4.0.1, 4.1.0, 4.1.1, 4.2.0, etc. Not until version 5.0.0 is released does it make sense to add a new conversion:

conversion(from(version={"1.0.0", "1.0.1"}, toVersion="1.1.0", ...),
           from(version={"1.1.0"}, toVersion="2.0.0", ...),
           from(version={"2.0.0", "2.1.0", "3.0.0"}, toVersion="3.0.1", ...),
           from(version={"3.0.1"}, toVersion="4.0.0", ...),
           from(version={"4.0.0"}, toVersion="5.0.0", ...))

Now, the problem is that library version 5.0.0 being marked with language version 3.S or later does not say anything about which language version that was used for library version 4.Y.Z. Consider trying to find a conversion for a model currently using library version 4.3.2:

  1. The semantics of the version numbers. As has already been noted, it is not obvious how to apply the semantics at semver.org to Modelica libraries, and questions have been raised regarding how to deal with violations against the versioning rules. I think it is best to make separate rules for Modelica library semantic versioning, based on ideas from semver.org. The basic rules could be formulated as:

    • Bump major version when a backward incompatible change is introduced.
    • Bump minor version when new stuff is added in a backward compatible way.
    • Bump patch version when existing stuff is modified (bugfixes, etc) in a more or less backward compatible way. I don't think that one has to care about stuff that depend on buggy behavior, and therefore break when a bug is fixed (meaning that fixing a bug should not imply bumping major version). The trickier question is what to do when changing (improving) the dynamic behavior of a component in the library. That will break correctness testing against reference results computed with the old dynamics, so in a way it seems like a backward incompatible change. I would, however, prefer to consider this similar to depending on buggy behavior, and therefore not require bumping of the major version.
  2. How to resolve a uses annotation when a library is using semantic versioning. As mentioned above, I think this one is obvious. Among the available versions of the library, simply pick the version of highest precedence among those that are semantically compatible. I guess the controversial part here might be that a uses annotation is not guaranteed to be resolved to the exact same version of the library, even if that version is available. Some examples of how to resolve uses(SomeLib(version="3.2.1")):

= Available versions = = Resolution = = Comment =
3.2.0, 3.2.2, 4.0.0 3.2.2
3.2.1, 3.3.0, 4.0.0 3.3.0
3.2.0, 4.0.0 N/A Possible dependency on a bugfix that appeared in 3.2.1.
3.2.1-alpha, 4.0.0 N/A
  1. How to update a uses annotation when making changes to a library using semantic versioning. If the uses annoation points at the version currently loaded, nothing needs to be done. The question is what to do when the currently loaded version is a later version that is compatible with the version in the uses annonation. Are there other alternatives than:

    • Refuse to make changes without updating the uses annoation to the currently loaded version.
    • Force the user to disable all newer versions, so that the loaded version is the exact version in the uses annotation.
  2. How to migrate a library non-semantic version numbering to semantic version numbering. When resolving a uses annotation with version="3.2.1", one has to be able to tell which of the available versions of the library that match. By just looking at "3.2.1" in the model, one cannot tell whether it is a semantic version number or not, and therefore one doesn't know whether the dependency may be resolved with version 3.2.2 or not. To figure this out, one must be able to infer this by looking at available versions of the library. If no version 3.... of the library is available, one can stop thinking, since no matching version can be found anyway. Now, if 3.2.2 is available and doesn't use semantic versioning, then we know that 3.2.1 cannot be resolved. On the other hand if 3.2.2 is available and uses semantic versioning, we need to be able to conclude what to do. Hence, it should be required all library versions of the same major version use the same type of versioning. As a consequence, many libraries will need to bump their major version when starting to use language version 3.S. (The exception is when a library has been following the semantic versioning rules even before starting to use langueage version 3.S.)

  3. Generation part of the version number. Personally, I am in favor of a four part version number, W.X.Y.Z, where W is the generation number, and is bumped only when a library is reincarnated with a completely new design, or when a library goes from generation 0 (library design is still under active development) to generation 1 (library design has settled and library is ready for widespread use). In most ways, W.X will work just as X alone in a three part version number. However, conversion scripts should not be expected to deal with upgrades between different generations, and parallel development in different generations can be done without the need to make patch releases with updated conversions. Having the generation number as part of the version number avoids the need to put the generation number in the name of the library, allowing a nicer user experience. For example, if a new MultiBody library would be developed one day, "MultiBody" is still a very good name for such a library, and a generation number in the version avoids the need to use an ugly name such as "MultiBody2". Another possible way to use a generation number is to require the generation number to be increased each time the backward incompatible changes cannot be handled with a conversion script.

  4. Version numbers with build metadata. For example, after releasing version 3.2.1, but before it is known whether the next release should be 3.2.2, 3.3.0, or 4.0.0, it is useful to have version numbers with build metadata, and attach something like a SHA1 and the number of commits since the last tagged version, like 3.2.1+123asd.18. I find it problematic that such a version number has equal precedence to 3.2.1 according to semver.org. I'd expect library developers to have both the latest release and one or more development versions installed on their system, and I don't think resolving a uses annotations pointing to version 3.2.1 with any of the development versions make sense. One possible solution could be to not follow the precedence rules at semver.org when resolving the version in a uses annotation, and only allow 3.2.1+ to match versions with build metadata (and no other versions that would be semantically compatible with 3.2.1, like 3.2.2), and also allow uses annotations pointing out a particular version with build metadata. This avoids the need to define new precedence rules for versions with build metadata, and a user who wants to use the latest of the versions with metadata can either make sure to only have that version installed, or point to a particular version.

  5. Allow parallel development in distinct major versions. There is little reason to allow parallel developmet in distinct minor versions (that is, starting from 3.2.1, first release 3.3.0, and then make additional patches to the minor version 2 in 3.2.2), since a new minor version should be better than the previous in every aspect (in particular, contain the same bugfixes). The question whether parallel development should be allowed in distinct major versions, that is, starting from 3.2.1, first make backwards incompatible changes and release 4.0.0, then fix a bug in major version 3 and release 3.2.2 (or add a new feature and release 3.3.0, for that matter). Allowing parallel development means that version precedence (as defined at semver.org) does not necessarily correspond to chronological order, or that a version with higher precedence should be expected to be superior. The main problem I see here comes when semantic versioning is combined with conversion annotations, as releasing new features in 3.3.0 may call for additional conversion operations to be added to the already released major version 4. It may not be more difficult to handle than require that a the new conversions are included in a new patch release of major version 4, but it's nevertheless a problem to be considered.

  6. Multiple versions in the uses annotation. Sometimes, a package may be compatible with more than one major version of a library, because the backward incompatible changes don't affect the parts of the library that are actually used. Should the package be forced to select only one of the major versions, or should multiple versions be allowed in the uses annotation? If multiple versions would be allowed, it would probably be a good idea to disallow semantically compatible versions in the list. For example, uses(SomeLib(version={"2.0", "2.1", "3.2.1", "4.0.0"})) could be allowed if versioning was introduced in version 3.0.0, while uses(SomeLib(version={"2.0", "2.1", "3.2.1", "3.3.0"})) wouldn't make sense in terms of semantic versioning (specifying "3.3.0" is redundant in the presence of "3.2.1").

modelica-trac-importer commented 5 years ago

Comment by henrikt on 24 Sep 2015 14:27 UTC Some scenarios to support the discussion:

  1. LibA depends on LibB v 3.2.1, user uses LibA without making modifications to it. a. User has one or more versions of LibB installed that are compatible with 3.2.1. b. User has no version of LibB installed that is compatible with 3.2.1.

  2. LibA depends on LibB v 3.2.1, user makes changes to LibA, has one or more versions of LibB installed that are compatible with 3.2.1. a. Version 3.2.1 is one of the installed versions. b. Version 3.2.1 is not one of the installed versions.

  3. LibA is at version 3.2.1, and library developer is fixing a bug. a. The bug is fixed and shall be released immediately. b. The bug is fixed, but more development is expected before the next release.

  4. LibA is at version 3.2.1, library developer adds a new component, and — by mistake — only bumps the minor version to 3.2.2 when releasing a new vewsion of the library.

  5. LibA is at version 3.2.1, a bad design change is made, leading to the release of the very impopular version 4.0.0, and a regretful library developer wants to resume development of major versio 3. (New releases under major version 3 may require updated conversion annotations in major version 4, thereby requiring new patch releases of major version 4.)

  6. LibA is at version 3.2.1, a backward incompatible change is made, and is — by mistake — released in version 3.2.2 (alternatively, in version 3.3.0).

  7. LibA is at version 3.2.1, and a change is made that shall be released immediately (avoiding the question of how to label development versions in this scenario). a. A bug is fixed in a completely backwards compatible way. b. A bug is fixed in a non-backwards compatible way. c. An error in the expression for the inertia matrix of a rigid body is corrected. More generally, fixing errors in the dynamics of ideal (undisputed definition of correct dynamics) components. d. A real parameter value is changed to tweak model dynamics. e. A structural parameter value is changed. f. An expression is changed to tweak model dynamics. g. The dynamics of a component is fundamentally changed (without changing the interface). h. A new component is added. i. An obsolete component is removed. j. A component of poor quality is removed. k. Aestetic changes are made (icons, diagrams, documentation). The idea is not to get a list of actions to take in each of these scenarios, but to verify that a small number generic rules gives a clear answer in each case.

  8. An old well-maintained pre-3.S library at version 1.5.0 is updated to language version 3.S. (Makes sense to think of "1" as generation, and "5" as major, suggesting to make next version 1.6.0.0.)

  9. An old well-maintained pre-3.S library at version 13.7.1 is updated to language version 3.S. (Makes sense to think of "13" as major, suggestion to make next version 14.0.0, or 1.14.0.0.)

  10. A user upgrades to a newer semantically compatible version of a library, but finds that some models that depend on the library break because of this. (Library developer needs to be informed, so that the problems can be fixed in a new patch release.)

modelica-trac-importer commented 5 years ago

Comment by hansolsson on 25 Sep 2015 08:36 UTC First a minor clarification about current status and semantic versioning, which will then lead to more complicated issues (that haven't gotten enough attention in my opinion).

There are three parts of semantic versioning:

  1. Format of version numbers
  2. How to compare version numbers
  3. Semantics of semantic versioning

Versions number in Modelica 3.3r1 are defined including ordering (except as listed below). The version numbers in Modelica 3.3r1 are more general (more levels) - and are slightly different than semantic versioning - using space instead of hyphen to separate pre-release/beta versions, and having "build" as a separate number instead of part of the version number.

The comparisons of versions use the same logic in Modelica 3.3r1 and semantic versioning; except for some odd cases for hierarchical pre-release versions (which I don't think we have used; basically SemVer allows "Beta.9", "Beta.10" to be correctly ordered).

There are also unordered versions in Modelica 3.3r1 - that was intended for things like "MyVersion", "Testing" - I don't know if anyone actually uses those version numbers; and I don't have any strong feelings about them.

But what abut semantics?

Modelica 3.3r1 does not define any semantics for the versions, and I believe this should be main focus - but there are three main issues:

This means that we need to completely need to define the semantics of versions and cannot just reference an existing version of Semantic Versioning.

The things we need to consider are:

One might think that we could define the public API in a way that does not allow "extends ..." from non-partial classes. However, e.g. VehicleInterfaces have non-partial classes that are intended to extend from - with no special marking; and there are also other cases where extending is normal. We might also want to more or less exclude the Examples from the public API for some libraries - but the details are unclear.

If we cannot find a 100% safe solution the benefits seems less clear.

One possibility would be that we could e.g. extend the uses-annotation to indicate that we use more than the public API, e.g.: "uses(Modelica="3.2", extendingFrom= true)", but how and what it brings isn't clear. Similarly we could add something to indicate that a non-partial class is intended to be used as a base-class (new keyword? annotation?).

I'm not saying that using the semantics of semantic versioning is a bad idea or impossible - just that the details are unclear at the moment; and we have a lot of work to do - and that success is not guaranteed.

Replying to [comment:11 henrikt]:

Here is some input for the discussion tomorrow evening. I know it is a lot, but I don't know how to organize it all in a ticket thread like this. Perhaps some of this should go into a development document, and then we could break down the discussion in this thread to consider smaller parts of the document.

In order to bring the discussion back to the ticket, I'll try to summarize the main problems that need to be resolved.

Before going to the problems, however, I'll state some things that seem clear to me at this point.

  1. I consider a (Modelica) language version header (MCP-0015) a widely accepted prerequisite for the semantic versioning of libraries. In the discussion below, let's assume that semantic versioning of libraries is introduced in Modelica language version 3.S ("S" for "Semantic").

  2. The semantics of a a version number is a property of the library, not a property of the model that uses the library. That is, even if a model uses Modelica version 3.S, not all its uses annotations are necessarily refering to semantic version numbers. Conversely, a tool that is able two handle multiple versions of the language at the same time may allow a model using language version 3.3 (as can be seen by the absence of a language version header) to have uses annotations pointing to libraries with semantic version numbers, and resolve these version numbers as such.

  3. If the language specification mandates that library version numbers are semantic as of language version 3.S, I think that the way we define semantics must be able to rely on version numbers following the semantic rules.

I am not sure that we can make an informed decision whether semantic versioning should be required starting from a specific version or not before we have more information about the details - as indicated previously 'public API' is not clear.

Thus I would propose to delay this until the other issues are resolved, or possibly having it optional while we are working on the details - that would allow us to get some of the benefits before everything is clear.

To support this, we must find ways to deal with the scenarios where the semantic rules have been violated.

I agree that we need to handle cases where errors have occurred in a good way, and will later try to explain how that could be handled. However, the only way to deal with it according to the specifications of Semantic Versioning 2.0.0 is to reject your software as non-conformant, i.e. reject all versions of your software as non-conformant.

I am not even sure that the SemVer specification allows you to say that only some library versions are semantically versioned - i.e. even if we don't make any mistakes in the future we might still not be able to say that MSL is semantically versioned due to older versions.

You might argue that this is extreme - but either we follow an existing version of SemVer (which doesn't work in case of errors) - or we clearly define our own rules "in the spirit of SemVer".

  1. Generation component of the version number. Personally, I am in favor of a four part version number, W.X.Y.Z, where W is the generation number, and is bumped only when a library is reincarnated with a completely new design, or when a library goes from generation 0 (library design is still under active development) to generation 1 (library design has settled and library is ready for widespread use).

Having four part version numbers is also an alternative that can be discussed, and is close to the current MSL versions, except that Z is separated out into the build-number. (A separate build-number has some minor problems, e.g. pre-release versions of builds are oddly numbered: "3.2.1 Release Candidate 5" - build 4 is more logically "3.2.1.4 Release Candidate 5" in the sense that the Release Candidates are per build.)

I understand that for other projects this is also quite common, and have seen several people arguing for adding something like that to Semantic Versioning.

However, it is not any version of Semantic Versioning 2.0.0. But if we anyway have to define our own rules that is not a problem - we just need clear understandable rules.

modelica-trac-importer commented 5 years ago

Comment by choeger on 25 Sep 2015 09:40 UTC Since I am not at the meeting, just a few comments:

My pragmatic conclusion would be to introduce mandatory semantic versioning syntax, semantic versioning ordering semantics and, optionally, semantic versioning compatibility semantics (e.g. by an additional annotation). That way, a library could safely migrate to complete semantic versioning semantics by setting a flag and still use semantic versioning syntax for older versions.

modelica-trac-importer commented 5 years ago

Comment by henrikt on 25 Sep 2015 10:00 UTC It seems like we are all pretty much on the same page.

To me, there appears to be several important subtopics of this discussion, with the most difficult one being how to define backward compatibility in a useful manner. I don't see how we can manage discussion of all of these topics at the same time in this ticket alone. How about creating sub-tickets for the different sub-topics, so that each can be discussed in isolation?

modelica-trac-importer commented 5 years ago

Comment by henrikt on 25 Sep 2015 10:16 UTC Replying to [comment:13 hansolsson]:

I am not sure that we can make an informed decision whether semantic versioning should be required starting from a specific version or not before we have more information about the details - as indicated previously 'public API' is not clear.

There was lengthy discussions about this in Waterloo, and then, the conclusion was that semantic versioning should be mandatory as of the language version where it is introduced. This causes no problems for legacy libraries, as they will still use an older version of the language, and when a new library is released using the new version of the language, one just have to make sure to bump the major version if the previous version number was in the form of a semantic version number.

The more general argument for making semantic versioning mandatory is that we don't want a language with features that can be turned on and off. If we introduce an optional language feature now, this would be an excuse for introducing even more feature switches when it is hard to find agreement on other language improvements in the future. For example, I sometimes find it a bit scary that there are non-differentiable built in functions that don't generate events, but I understand that introducing a feature switch for this into a growing collection of switches would be a mess both for users and tool makers.

modelica-trac-importer commented 5 years ago

Comment by hansolsson on 30 Sep 2015 13:12 UTC I realized something related to versions.

The different version schemes mostly differ in how they construct ONE string containing all parts of the version-information (API-version (possibly split into (generation), major, minor), patch (or build), pre-release-information, meta-data).

Having one string is useful for tools - but for humans it seems easier to understand if we actually present the parts separately. This has also been both for the Modelica Standard Library and Modelica Language Specification.

Considering some recent MSL and MLS version we have: MSL 3.2.1+build.3 -> API-version: 3.2.1 Patch-level: 3 Optional pre-release/beta indicator (empty here):

MSL 3.2.1+build.4-rc1 -> API-version: 3.2.1 Patch-level: 4 Optional pre-release/beta indicator: rc1

MLS 3.3 revision 1 -> API-version: 3.3 Patch-level: 1 (although some parts are more than a "bug-fix") Optional pre-release/beta indicator (empty here):

MLS 3.4 -> API-version: 3.4 Patch-level: 0 Optional pre-release/beta indicator:

There are then two separate questions:

As for the currently unnamed version a simple idea would be to just use the date, e.g.: "2015-09-30" (i.e. YYYY-MM-DD format); since they will be sorted correctly and before any alpha/beta/rc. (It is formally a valid pre-release identifier in semantic versioning, even though not exactly in the spirit.) Having some prefix would be nicer, except that it is has to be alphabetically before "alpha".

It might also be that we need something completely different during development (i.e. before the beta-phase).

Replying to [comment:14 choeger]:

Since I am not at the meeting, just a few comments:

* Package managers require a defined (partial) order of versions. Semantic versioning provides that specific semantics - as could the Modelica specification. I think this first point is both crucial and undisputed.

I agree that an ordering is needed.

And just to be clear: the current Modelica Specification already provides a partial ordering for versions (which for normal versions is the same order as defined by semantic versioning).

My pragmatic conclusion would be to introduce mandatory semantic versioning syntax, semantic versioning ordering semantics and, optionally, semantic versioning compatibility semantics (e.g. by an additional annotation). That way, a library could safely migrate to complete semantic versioning semantics by setting a flag and still use semantic versioning syntax for older versions.

To me there are two parts of the compatibility semantics: patches and normal versions.

I believe the specification could limit patches to compatible bug-fixes (that distinction is fairly clear), but the separation of other changes into minor/major is currently semantically unclear and should be optional.

modelica-trac-importer commented 5 years ago

Comment by henrikt on 1 Oct 2015 07:18 UTC I think that having a single string containing the entire version is better, since it allows the very same string to be used when:

Instead of having three separate strings, I think it is enough that the format of the string should make it absolutely clear (and trivial for tools to implement) what the different parts are. A tool may then provide a user interface where the parts may be presented and edited separately, so the normal user can still get a smooth and uncluttered experience.

modelica-trac-importer commented 5 years ago

Comment by dietmarw on 2 Oct 2015 06:07 UTC I totally agree here with Henrik. Why would you try to make things more complicated than necessary and by doing it loosing the ability to handle versions in a standard way. Anyone can implement a grep function for display purposes in order to build a version string out of several components. But the most important thing is we should stick(/move) to the X.Y.Z symantics because that gives both the user and the tool the information they need in a very easy to use and transparent way.

We've already agreed in Lyon that the MSL version number needs to be decoupled from the MLS version number. Without this we don't get in this whole interdependent version mess where we struggle to fit the current version scheme of the MSL implies a certain compatibility with a certain MLS version into a semantic version part.

modelica-trac-importer commented 5 years ago

Comment by hansolsson on 2 Oct 2015 10:06 UTC Replying to [comment:18 henrikt]:

I think that having a single string containing the entire version is better, since it allows the very same string to be used when:

  • Tagging the source repository in typical version control systems that just support a single string for the version.

Except that many (including current MSL) use a v-prefix for the tag (following version 1.0.0 of Semantic Versioning - the status in the versions 2.0.0 is less clear; but the web-pages are called v2.0.0.html), i.e. it is not exactly the same string.

I don't know if it is to clarify that it is a version-tag and not some other tag, or because using pure numbers would create a mess in some version control systems.

  • Making release announcements.

For any non-zero patch/build/refresh/update/revision (or what-ever it is called) it is common to include the information that it is a patch/... at the start of the announcement (if there is an announcement - sometimes a new patch is just pushed silently without any change in version number). At least that is my experience, but I haven't kept detailed statistics.

Basically the first line of the announcement is intended to be understood by users who don't understand the nuances of the versions "3.2.1.4"; without having to duplicate that by also writing "which is a new bug-fix for 3.2.1" at the start.

My point is that if we conceptually start from three parts (or two since we can ignore pre-release information as pre-releases are not widely announced) we can find a better way to store and present that - including the possibility to have generation numbers for the version as you suggested.

I assume the current tag "v3.2.1.build.4" (with description "Version 3.2.1 (Build 4)" )and name "3.2 Revision 2" was made for that reason. Note the spaces - that makes it more readable for users, but problematic for some tools.

I agree that there should logic, and the idea with conceptually considering the three parts of version was to see if we can be clearer. One possibility was to store separate annotations in Modelica - and then define how to map that to one string, another would be to use "build" (or similar word) instead of "." to separate the build. Clearly it should be well-defined, instead of using "build" and "revision" somewhat arbitrarily.

I'm not saying that we have to do this. Just that I don't like a situation where we have to spell out the version-information for every announcement like release "3.2.1.4 [rc1] - which is [release candidate 1] for an updated build of 3.2.1" - basically I am more concerned with making version announcements and information understandable for users than for tools.

Basically I want version numbers to be understandable for users - both in the library and in announcements (and, obviously, correspond to each other).

Instead of having three separate strings, I think it is enough that the format of the string should make it absolutely clear (and trivial for tools to implement) what the different parts are. A tool may then provide a user interface where the parts may be presented and edited separately, so the normal user can still get a smooth and uncluttered experience.

Yes, I indicated that this was one solution - and also that the current handling in Modelica is not good, we combine API-version and pre-release information in one string and separate out the build-number which is logically in the middle.

modelica-trac-importer commented 5 years ago

Comment by dietmarw on 2 Oct 2015 11:00 UTC Hans, the current tag already following semantic version naming (not meaning yet wrt expressing any compatibility with minor or patch though) is v3.2.1+build.4.

3.2.1.4 is not a semantic version so it does not make sense discussing this.

modelica-trac-importer commented 5 years ago

Comment by otter on 2 Oct 2015 12:24 UTC The question is whether we should follow the precise semantic versioning rules defined on the web, or whether we adapt it to our needs?

I like very much most of the rules of semantic versioning. Due to the discussion and own experience I am no longer sure whether "nr1.nr2.nr3" is not too restrictive. The reason is that 90 % of the users will never understand semantic versioning, they just see a version number and interpret it from their experience. It would therefore be better, if someone who does not know at all "semantic versioning" grasps at once the meaning of a version number, by just looking at the version tag. In this respect a version number such as

// MSL
3.2.1+build.4 or
3.2.1+patch.4 or

// Modelica_DeviceDrives
1.4+build.3 or
1.4+patch.4

is clearer: The user sees that this is version 3.2.1 or 1.4, but something is patched (so an error correction). If a users sees 1.4.3 he/she needs the additional information that this is a "semantic version" number and what this means (and I do not think that this can be expected).

Therefore, one possibility could be to extend the semantic version rules:

Not restrict to precisely 3 numbers, but to any number of numbers (one, two, three, four, ... numbers), and otherwise follow the rules (so "+" means afterwards and "build" or "patch" is alphabetically sorted. Since "patch" always means "have something fixed", this is not a good word for the first build of a released version. Therefore, we could use the following scheme (that has a strict ordering and is at once understood by humans):

3.2.2-alpha.1  // alpha version
3.2.2-beta.2   // beta version
3.2.2-rc.1     // release candidate
3.2.2+build.1  // first release version
3.2.2+build.2  // bug-fixed release

For some Modelica libraries that do not change so often, it might be better to have only 2 version numbers (such as 2.1).

The proposal above is only regarding a precise ordering of version numbers, not about the meaning. The big question is what means "backwards compatible"? If we are strict, we need tool support, and a tool tells us whether a library is backwards compatible to another library and then we adapt the version number correspondingly.

However, for Modelica this would mean that nearly no new release will be backwards compatible. The reason is that the user might have used "import xxx.*" or "extends xxx" and then every addition of a new component (either public or protected in a model or public or protected in a package) is not backwards compatible. Since every MSL release in the past introduced new components, none of the MSL releases in the past claimed as "backwards" compatible is backwards compatible in this sense.

modelica-trac-importer commented 5 years ago

Comment by hansolsson on 2 Oct 2015 12:25 UTC Replying to [comment:21 dietmarw]:

Hans, the current tag already following semantic version naming (not meaning yet wrt expressing any compatibility with minor or patch though) is v3.2.1+build.4.

You are right that the versions "3.2.1+build.4" and "3.2.1+build.4-rc1" follow the syntax of semantic versions without the 'v').

However, they are not correct semantic versions name - in the semantic sense (even ignoring API compatibility with other versions). The reason is that "+" separates the meta-data, but "build.4" and "build.4-rc1" is not meta-data.

Note that in particular "rc1" is not seen as a pre-release identifier, but part of the meta-data (actually part of the identifier "4-rc1"). Added: Note that if it had been part of version comparison then the order would have been build.3, build.4, ..., build.1-rc1 since numerical identifiers precede non-numerical ones (i.e. "4" is before "1-rc1").

The semantics of comparing version is more complicated (meta-data is more or less ignored - depending on SemVer version); I would hope we could progress on discussing that. Otherwise we seem to be discussing semantic versioning without semantics.

The reason I wanted to conceptually think of API-version, patch-number, and pre-release-version is to not focus on the syntax of the individual versions number, but to focus on comparing version, and how to present this information for users.

What to store in models and in version tags is the easy part; when we know what we mean - i.e. focusing on SEMANTICS.

However, compatibility is difficult in Modelica due to using classes as base-classes, hierarchical modifiers, import A.*, etc. A minimum is to define a bug-fix in a clear sense (since you shouldn't add new public classes in that case).

3.2.1.4 is not a semantic version so it does not make sense discussing this.

I'm fully aware of that it is not consistent with SemVer 2.0.0 specifications; as indicated above in my comment 13.

However, Henrik previously mentioned the idea of adding generation number to construct 4-part version numbers (in comment 12 - item 7); and there are also others that prefer them and have proposed extending SemVer along those lines - and thus I find it relevant for this discussion.

As previously indicated there are problems with SemVer 2.0.0 specification that makes it impossible to strictly follow it; and thus we anyway have to define our own rules ("in the spirit of SemVer").

modelica-trac-importer commented 5 years ago

Comment by hansolsson on 2 Oct 2015 12:41 UTC Replying to [comment:22 otter]:

The question is whether we should follow the precise semantic versioning rules defined on the web, or whether we adapt it to our needs?

...

Therefore, we could use the following scheme (that has a strict ordering and is at once understood by humans): {{{
3.2.2-alpha.1 // alpha version 3.2.2-beta.2 // beta version 3.2.2-rc.1 // release candidate 3.2.2+build.1 // first release version 3.2.2+build.2 // bug-fixed release }}}

To be clear:

modelica-trac-importer commented 5 years ago

Comment by hansolsson on 12 Nov 2015 08:48 UTC The recent discussion about Modelica 2 License made me realize that something I had previously read is getting more important:

Semantic versioning (in current forms) are not suitable for distributed development where multiple people may develop changes to a library in parallel.

One could potentially argue that those versions are not public "releases"; but that argument seems wrong for two reasons: they are publicly available (just an url for everyone to click on) - and semantic versioning also specifies the handling of pre-release versions (without any way of disabling it).

There are, of course, multiple proposals for changing semantic versioning to handle it; but none accepted - one of the simpler solution is just to abandon strict numbering of non-released versions (hopefully with some tag to make that it clear which versions are released and which aren't).

modelica-trac-importer commented 5 years ago

Comment by choeger on 12 Nov 2015 09:38 UTC I think that a distributed development scheme does not get along with versioning very well. In such a scenario, versioning is usually left to some upstream while all forks are working on a specific branch. In fact, the point that we have named branches, tags and commit hashs in git makes versions superfluous during development (except of course for the fact that versions are understandable for people that are not developers of the project ;)). So IMO a version number is a way for a project to communicate with the outside. Hence, a fork should always only change the version number as a service to upstream (i.e. "what about doing this as version 2.3?") or when the fork intends to be permanent (i.e. "upstream is a bunch of lamers use LibreModelica from now on!")

modelica-trac-importer commented 5 years ago

Comment by sjoelund.se on 12 Nov 2015 09:47 UTC Pre-release version numbers work rather OK for us in OpenModelica using git. For example: v1.9.4-dev.473+gea54626: 1.9.4 development, 473 commits from development started, git hash ea54626 (note that there may be multiple copies 473 commits deep, even in the same branch). The git hash is there so we know exactly what commit someone is using, and the sequence is there to give the user (of nightly builds) the feel of a linearly increasing version number.

modelica-trac-importer commented 5 years ago

Comment by otter on 12 Nov 2015 10:04 UTC Replying to [comment:27 sjoelund.se]:

Pre-release version numbers work rather OK for us in OpenModelica using git. For example: v1.9.4-dev.473+gea54626: 1.9.4 development, 473 commits from development started, git hash ea54626 (note that there may be multiple copies 473 commits deep, even in the same branch). The git hash is there so we know exactly what commit someone is using, and the sequence is there to give the user (of nightly builds) the feel of a linearly increasing version number.

Does this also work if there are different forks and different branches in different forks? Even if this works then this means probably that for every committ "somehow" the version number has to be updated in the library (which seems not practical).

modelica-trac-importer commented 5 years ago

Comment by hansolsson on 12 Nov 2015 10:23 UTC Replying to [comment:27 sjoelund.se]:

Pre-release version numbers work rather OK for us in OpenModelica using git. For example: v1.9.4-dev.473+gea54626: 1.9.4 development, 473 commits from development started, git hash ea54626 (note that there may be multiple copies 473 commits deep, even in the same branch). The git hash is there so we know exactly what commit someone is using, and the sequence is there to give the user (of nightly builds) the feel of a linearly increasing version number.

If you rely on the git-hash to disambiguate versions you are not following semantic versioning (depending on version that is either a bit wrong - or completely wrong).

As I understand your scenario with distributed development scenario it might be that 405, 413 and 473 is one branch and 406, 413 (with other hash) and 460 are on another branch.

An issue with distributed development is that there is no strict order between the versions on different branches that make sense (as assumed by semantic versioning), but what you state is that users only look at a sub-set of version (the nightly builds) - and that sub-set is strictly ordered (since the nightly builds are centralized).

Basically you are not really following any published version of semantic versioning - but something inspired by it. That wouldn't be a problem if people stated that (and specified those rules).

Added: Mathematically speaking the difference is that semantic versioning imposes a 'total order', but we only have 'partially ordered set' (at least for the distributed development versions).

modelica-trac-importer commented 5 years ago

Comment by sjoelund.se on 12 Nov 2015 10:47 UTC

If you rely on the git-hash to disambiguate versions you are not following semantic versioning (depending on version that is either a bit wrong - or completely wrong).

We don't. The released versions will all use unique identifiers though (which are monotonous). A git describe in someone else's repository might use the same id, but the official repository's HEAD will not re-use IDs. With the hashes, you can tell if someone for example uses a different repository or branch (so, unofficial releases).

No one else can make an official release anyway. I mean... some random person (let's say me) can't start distributing MSL as 4.7.3 and expect that it follows semver. And the fact that someone would create this file does not magically make the official MSL not follow semver anymore.

Of the releases (made from the HEAD of the master branch on the development server), the ordering is total. And that can be considered authoritative.

Note: Maintenance branches can be handled in a similar way (if for example, the last release is 3.3.0, you can have it auto-increment release builds like 3.3.1 for 1 commit into the branch).

Anyway, I do not think it is problematic as long as one sets up a good system for how to deal with versions.

modelica-trac-importer commented 5 years ago

Comment by hansolsson on 12 Nov 2015 11:20 UTC Replying to [comment:30 sjoelund.se]:

Anyway, I do not think it is problematic as long as one sets up a good system for how to deal with versions.

I agree, and the problem is that we need a good system for how to deal with versions, or more specifically:

modelica-trac-importer commented 5 years ago

Comment by choeger on 12 Nov 2015 13:18 UTC Replying to [comment:31 hansolsson]:

* Semantic versioning (in current forms) does not fit the requirements of distributed development.

Why? In what scenario would there be which problem? e.g. the linux kernel follows something very similar to semver and is one of the largest distributed projects that I know of - so I assume they would have hit any practical problem.

modelica-trac-importer commented 5 years ago

Comment by hansolsson on 12 Nov 2015 14:10 UTC Replying to [comment:32 choeger]:

Replying to [comment:31 hansolsson]:

* Semantic versioning (in current forms) does not fit the requirements of distributed development.

Why? In what scenario would there be which problem? e.g. the linux kernel follows something very similar to semver and is one of the largest distributed projects that I know of - so I assume they would have hit any practical problem.

The Linux kernel uses a hierarchical numbered version number for released versions; I believe we all agree that it makes sense - and we already use that for MSL, and it is specified in the current Modelica specification.

However, Linux kernel does not follow semantic versioning (in terms of version numbering and semantics). Even the current Modelica version specification seems closer to semantic versioning than the Linux kernel versioning described below.

At least according to https://en.wikipedia.org/wiki/Linux_kernel#Version_numbering they have generation.major.minor (and sometimes .emergencyPatch) and development versions use initial of developers, not any generic "dev", "alpha" designator and thus avoid the problem of distribution and strict ordering.

For the semantics the Linux kernel is not following semantic versioning (regarding API-changes). That's why Linus asked if he should make Linux kernel 4.0 or not; whereas it for semantic versioning would be automatic iff any internal API in the kernel had any incompatible change.

I have a feeling that telling Linus to use semantic versioning in its current form might not get a polite response.

modelica-trac-importer commented 5 years ago

Comment by henrikt on 13 Nov 2015 08:21 UTC Replying to [comment:31 hansolsson]:

Replying to [comment:30 sjoelund.se]: * One would think that if we add semantic versioning we would actually have semantics of versions - including how to know if it is a released version or a development version. I don't see the benefit of super-strict rules if we don't know when they apply. * Semantic versioning (in current forms) does not fit the requirements of distributed development. Requiring an order between unrelated development versions does not make sense, and I don't see that this scenario is a major issue for the license and a non-issue for the versioning.

I'll try repeat/rephrase what I think sjoelund.se already explained here. The good intention to have distributed development in mind does not mean we should promote versioning anarchy by the way we open things up in the semantic versioning scheme we decide on. Distributed development is good, but having multiple authorities that independently define their own official version numbers for the same library is not good. Each library should have one authority that defines the content of official releases that the corresponding version numbers.

In my opinion, a contributor should never introduce version numbers deriving from not yet officially released version numbers. If the intention is to make a new feature part of a specific not yet released version, there are cleaner ways to communicate this to the primary maintainer than to encode it in a semantic version number. For a big contribution project, clearly communicating which (feature) branch is being distributed is probably a better idea than fiddling with the semantical parts of a semantic version number. Users will have to be aware anyway that they are not using an official release, and a version number like 4.3.2+NewMultiBody.7654.gea54626 could be one way of telling that this is a non-official release of the NewMultiBody project, currently 7654 commits from the official release 4.3.2, having hash gea54626. (Note that it is the NewMultiBody project itself that decides to include its name in the build metadata.)

Since not everybody is using Git, we cannot decide on a semantic versioning scheme where a Git hash is a mandatory part. We just have to make sure that the scheme is flexible enough to make it possible to specify build metadata like the one used by OpenModelica or in the NewMultiBody example above.

modelica-trac-importer commented 5 years ago

Comment by hansolsson on 13 Nov 2015 09:21 UTC Replying to [comment:34 henrikt]:

Replying to [comment:31 hansolsson]:

Replying to [comment:30 sjoelund.se]: * One would think that if we add semantic versioning we would actually have semantics of versions - including how to know if it is a released version or a development version. I don't see the benefit of super-strict rules if we don't know when they apply. * Semantic versioning (in current forms) does not fit the requirements of distributed development. Requiring an order between unrelated development versions does not make sense, and I don't see that this scenario is a major issue for the license and a non-issue for the versioning.

I'll try repeat/rephrase what I think sjoelund.se already explained here. The good intention to have distributed development in mind does not mean we should promote versioning anarchy by the way we open things up in the semantic versioning scheme we decide on. Distributed development is good, but having multiple authorities that independently define their own official version numbers for the same library is not good. Each library should have one authority that defines the content of official releases that the corresponding version numbers.

I agree, and my main input is that distributed development and sites like github makes it even more important to have a good versioning system, because the development no longer have a strict order(the official releases still do), and all versions are available to the public at the same level (including development ones).

In my opinion, a contributor should never introduce version numbers deriving from not yet officially released version numbers. If the intention is to make a new feature part of a specific not yet released version, there are cleaner ways to communicate this to the primary maintainer than to encode it in a semantic version number. For a big contribution project, clearly communicating which (feature) branch is being distributed is probably a better idea than fiddling with the semantical parts of a semantic version number. Users will have to be aware anyway that they are not using an official release, and a version number like 4.3.2+NewMultiBody.7654.gea54626 could be one way of telling that this is a non-official release of the NewMultiBody project, currently 7654 commits from the official release 4.3.2, having hash gea54626. (Note that it is the NewMultiBody project itself that decides to include its name in the build metadata.)

Yes, something like the above might work. One solution might be to be generous with project names (and use user-names as backup/part of hierarchy) - and/or possibly accept that development versions may not unique version numbers.

An interesting part of this is that you are also discussing post-release development, i.e. 4.3.2+changes whereas semver only discusses pre-releases 4.3.3-notYetDone. (There are several proposals for changing this aspect of semver, of course.)

If we consider a distributed scenario where people want to (report and) fix bugs and propose additions I agree that the scenario of post-release version might in many cases be a preferable alternative to pre-release versions. That keeps the decision about new releases centralized - without blocking development.

modelica-trac-importer commented 5 years ago

Comment by henrikt on 13 Nov 2015 09:45 UTC Replying to [comment:35 hansolsson]:

Replying to [comment:34 henrikt]:

In my opinion, a contributor should never introduce version numbers deriving from not yet officially released version numbers. If the intention is to make a new feature part of a specific not yet released version, there are cleaner ways to communicate this to the primary maintainer than to encode it in a semantic version number. For a big contribution project, clearly communicating which (feature) branch is being distributed is probably a better idea than fiddling with the semantical parts of a semantic version number. Users will have to be aware anyway that they are not using an official release, and a version number like 4.3.2+NewMultiBody.7654.gea54626 could be one way of telling that this is a non-official release of the NewMultiBody project, currently 7654 commits from the official release 4.3.2, having hash gea54626. (Note that it is the NewMultiBody project itself that decides to include its name in the build metadata.)

Yes, something like the above might work. One solution might be to be generous with project names (and use user-names as backup/part of hierarchy) - and/or possibly accept that development versions may not unique version numbers.

Right, let us not try to enforce global uniqueness of build metadata. We would be doomed to fail unless we introduce something the size of reverse DNS namespaces for build metadata. Imagine having to deal with version numbers like 4.3.2+com.wolfram.NewMultiBody.7654.gea54626, and how projects would have to agree on which reverse DNS to use… and not even this would work for individual contributors that don't have their own domain…

I don't think that we shouldn't even define project and/or user names in the versioning scheme, only not that such things should go into the build metadata part if someone wants to include such information. We should not define semantics for the build metadata, so by just looking at a semantic version number with build metadata, it won't be clear if the alphanumeric chunks denote project names, user names, branch names, exceptional hashes, or whatever. The interpretation of the build metadata should be defined where the non-official version is being distributed. Let us focus on the semantics of official release versions, including official pre-release versions.

modelica-trac-importer commented 5 years ago

Comment by mtiller on 13 Nov 2015 13:29 UTC Replying to [comment:35 hansolsson]:

Replying to [comment:34 henrikt]:

Replying to [comment:31 hansolsson]:

Replying to [comment:30 sjoelund.se]: * One would think that if we add semantic versioning we would actually have semantics of versions - including how to know if it is a released version or a development version. I don't see the benefit of super-strict rules if we don't know when they apply. * Semantic versioning (in current forms) does not fit the requirements of distributed development. Requiring an order between unrelated development versions does not make sense, and I don't see that this scenario is a major issue for the license and a non-issue for the versioning.

I'll try repeat/rephrase what I think sjoelund.se already explained here. The good intention to have distributed development in mind does not mean we should promote versioning anarchy by the way we open things up in the semantic versioning scheme we decide on. Distributed development is good, but having multiple authorities that independently define their own official version numbers for the same library is not good. Each library should have one authority that defines the content of official releases that the corresponding version numbers.

I agree, and my main input is that distributed development and sites like github makes it even more important to have a good versioning system, because the development no longer have a strict order(the official releases still do), and all versions are available to the public at the same level (including development ones).

I'd like to address the two comments that "Semantic versioning (in current forms) does not fit the requirements of distributed development" and "distributed development and sites like github makes it even more important to have a good versioning system".

Let's take a step back here to recognize that npmjs.org hosts over 205,000 packages. They use semantic versioning (https://docs.npmjs.com/getting-started/semantic-versioning). Furthermore, nearly all of those packages are actually developed via GitHub. As such, I'm puzzled by the notion that semantic versioning is somehow not sufficient for use either with GitHub or that it would somehow be insufficient for distributed version control. As we say in English, "the proof is in the pudding".

That being said, one advantage they have in the Javascript world is the de facto universal registry that is npmjs.org. So in some sense, what we might be missing is a definite source for naming that disambiguates any competing claims to a name. But that is part of what Dietmar and I have been trying to do with the impact project because if you look carefully you will see that the public impact index (which is what is used by our impact search engine(impact.github.io) and the impact command-line tool is based on the projects specifically registered on GitHub under the modelica, modelica-deprecated and modelica-3rdparty organizations. In other words, we are already attempting to establish a fixed namespace to avoid confusion over library names. This approach allows people, without issue, to fork and modify libraries.

In summary, GitHub+Semantic Versioning = proven success at scale. I would argue that what this discussion highlights more than anything is the need for a universal registry of Modelica packages and an associated index. That is what we are trying to do with impact. So I think our energy would be better spent trying to realize such a registry than arguing about whether distributed development and semantic versioning can actually work.

modelica-trac-importer commented 5 years ago

Comment by hansolsson on 13 Nov 2015 13:45 UTC Replying to [comment:36 henrikt]:

Replying to [comment:35 hansolsson]:

Replying to [comment:34 henrikt]:

In my opinion, a contributor should never introduce version numbers deriving from not yet officially released version numbers. If the intention is to make a new feature part of a specific not yet released version, there are cleaner ways to communicate this to the primary maintainer than to encode it in a semantic version number. For a big contribution project, clearly communicating which (feature) branch is being distributed is probably a better idea than fiddling with the semantical parts of a semantic version number. Users will have to be aware anyway that they are not using an official release, and a version number like 4.3.2+NewMultiBody.7654.gea54626 could be one way of telling that this is a non-official release of the NewMultiBody project, currently 7654 commits from the official release 4.3.2, having hash gea54626. (Note that it is the NewMultiBody project itself that decides to include its name in the build metadata.)

Yes, something like the above might work. One solution might be to be generous with project names (and use user-names as backup/part of hierarchy) - and/or possibly accept that development versions may not unique version numbers.

Right, let us not try to enforce global uniqueness of build metadata. We would be doomed to fail unless we introduce something the size of reverse DNS namespaces for build metadata. Imagine having to deal with version numbers like 4.3.2+com.wolfram.NewMultiBody.7654.gea54626, and how projects would have to agree on which reverse DNS to use… and not even this would work for individual contributors that don't have their own domain…

I agree - except a terminology change.

We shouldn't call it metadata as that causes confusion with metadata in semver (which is ignored for the versioning - more or less strictly depending on version); whereas this development-tag is an important part of the version.

What I don't want is to that claim that we use semver - and/or its terminology and then have different semantic meaning, even if we certainly wouldn't be the first ones to do that.

Let us focus on the semantics of official release versions, including official pre-release versions.

I agree that the important part is handling official versions, and being able to tell if it is an official version or not.

modelica-trac-importer commented 5 years ago

Comment by henrikt on 16 Nov 2015 07:43 UTC Replying to [comment:38 hansolsson]:

Replying to [comment:36 henrikt]:

Right, let us not try to enforce global uniqueness of build metadata. We would be doomed to fail unless we introduce something the size of reverse DNS namespaces for build metadata. Imagine having to deal with version numbers like 4.3.2+com.wolfram.NewMultiBody.7654.gea54626, and how projects would have to agree on which reverse DNS to use… and not even this would work for individual contributors that don't have their own domain…

I agree - except a terminology change.

We shouldn't call it metadata as that causes confusion with metadata in semver (which is ignored for the versioning - more or less strictly depending on version); whereas this development-tag is an important part of the version.

OK, but then we don't agree. :) What I suggested was to use the semver metadata concept, so that we don't have to define order in version number anarchy (where anybody is entitled to introduce version numbers at will, and distribute more or less official versions of a library in a completely decentralized manner).

The official registry that Mike suggested in comment 37 would be one way of defining what the official version numbers are, as well as indirectly defining the authorities defining version numbers for each library (by means of privileges to add new version numbers to the distribution site listed in the official registry). Personally, I think that each library would be able to define this by itself, without a need for an official registry. If a library fails to include a README file listing the primary distribution site and/or include this information in the top level package documentation, they might as well fail to register themselves with the official registry. (In my opinion, an official registry plays a more important roll for the allocation of library package roots — compare Java namespaces.) Anyway, I think the main point that Mike is making here is that the important thing is defining what the official versions are, rather than trying to define semantics of non-official versions.

What I don't want is to that claim that we use semver - and/or its terminology and then have different semantic meaning, even if we certainly wouldn't be the first ones to do that.

Sure, that seems sensible. It's just that, at the moment, the terminology from semver is still the best match for our discussions. In the end, we will need to define our own terminology, but even then, I think that large overlap with semver terminology is desirable to avoid confusion when talking about versions with those who have already adopted semver terminology for their mental picture of semantic versioning in general.

Let us focus on the semantics of official release versions, including official pre-release versions.

I agree that the important part is handling official versions, and being able to tell if it is an official version or not.

Again, this is not something that has to be clear from the semantic version number itself. It is enough to assume that each library has a single official site where official versions are defined. If a version is listed there, it is official, and vice versa. If you want an official release of a library, don't use a version with build metadata in the version number; get yourself a plain version instead, and it will be an official version as long as there aren't wild contributors to the library out there that don't respect the library's build metadata scheme (which should, at least, ensure that any deviation from an official release is marked with some sort of non-empty build metadata in the version number). Again, if we focus on the semantics of official releases, it should be up to each library to define how to use the build metadata part of the version number.

modelica-trac-importer commented 5 years ago

Comment by hansolsson on 17 Nov 2015 15:40 UTC Replying to [comment:39 henrikt]:

Again, this is not something that has to be clear from the semantic version number itself. It is enough to assume that each library has a single official site where official versions are defined. If a version is listed there, it is official, and vice versa. If you want an official release of a library, don't use a version with build metadata in the version number; get yourself a plain version instead, and it will be an official version as long as there aren't wild contributors to the library out there that don't respect the library's build metadata scheme (which should, at least, ensure that any deviation from an official release is marked with some sort of non-empty build metadata in the version number). Again, if we focus on the semantics of official releases, it should be up to each library to define how to use the build metadata part of the version number.

I see, the idea is that we follow semver syntax and official versions have special "metadata" tags (either empty or some "magic" mark - which may depend on the package); and non-official versions have different non-empty ones.

That is fine and could work if we describe it.( * )

However, using the meta-data to give precedence to different versions is not semver 2.0.0 semantics from http://semver.org/ (and later even clearer): Precedence MUST be calculated by separating the version into major, minor, patch and pre-release identifiers in that order (Build metadata does not figure into precedence). MUST: This word, or the terms "REQUIRED" or "SHALL", mean that the definition is an absolute requirement of the specification.

Using pre-release syntax would require more discipline (as previously indicated) - and one can view this as reinterpreting meta data as "post-release information" ("-" means before and "+" after!).

*: One possibility would be cryptographic checksum for the official releases, although there are issues to resolve regarding that.

Replying to [comment:37 mtiller]:

I'd like to address the two comments that "Semantic versioning (in current forms) does not fit the requirements of distributed development" and "distributed development and sites like github makes it even more important to have a good versioning system".

Let's take a step back here to recognize that npmjs.org hosts over 205,000 packages. They use semantic versioning (https://docs.npmjs.com/getting-started/semantic-versioning).

The claim is that there are 205,000 packages and they state that they use semver. One would think that this means that 205,000 packages use semver in some meaningful way, right?

Well, when I looked of the most recently changes packages 7 of 12, and for the most downloaded 6 of the 20 were below version 1.

That means that semver does not give ANY compatibility guarantees for those packages.

And for the ">=1.0.0" packages when looking I could see that many don't *strictly* follow semver (looking through changelog), and semver makes it clear that you can only follow it strictly; once your package is no longer semver compliant you are out. I believe that strictness is what attracts many to semver (it sounds impressive) - but then the strictness is often ignored in practice (when it comes in conflict with practical problems).

Additionally even npmjs does not strictly follow semver, in particular the precedence is different regarding pre-release tags (I actually find that the npmjs-precedence makes more sense than the semver one and solves some problems, but it doesn't suffice).

So, the point remains that forking in git and github causes similar problems for both semver and the Modelica License; and I don't see why we should solve one and ignore the other.

modelica-trac-importer commented 5 years ago

Comment by mtiller on 17 Nov 2015 16:32 UTC Hans, I don't understand your comments. A package with a version number less than 1.0.0 is still using semver. Such a version means "this is not ready for use, anything could break". I don't see why the presence of such packages doesn't constitute "meaningful" use of semver. They are using semver to express exactly what they want to express.

Furthermore, people who label their code with incorrect versions are irrelevant. No matter what system we come up with here, users will always be free to abuse the system. The important point with npm is that people are, in effect, punished for such things because their users will complain that their code is breaking when it shoudn't.

It would be more helpful if you pointed out specifically what you mean when you say "npm" doesn't follow semver for pre-releases. It may very well be true, but I couldn't find any reference to what you are talking about.

Finally, what would be more compelling as an argument would be to point out where any of these issues actually impacted somebody. We spend a lot of time in Modelica chasing ghosts of problems where actual problems don't exist.

My point was that lots of people use npm successfully. Nothing you said refutes that statement. This discussions is, in my opinion, a great example of the proverb "Perfect is the enemy of good". What is to be gained by spending what is likely to be years arguing about the perfect versioning system? I am willing to stipulate that semver may not be perfect. But I assert it is good enough and I don't feel you've demonstrated otherwise.

modelica-trac-importer commented 5 years ago

Comment by hansolsson on 17 Nov 2015 17:39 UTC Replying to [comment:41 mtiller]:

Hans, I don't understand your comments. A package with a version number less than 1.0.0 is still using semver. Such a version means "this is not ready for use, anything could break".

And 6 out of 20 most downloaded packages were such packages. Do you honestly not see that there is a problem when something that is not ready for use is used?

Furthermore, people who label their code with incorrect versions are irrelevant. No matter what system we come up with here, users will always be free to abuse the system. The important point with npm is that people are, in effect, punished for such things because their users will complain that their code is breaking when it shoudn't.

If a specification has an 'absolute requirement' it is not irrelevant if people break it.

According to semver the package is no longer compliant. The specification text for semver (in contrast to the FAQ) does not specify ANY way of getting back on track - or what 'back on track is', in fact there is NO WAY back.

That does not help users; so people ignore that and try to be sensible instead.

It would be more helpful if you pointed out specifically what you mean when you say "npm" doesn't follow semver for pre-releases. It may very well be true, but I couldn't find any reference to what you are talking about.

https://docs.npmjs.com/misc/semver#prerelease-tags

Finally, what would be more compelling as an argument would be to point out where any of these issues actually impacted somebody. We spend a lot of time in Modelica chasing ghosts of problems where actual problems don't exist.

The problem exists if we actually follow semver, but since you seem unconvinced that an absolute requirements matter - let us consider a practical example: https://trac.modelica.org/Modelica/ticket/1241

I agree with the change, and I don't like that people are afraid to make sensible changes - just because of some theoretical compatibility issue.

Users don't complain if the interface is incompatible with previous version; they only complain if the change impacted them negatively.

My point was that lots of people use npm successfully. Nothing you said refutes that statement. This discussions is, in my opinion, a great example of the proverb "Perfect is the enemy of good". What is to be gained by spending what is likely to be years arguing about the perfect versioning system? I am willing to stipulate that semver may not be perfect. But I assert it is good enough and I don't feel you've demonstrated otherwise.

I don't want a perfect a versioning system - just one that has rules you can actually follow; whereas semver claims to be the perfect system.

And I didn't say that npm was bad - I discussed problems with semver, that matters since npm handles semver syntax and semantics that are both semver and semver-like.

So, I don't want a perfect versioning system just something basic with a suitable syntax and some rules (similar to the npm-summary of semver):

The "normal Modelica models" needs to be defined to make it suited for Modelica; see comment 2 and 3 above - it is amazing how little the concrete problems of defining compatibility in Modelica have been discussed.

modelica-trac-importer commented 5 years ago

Comment by henrikt on 27 Nov 2015 08:49 UTC Should we try to get some time at the next meeting just for bringing some structure to the discussions?

modelica-trac-importer commented 5 years ago

Modified by dietmarw on 2 Dec 2015 10:08 UTC

modelica-trac-importer commented 5 years ago

Comment by hansolsson on 13 Sep 2016 13:16 UTC Design group: This ticket is long and it is somewhat difficult to follow the discussion.

One possibility is to split off separate tickets for specific topics - and just cross-linking them to this one. Do we agree that this is a good idea? Yes.

Some trac-systems can create sub-tickets, dependencies etc - we will just have to handle that manually. E.g. we will have to ensure that all subtickets are closed before closing the main one. We could also install the addon in trac for it - but then it adds maintenance.

modelica-trac-importer commented 5 years ago

Comment by leo.gall on 24 Apr 2018 11:56 UTC Does this ticket replace #573 Package improvements?

How do we get going, again? Plan a joint meeting of MAP-LANG and MAP-LIB?

modelica-trac-importer commented 5 years ago

Comment by dietmarw on 24 Apr 2018 12:20 UTC I don't think it replaces #573 but can be handled independently. Having finally semantic versioning in place and standing on the shoulders of a giant like npm is definitely they way to go. They have a semver based system that is the largest registry (with today 619670 packages and growing by about 500 per day) in the world and *just works* (http://www.modulecounts.com/). If you are in doubt ask people like Michael Tiller who work with this on a daily basis.

So the pragmatic solution is to simply use this as also suggested by @HansOlsson

modelica-trac-importer commented 5 years ago

Comment by henrikt on 26 Apr 2018 20:23 UTC One of the obstacles holding this back has been the Language Version MCP #1726, which has been considered a prerequisite for starting to apply semantic versioning rules for libraries. I'll move it now to _Under Evaluation', which gives us at least some progress in this area.

I still think it will be necessary to break down the discussion into sub-topics, before organizing something as big as a joint MAP-LANG and MAP-LIB meeting. Perhaps someone from MAP-LIB would like to join the working group, and then the working group could begin by doing the break-down? With a better overview, I hope we (as in this ticket thread) will be able to identify the most important sub-topics to be discussed in a bigger group.

casella commented 2 years ago

See also #3209 for the specific issue of what "backwards compatible" actually means.