[GH-ISSUE #765] RFC: Forward-development or WIP (work-in-progress) support in Semantic Versioning #2242

Open
opened 2026-04-20 10:15:10 -05:00 by GiteaMirror · 17 comments
Owner

Originally created by @EvanCarroll on GitHub (Oct 28, 2021).
Original GitHub issue: https://github.com/semver/semver/issues/765

The spec assumes that pre-release is made on the final published version,

$VERSION-$PRERELEASE

This assumes you know what $VERSION will be as you progress with development and that your release is premediated. This is not ideal for modern agile development practices such as those espoused by semantic-release. As such, code in a broken state or not ready to ship but needing testing, versioning, building, and deployment is not supported by semantic-version.

Suggested Fix

Currently semantic-version supports the following to delineate non-version data,

  • The - prefix for pre-release.
  • The + prefix for build metadata.

By introducing a third unused character a forward-slash / (mnemonic Forward-Progress), we can mark a build as not-released and internal, but more forward than the actual version. We can call this "Forward"

Working Example

Let's say you decide to develop a new feature. The product your working on is currently at version 7.0.0 and your first commit is 0d0e0a1d8f. This version number could be automated to be

7.0.0/1 -- 0d0e0a1d8f paves the way future refactor none of this code is active

Later, when you want to make available and release this functionality, you have some options

8.0.0-rc.1 -- This replaces old code used with the work from 0d0e0a1d8f breaking the following functionality [...]
7.1.0-rc.1 -- This uses the code 0d0e0a1d8f to provide a new feature alongside the old functionality, deprecating the old functionality [...]
7.0.1-rc.1 -- This uses the code 0d0e0a1d8f to fix and issue I found in [...] which was too very muddy code

Ultimately you don't know where your commit (0d0e0a1d8f) will land and most build systems that use semantic-versioning have no guidance on how to handle this unknown state (npm/cargo/semantic-release etc). The key here is that 0d0e0a1d8f may need to be QA'd, and it may need a build and currently the convention supported by pre-release requires people to guess whether or not the code that they've just written will ultimately be used to

  • fix old code
  • provide a new feature
  • and if so, whether that feature will introduce a breaking change.

These are easier to determine when you decide to release and when you've satisfied the quality gates then when you're developing.

This new convention provided by Forward allows you to replace release-forethought which is very often sentimental even if the numbering scheme isn't, with ignorance.

Ordering

I'm not sure how Forward should be ordered except to say that if available it should come after the final-release.

1.2.3/2
1.2.3/1
1.2.3
1.2.3-rc.1

Not sure if the order should specify /2 coming after /1; or, if order should be simply undefined (which is not unprecedented the spec's build-metadata, denoted with a + prefix, is current undefined in ordering). Development is very often non-linear (happening in parallel) so it may be desirable to keep the ordering undefined.

Originally created by @EvanCarroll on GitHub (Oct 28, 2021). Original GitHub issue: https://github.com/semver/semver/issues/765 The spec assumes that pre-release is made on the final published version, $VERSION-$PRERELEASE This assumes you know what `$VERSION` will be as you progress with development and that your release is premediated. This is not ideal for modern agile development practices such as those espoused by `semantic-release`. As such, code in a broken state or not ready to ship but needing testing, versioning, building, and deployment is not supported by semantic-version. Suggested Fix ==== Currently semantic-version supports the following to delineate non-version data, * The `-` prefix for pre-release. * The `+` prefix for build metadata. By introducing a third unused character a forward-slash `/` (mnemonic Forward-Progress), we can mark a build as not-released and internal, but _more_ forward than the actual version. We can call this "Forward" Working Example ==== Let's say you decide to develop a new feature. The product your working on is currently at version 7.0.0 and your first commit is `0d0e0a1d8f`. This version number could be automated to be 7.0.0/1 -- 0d0e0a1d8f paves the way future refactor none of this code is active Later, when you want to make available and release this functionality, you have some options 8.0.0-rc.1 -- This replaces old code used with the work from 0d0e0a1d8f breaking the following functionality [...] 7.1.0-rc.1 -- This uses the code 0d0e0a1d8f to provide a new feature alongside the old functionality, deprecating the old functionality [...] 7.0.1-rc.1 -- This uses the code 0d0e0a1d8f to fix and issue I found in [...] which was too very muddy code Ultimately you don't know where your commit (`0d0e0a1d8f`) will land and most build systems that use semantic-versioning have no guidance on how to handle this unknown state (npm/cargo/semantic-release etc). The key here is that `0d0e0a1d8f` may **need** to be QA'd, and it may need a build and currently the convention supported by pre-release requires people to guess whether or not the code that they've just written will ultimately be used to * fix old code * provide a new feature * and if so, whether that feature will introduce a breaking change. These are easier to determine when you decide to release and when you've satisfied the quality gates then when you're developing. This new convention provided by Forward allows you to replace release-forethought which is very often [sentimental](http://sentimentalversioning.org/) even if the numbering scheme isn't, with ignorance. Ordering ==== I'm not sure how Forward should be ordered except to say that if available it should come after the final-release. ```text 1.2.3/2 1.2.3/1 1.2.3 1.2.3-rc.1 ``` Not sure if the order should specify `/2` coming after `/1`; or, if order should be simply undefined (which is not unprecedented the spec's build-metadata, denoted with a `+` prefix, is current undefined in ordering). Development is very often non-linear (happening in parallel) so it may be desirable to keep the ordering undefined.
Author
Owner

@jwdonahue commented on GitHub (Nov 29, 2021):

@EvanCarroll wrote:

The spec assumes that pre-release is made on the final published version,

I am unaware of any part of the spec that can be construed as making that assumption or requiring that in any way. The following history is perfectly legit SemVer:

  • 1.0.42-a.Dev.
  • 1.1.0-a.Dev.FeatureY
  • 1.1.0-rc
  • 1.1.1-rc
  • 2.0.0

The presence of a prerelease version in a package feed, in no way obligates anybody to ever issue any release version what-so-ever. Package feeds are littered with 0.y.z (prerelease) versions that can never morph into a release without a version change.

It seems that you are also trying to solve another pseudo problem w.r.t commits in a repository. You are assuming that it is a good or desired practice to commit version numbers to the source tree. Such a practice cannot scale well; to multiple developers, branches and build pipelines. Modifying the SemVer spec will not improve the prospects of such practices.

Instead, your developers should get in the habit of using semantic commit descriptions that clearly state whether the commit is a non-breaking fix, non-breaking feature addition, or breaking change. That is all that is required for a build system to determine what the next version number should be. While it may be convenient for the build system to tag the commit that it built the product from with the derived version, it is not necessary, if the commit hash is associated with that version number by other means (build meta, log or database).

You should also keep in mind that for a given commit hash, there can be multiple versions built, either as a product of the workflows or simply because multiple build machines produced output from the same commit hash at one time or another. Consider the case where one build agent is configured to produce instrumented output for the test lab telemetry system, while another constructs an RC candidate to be evaluated by security, legal, marketing or other teams. But this is not the venue for me to delve into these intricacies.

Given that there are few, if any, production build systems that are capable of building exactly the same bits twice in a row, even from exactly the same sources, and given that no two package content hashes should ever have the same name and version number on them, it is obvious that the version number should never come from the repo. Not even the commit hash is sufficient to uniquely version the output.

<!-- gh-comment-id:981289765 --> @jwdonahue commented on GitHub (Nov 29, 2021): @EvanCarroll wrote: > The spec assumes that pre-release is made on the final published version, I am unaware of any part of the spec that can be construed as making that assumption or requiring that in any way. The following history is perfectly legit SemVer: - 1.0.42-a.Dev. - 1.1.0-a.Dev.FeatureY - 1.1.0-rc - 1.1.1-rc - 2.0.0 The presence of a prerelease version in a package feed, in no way obligates anybody to ever issue any release version what-so-ever. Package feeds are littered with 0.y.z (prerelease) versions that can never morph into a release without a version change. It seems that you are also trying to solve another pseudo problem w.r.t commits in a repository. You are assuming that it is a good or desired practice to commit version numbers to the source tree. Such a practice cannot scale well; to multiple developers, branches and build pipelines. Modifying the SemVer spec will not improve the prospects of such practices. Instead, your developers should get in the habit of using semantic commit descriptions that clearly state whether the commit is a non-breaking fix, non-breaking feature addition, or breaking change. That is all that is required for a build system to determine what the next version number should be. While it may be convenient for the build system to tag the commit that it built the product from with the derived version, it is not necessary, if the commit hash is associated with that version number by other means (build meta, log or database). You should also keep in mind that for a given commit hash, there can be multiple versions built, either as a product of the workflows or simply because multiple build machines produced output from the same commit hash at one time or another. Consider the case where one build agent is configured to produce instrumented output for the test lab telemetry system, while another constructs an RC candidate to be evaluated by security, legal, marketing or other teams. But this is not the venue for me to delve into these intricacies. Given that there are few, if any, production build systems that are capable of building exactly the same bits twice in a row, even from exactly the same sources, and given that no two package content hashes should ever have the same name and version number on them, it is obvious that the version number should never come from the repo. **Not even the commit hash is sufficient to uniquely version the output**.
Author
Owner

@EvanCarroll commented on GitHub (Dec 23, 2021):

@jwdonahue it's under the sorting rules,

Pre-release versions have a lower precedence than the associated normal version.

And again,

  1. When major, minor, and patch are equal, a pre-release version has lower precedence than a normal version:

Example: 1.0.0-alpha < 1.0.0.

It's even in the name pre- release, (not post- release).

The problem with this is that -alpha comes before 1.0.0, but what if 1.0.0 is released and you're developing on something that may be 2.0.0 or 1.1.0 or 1.0.1. You're going to want a method for that to sort AFTER, 1.0.0, otherwise how will you create tooling that allows you to grab the latest version? How will you draw the distinction about the versions that came before 1.0.0 and the ones that represent development after the release of 1.0.0?

The question is more of how do we want to represent this with a version spec. I've given you the problem description.

The rest of what you're saying about development practices is all personal conjecture. If I have a method of reprsenting unreleased development before a specific release and that's good development practice, I should have a method of representing unreleased development after a specific release.

<!-- gh-comment-id:1000496369 --> @EvanCarroll commented on GitHub (Dec 23, 2021): @jwdonahue it's under the sorting rules, > Pre-release versions have a lower precedence than the associated normal version. And again, > 3. When major, minor, and patch are equal, **a pre-release version has lower precedence than a normal version:** > > Example: `1.0.0-alpha` < `1.0.0`. It's even in the name **pre-** release, (not **post-** release). The problem with this is that `-alpha` comes before `1.0.0`, but what if `1.0.0` is released and you're developing on something that may be `2.0.0` or `1.1.0` or `1.0.1`. You're going to want a method for that to sort _AFTER_, `1.0.0`, otherwise how will you create tooling that allows you to grab the _latest_ version? How will you draw the distinction about the versions that came before `1.0.0` and the ones that represent development _after_ the release of `1.0.0`? The question is more of how do we want to represent this with a version spec. I've given you the problem description. The rest of what you're saying about development practices is all personal conjecture. If I have a method of reprsenting unreleased development before a specific release and that's good development practice, I should have a method of representing unreleased development after a specific release.
Author
Owner

@jwdonahue commented on GitHub (Dec 24, 2021):

@EvanCarroll

what if 1.0.0 is released and you're developing on something that may be 2.0.0 or 1.1.0 or 1.0.1. You're going to want a method for that to sort AFTER, 1.0.0

No prerelease ever sorts after a release version. It's not safe and a post release doesn't change that. You either have a release quality publication or you don't.

Your best option is to start with 1.0.1-alpha and work until you know where you landed in the (1.0.0, 2.y.z] range. As long as -alpha is attached, all changes are potentially breaking, so you're not going to harm anybody that isn't willing to take a little risk. You could have a history like this:

1.0.0-alpha
1.0.0
1.0.1-alpha // Technically a post 1.0.0 prerelease.
1.0.2-alpha
1.0.2 // Decided those bug fixes should be released.
1.0.3-alpha.0 // Alternate counting scheme.
1.0.3-alpha.1
2.0.0-alpha // You had to break it, but you're still in prerelease and no idea where you'll land.
1.0.3-beta // Bug fixes cherry picked from dev into release branch.
1.0.4
2.1.0-alpha // etc.

Precedence rules define sort order, not how consumers chose a version to pull. Most tools will let you pull the highest X.Y.Z-alpha* that is visible on the feed. In the above history, we have a choice to pull the latest release of 1.0.4 or the highest prerelease version available. We could even limit what we pull to the [1.0.0-*, 2.0.0-*) range. With a good tool, you can chose between -beta or -alpha.

<!-- gh-comment-id:1000595404 --> @jwdonahue commented on GitHub (Dec 24, 2021): @EvanCarroll > what if 1.0.0 is released and you're developing on something that may be 2.0.0 or 1.1.0 or 1.0.1. You're going to want a method for that to sort AFTER, 1.0.0 No prerelease ever sorts after a release version. It's not safe and a post release doesn't change that. You either have a release quality publication or you don't. Your best option is to start with 1.0.1-alpha and work until you know where you landed in the (1.0.0, 2.y.z] range. As long as -alpha is attached, all changes are potentially breaking, so you're not going to harm anybody that isn't willing to take a little risk. You could have a history like this: 1.0.0-alpha 1.0.0 1.0.1-alpha // Technically a post 1.0.0 prerelease. 1.0.2-alpha 1.0.2 // Decided those bug fixes should be released. 1.0.3-alpha.0 // Alternate counting scheme. 1.0.3-alpha.1 2.0.0-alpha // You had to break it, but you're still in prerelease and no idea where you'll land. 1.0.3-beta // Bug fixes cherry picked from dev into release branch. 1.0.4 2.1.0-alpha // etc. Precedence rules define sort order, not how consumers chose a version to pull. Most tools will let you pull the highest X.Y.Z-alpha* that is visible on the feed. In the above history, we have a choice to pull the latest release of 1.0.4 or the highest prerelease version available. We could even limit what we pull to the `[1.0.0-*, 2.0.0-*)` range. With a good tool, you can chose between -beta or -alpha.
Author
Owner

@jwdonahue commented on GitHub (Dec 24, 2021):

@EvanCarroll

The key here is that 0d0e0a1d8f may need to be QA'd, and it may need a build and currently the convention supported by pre-release requires people to guess whether or not the code that they've just written will ultimately be used to

fix old code
provide a new feature
and if so, whether that feature will introduce a breaking change.

In fact, the prerelease tag is your ticket to make any kind of random changes you see fit to make:

#9 ... 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.

In other words, you can publish any kind of WIP without even testing it if that is what you need to do. The presence of the prerelease tag literally means "consumer beware, this version might be dangerous".

I think this perennial issue regarding "post release" forms of versioning stems from the pre-DevOps era practice of marking up version controlled source or configuration files, with a version number. If you let go of that practice and generate version numbers at build, release/publication, you'll find that you can get by just fine with prerelease tags and a sound understanding of how to use your tools to filter/select versions from your feeds/file-shares.

My personal preference for WIP that is published to internal feeds, is to tag it with a build number, prerelease tag (not SemVer) and build meta consisting of the repo hash value, build cluster/machine and some clues what build options were applied (was it instrumented? etc.). Apply QA to those outputs and when you have an acceptable one, publish using SemVer or other acceptable versioning scheme. That last step usually being a manual operation requiring lots of sign-offs.

<!-- gh-comment-id:1000604711 --> @jwdonahue commented on GitHub (Dec 24, 2021): @EvanCarroll > The key here is that 0d0e0a1d8f may need to be QA'd, and it may need a build and currently the convention supported by pre-release requires people to guess whether or not the code that they've just written will ultimately be used to >fix old code >provide a new feature >and if so, whether that feature will introduce a breaking change. In fact, the prerelease tag is your ticket to make any kind of random changes you see fit to make: > [#9](https://semver.org/#spec-item-9) ... 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. In other words, you can publish any kind of WIP without even testing it if that is what you need to do. The presence of the prerelease tag literally means "consumer beware, this version might be dangerous". I think this perennial issue regarding "post release" forms of versioning stems from the pre-DevOps era practice of marking up version controlled source or configuration files, with a version number. If you let go of that practice and generate version numbers at build, release/publication, you'll find that you can get by just fine with prerelease tags and a sound understanding of how to use your tools to filter/select versions from your feeds/file-shares. My personal preference for WIP that is published to internal feeds, is to tag it with a build number, prerelease tag (not SemVer) and build meta consisting of the repo hash value, build cluster/machine and some clues what build options were applied (was it instrumented? etc.). Apply QA to those outputs and when you have an acceptable one, publish using SemVer or other acceptable versioning scheme. That last step usually being a manual operation requiring lots of sign-offs.
Author
Owner

@EvanCarroll commented on GitHub (Dec 24, 2021):

You have a lot of words, but so many are unrelated to technical merits.

Precedence rules define sort order, not how consumers chose a version to pull.

That's not true, what do you think this does in a cargo.toml or package.json file,

[dependencies]
foo = "1"

It picks the latest version that sorts greater major version 1 that is known to not have breaking changes. That should include things developed after 1.0.0 but compatible to it. The version 1.0.0-rc1 would not get picked up, the proposed 1.0.0/dev1 would get picked up.

<!-- gh-comment-id:1000638757 --> @EvanCarroll commented on GitHub (Dec 24, 2021): You have a lot of words, but so many are unrelated to technical merits. > Precedence rules define sort order, not how consumers chose a version to pull. That's not true, what do you think this does in a `cargo.toml` or `package.json` file, ```toml [dependencies] foo = "1" ``` It picks the latest version that sorts greater major version 1 that is known to not have breaking changes. That _should_ include things developed after 1.0.0 but compatible to it. The version `1.0.0-rc1` would not get picked up, the proposed `1.0.0/dev1` would get picked up.
Author
Owner

@ljharb commented on GitHub (Dec 24, 2021):

The only way you could guarantee compatibility, is if you knew that the changes in the postrelease were patch or minor - in which case, you know which version it’s a prerelease for.

<!-- gh-comment-id:1000655097 --> @ljharb commented on GitHub (Dec 24, 2021): The only way you could guarantee compatibility, is if you knew that the changes in the postrelease were patch or minor - in which case, you know which version it’s a prerelease for.
Author
Owner

@jwdonahue commented on GitHub (Dec 24, 2021):

@EvanCarroll

foo = "1"

That is a selector or version filter. How it behaves is not defined by SemVer.

You are free to issue a PR for whatever language you propose. I doubt you'll find much support for it. There's been plenty of earlier "post release" proposals made, some of them actually issued a PR. Fact is that any change to allow post-release semantics of any kind would be a breaking change to the spec, and it is highly unlikely to be supported by any of the maintainers.

<!-- gh-comment-id:1000786903 --> @jwdonahue commented on GitHub (Dec 24, 2021): @EvanCarroll > foo = "1" That is a selector or version filter. How it behaves is not defined by SemVer. You are free to issue a PR for whatever language you propose. I doubt you'll find much support for it. There's been plenty of earlier "post release" proposals made, some of them actually issued a PR. Fact is that any change to allow post-release semantics of any kind would be a breaking change to the spec, and it is highly unlikely to be supported by any of the maintainers.
Author
Owner

@EvanCarroll commented on GitHub (Dec 24, 2021):

The only way you could guarantee compatibility, is if you knew that the changes in the postrelease were patch or minor - in which case, you know which version it’s a prerelease for.

I'm not sure what you mean by compatability but if the following conditions are ensured,

  • post-release and pre-releases are exclusive,
  • post-release comes before build-data

Then 1.2.3/1 is not valid semver at all now. And making it a valid version would not change the ordering on systems that predated it.

<!-- gh-comment-id:1000915831 --> @EvanCarroll commented on GitHub (Dec 24, 2021): > The only way you could guarantee compatibility, is if you knew that the changes in the postrelease were patch or minor - in which case, you know which version it’s a prerelease for. I'm not sure what you mean by compatability but if the following conditions are ensured, * post-release and pre-releases are exclusive, * post-release comes before build-data Then 1.2.3/1 is not valid semver at all now. And making it a valid version would not change the ordering on systems that predated it.
Author
Owner

@EvanCarroll commented on GitHub (Dec 24, 2021):

That is a selector or version filter. How it behaves is not defined by SemVer.

What are you even talking about? The whole purpose of semver is to establish version numbers so we know how one version relates to another version. It's pretty explicit (from the spec)

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

That precendence is what selectors depend on. It's what makes this project useful. This RFC allows you to have a corrolary to pre-release (which represents development before a release), but for after the actual release happens.

At this point I'm really having a hard time discerning any utility from your responses @jwdonahue.

<!-- gh-comment-id:1000916285 --> @EvanCarroll commented on GitHub (Dec 24, 2021): > That is a selector or version filter. How it behaves is not defined by SemVer. What are you even talking about? The whole purpose of semver is to establish version numbers so we know how one version relates to another version. It's pretty explicit (from the spec) > Precedence refers to how versions are compared to each other when ordered. That precendence is what selectors depend on. It's what makes this project useful. This RFC allows you to have a corrolary to pre-release (which represents development before a release), but for after the actual release happens. At this point I'm really having a hard time discerning any utility from your responses @jwdonahue.
Author
Owner

@ljharb commented on GitHub (Dec 24, 2021):

I’m saying that if you know that 1.2.3/1 is compatible with 1.2.3, then you also have precisely enough information to know whether it (currently) would be a prerelease for 1.2.4 or 1.3.0 - so why not use the existing, well-understood facility of prereleases and publish one?

<!-- gh-comment-id:1000919075 --> @ljharb commented on GitHub (Dec 24, 2021): I’m saying that if you know that 1.2.3/1 is compatible with 1.2.3, then you also have precisely enough information to know whether it (currently) would be a prerelease for 1.2.4 or 1.3.0 - so why not use the existing, well-understood facility of prereleases and publish one?
Author
Owner

@jwdonahue commented on GitHub (Dec 24, 2021):

@EvanCarroll SemVer specifies precedence rules that say V1 < V2. It does not define whether a consumer should select Min(Versions) or Max(Versions) or Predicate[x](Versions). Those functions may sort Versions prior to choosing a specific version to pull, but not all F(Versions) are sensitive to sort order. The spec simply provides the minimal set of rules required to order a set of versions when order is important. Package managers and other tools, layer additional conventions on top of the SemVer rules to make them useful within specific development environments.

Precisely what foo = "1" means, is defined by the tool that reads that configuration statement. Perhaps it means "give me package named foo version 1", which is not a SemVer version string, or perhaps it means "give me package named foo in the range of [1.0.0, 2.0.0)"? The later isn't particularly useful if you don't also define the predicate that selects from the set of available versions in that range. Most tools have a default selector of MinStable(r) or Max(r) in such cases.

Simply taking the latest in the set of all publicly available foo is generally not what anybody wants to do. We usually limit the range of acceptable versions and then apply some heuristics to select the best from that set for our purposes. Some of us want preleases, some want only releases.

Adding a "post-release" syntax will increase the complexity of SemVer compliant implementations without adding any apparent benefit. As you have proposed:

By introducing a third unused character a forward-slash / (mnemonic Forward-Progress), we can mark a build as not-released and internal, but more forward than the actual version. We can call this "Forward"

The "not-released and internal" implies it doesn't belong in the SemVer spec. You can use any versioning conventions you find useful in your internal processes. I've seen many uses of the 4 digit <SemVer Triple>.<BuildNumber> format used in internal schemes. SemVer is for labelling that which will be published and is not generally useful for internal development.

SemVer is unsuited for the kind of internal development where process actually matters, i.e.; multiple developers and development branches. Pure sort by date/timestamp, build number or any versioning scheme is virtually useless in a world where there are dozens of developers or teams working from different starting points in potentially different repos or branches in the code base and you have potentially thousands of build machines cranking away on those branches. No linear versioning scheme applies to such a messy, chaotic environment. The best you can hope for is to work towards a more manageable release cadence, heuristically selected from the bits that are ready to ship. You apply the appropriate SemVer version to the bits that you publish externally, not internally.

Many people have proposed similar breaking changes to the SemVer spec. There is a problem they want to solve and they think a change to the spec will automagically be taken up by the tool developers, or they are considering writing the tool themselves, but they think they'll have an easier time getting the required budget allocations if there is also movement in the psec. But that loop is slow compared to that which is implemented broadly and finds it's way into the spec.

Read the CONTRIBUTING.md file. Fork your favorite packaging tool and add your experimental feature. Then promote it, respond to feedback and when you think it's fully baked, write an RFC.

Good luck.

<!-- gh-comment-id:1000941071 --> @jwdonahue commented on GitHub (Dec 24, 2021): @EvanCarroll SemVer specifies precedence rules that say `V1 < V2`. It does not define whether a consumer should select `Min(Versions)` or `Max(Versions)` or `Predicate[x](Versions)`. Those functions may sort Versions prior to choosing a specific version to pull, but not all F(Versions) are sensitive to sort order. The spec simply provides the minimal set of rules required to order a set of versions when order is important. Package managers and other tools, layer additional conventions on top of the SemVer rules to make them useful within specific development environments. Precisely what `foo = "1"` means, is defined by the tool that reads that configuration statement. Perhaps it means "give me package named foo version 1", which is not a SemVer version string, or perhaps it means "give me package named foo in the range of [1.0.0, 2.0.0)"? The later isn't particularly useful if you don't also define the predicate that selects from the set of available versions in that range. Most tools have a default selector of `MinStable(r)` or `Max(r)` in such cases. Simply taking the latest in the set of all publicly available `foo` is generally not what anybody wants to do. We usually limit the range of acceptable versions and then apply some heuristics to select the best from that set for our purposes. Some of us want preleases, some want only releases. Adding a "post-release" syntax will increase the complexity of SemVer compliant implementations without adding any apparent benefit. As you have proposed: > By introducing a third unused character a forward-slash / (mnemonic Forward-Progress), we can mark a build as not-released and internal, but more forward than the actual version. We can call this "Forward" The "not-released and internal" implies it doesn't belong in the SemVer spec. You can use any versioning conventions you find useful in your internal processes. I've seen many uses of the 4 digit `<SemVer Triple>.<BuildNumber> `format used in internal schemes. SemVer is for labelling that which will be published and is not generally useful for internal development. SemVer is unsuited for the kind of internal development where process actually matters, i.e.; multiple developers and development branches. Pure sort by date/timestamp, build number or any versioning scheme is virtually useless in a world where there are dozens of developers or teams working from different starting points in potentially different repos or branches in the code base and you have potentially thousands of build machines cranking away on those branches. No linear versioning scheme applies to such a messy, chaotic environment. The best you can hope for is to work towards a more manageable release cadence, heuristically selected from the bits that are ready to ship. You apply the appropriate SemVer version to the bits that you publish externally, not internally. Many people have proposed similar breaking changes to the SemVer spec. There is a problem they want to solve and they think a change to the spec will automagically be taken up by the tool developers, or they are considering writing the tool themselves, but they think they'll have an easier time getting the required budget allocations if there is also movement in the psec. But that loop is slow compared to that which is implemented broadly and finds it's way into the spec. Read the [CONTRIBUTING.md](https://github.com/semver/semver/blob/master/CONTRIBUTING.md) file. Fork your favorite packaging tool and add your experimental feature. Then promote it, respond to feedback and when you think it's fully baked, write an RFC. Good luck.
Author
Owner

@EvanCarroll commented on GitHub (Dec 25, 2021):

@jwdonahue I would block you if I could, but I can't. It's not my intent to respond to you again. Not because you're bad guy, but I don't care about the non-technical objections. This isn't productive. You've got the last word on the matter. Thanks.

<!-- gh-comment-id:1000952375 --> @EvanCarroll commented on GitHub (Dec 25, 2021): @jwdonahue I would block you if I could, but I can't. It's not my intent to respond to you again. Not because you're bad guy, but I don't care about the non-technical objections. This isn't productive. You've got the last word on the matter. Thanks.
Author
Owner

@EvanCarroll commented on GitHub (Dec 25, 2021):

I’m saying that if you know that 1.2.3/1 is compatible with 1.2.3, then you also have precisely enough information to know whether it (currently) would be a prerelease for 1.2.4 or 1.3.0 - so why not use the existing, well-understood facility of prereleases and publish one?

@ljharb Ah, so you mean how would compatibilty be inferred between versions, rather than between between a version of semvar with and without such knowledge of forward-releases. I don't think it would work any different than pre-release currently does.

For example the spec says this,

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.

Why is that this couldn't also be said,

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

The only thing you're trying to maintain here is the ordinal significance that this came after the released version. I'm not trying to make it more useful than something that signifies the same thing that comes before it.

<!-- gh-comment-id:1000953222 --> @EvanCarroll commented on GitHub (Dec 25, 2021): > I’m saying that if you know that 1.2.3/1 is compatible with 1.2.3, then you also have precisely enough information to know whether it (currently) would be a prerelease for 1.2.4 or 1.3.0 - so why not use the existing, well-understood facility of prereleases and publish one? @ljharb Ah, so you mean how would compatibilty be inferred between versions, rather than between between a version of semvar with and without such knowledge of forward-releases. I don't think it would work any different than pre-release currently does. For example the [spec says this,](https://semver.org/) > 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. Why is that this couldn't also be said, > A post-release version indicates that the version is unstable and might not satisfy the intended compatibility requirements as denoted by its associated normal version. The only thing you're trying to maintain here is the ordinal significance that this came after the released version. I'm not trying to make it more useful than something that signifies the same thing that comes before it.
Author
Owner

@ljharb commented on GitHub (Dec 25, 2021):

Right - but “a prerelease for a version that comes after the released version” already conveys that information. Why do we need two ways to do so?

<!-- gh-comment-id:1000954800 --> @ljharb commented on GitHub (Dec 25, 2021): Right - but “a prerelease for a version that comes after the released version” already conveys that information. Why do we need two ways to do so?
Author
Owner

@jwdonahue commented on GitHub (Dec 25, 2021):

Well there's a first. I've never been accused of being non-technical before.

@EvanCarroll If I could silence everyone who disagrees with me, I'd be a happy camper too.

<!-- gh-comment-id:1000959017 --> @jwdonahue commented on GitHub (Dec 25, 2021): Well there's a first. I've never been accused of being non-technical before. @EvanCarroll If I could silence everyone who disagrees with me, I'd be a happy camper too.
Author
Owner

@jarphal commented on GitHub (Feb 25, 2022):

I need help

<!-- gh-comment-id:1051369775 --> @jarphal commented on GitHub (Feb 25, 2022): I need help
Author
Owner

@jarphal commented on GitHub (Feb 25, 2022):

Please help me with

<!-- gh-comment-id:1051369974 --> @jarphal commented on GitHub (Feb 25, 2022): Please help me with
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/semver#2242