semantic-release: EINVALIDNEXTVERSION error when releasing a patch from maintenance branch

Current behavior

  • release a new version 1.0.0 from master branch
  • continue adding new features commits on master (like feat(module): ...) without releasing a new version from master branch
  • hotfix the previous version 1.0.0 to add a fix for 1.0.0 users. Here I cannot do the fix from master since I added new features on master and I don’t want them to be included in the fix. So I create a hotfix branch git checkout -b 1.0.x v1.0.0
  • push the fix on the 1.0.x branch and try to release a patch
  • semantic release raising the following error:
[semantic-release] › ✖  EINVALIDNEXTVERSION The release `1.0.1` on branch `1.0.x` cannot be published as it is out of range.
 Based on the releases published on other branches, only versions within the range >=1.0.0 <1.0.0 can be published from branch 1.0.x.
  • if I create a new version on master 1.1.0 and re-do the process described above, the hotfix release 1.0.1 is successfully be created from the 1.0.x hotfix branch

Expected behavior

I can continue adding new features on master since the last 1.0.0 release without being ready yet to release a new version. In the meantime, I might have the need to add a fix to the previously released version 1.0.0 but not from master to avoid including the newly added features. So I would like to be able to patch release 1.0.1 from the hotfix branch while the version on master is not incremented yet (latest release on master 1.0.0).

Environment

  • semantic-release version: 17.0.4
  • CI environment: Gitlab
  • Plugins used:
[
      "@semantic-release/commit-analyzer",
      "@semantic-release/release-notes-generator",
      "@semantic-release/changelog",
      "@semantic-release/npm",
      "@semantic-release/git"
 ]
  • semantic-release configuration: default settings
  • CI logs: [semantic-release] › ✖ EINVALIDNEXTVERSION The release 1.0.1 on branch 1.0.x cannot be published as it is out of range. Based on the releases published on other branches, only versions within the range >=1.0.0 <1.0.0 can be published from branch 1.0.x.

About this issue

  • Original URL
  • State: open
  • Created 4 years ago
  • Reactions: 23
  • Comments: 24 (1 by maintainers)

Most upvoted comments

I’ve encountered the same problem with different versions of semantic-release.

But I’ve I discovered that it only happens when you try to publish a new maintenance version from a maintenance branch that has been created from the last tag/HEAD of the release branch (master)

Reproducible case

In my config below, I have 3 branches:

  • develop: where the prereleases go -> 1.1.0-dev.0
  • master: where the releases go -> 1.0.0
  • A.B.x: where the maintenance releases go -> 1.0.1 (here is the problem)

image

As you can see in the previous git graph, I created the 1.0.x branch from the tag v1.0.0 in order to create maintenance releases. But when semantic releases is executed in this branch, it reports the EINVALIDNEXTVERSION error.

Important is to notice that this does not happen in the next case, which is basically the same scenario but when the maintenance doesn’t start anymore from the last tag/HEAD of release branch (master).

In this case, as you can see, a new 1.1.0 version has been published in master. So, when the maintenance version is released in 1.0.x there’s no problem anymore -> 1.0.1

Before releasing in 1.0.x

image

After releasing in 1.0.x -> 1.0.1 image

I believe that both scenarios are valid, since both are basically the same. But in case I’m wrong, could you point me out what would be incorrect?

Configuration

I’ll leave the details of my configuration below:

Environment

  • semantic-release version: 17.1.1 | 17.3.9 | 17.4.0
  • CI environment: Jenkins
  • Plugins used:
[
      "@semantic-release/commit-analyzer",
      "@semantic-release/release-notes-generator",
      "@semantic-release/npm",
      "@semantic-release/git"
 ]

I did other tests replacing "@semantic-release/git" and "@semantic-release/npm" with "@semantic-release/exec"

- semantic-release configuration (open for more defails)

{
  "branches":[
    {
      "name":"develop",
      "channel":"dev",
      "prerelease":"dev"
    },
    "master",
    {
      "name":"hotfix-+([0-9])?(.{+([0-9]),x}).x",
      "channel":"${name}",
      "prerelease":"hotfix"
    },
    {
      "name":"+([0-9])?(.{+([0-9]),x}).x",
      "channel":"${name}"
    }
  ],
  "plugins":[
    [
      "@semantic-release/commit-analyzer",
      {
        "preset":"conventionalcommits",
        "releaseRules":[
          {
            "type":"refactor",
            "release":"minor"
          },
          {
            "type":"build",
            "release":"patch"
          },
          {
            "type":"perf",
            "release":"patch"
          }
        ]
      }
    ],
    [
      "@semantic-release/release-notes-generator",
      {
        "preset":"conventionalcommits",
        "presetConfig":{
          "types":[
            {
              "type":"build",
              "section":"Build System"
            },
            {
              "type":"chore",
              "section":"Miscellaneous Chores"
            },
            {
              "type":"ci",
              "section":"Continuous Integration",
              "hidden":true
            },
            {
              "type":"docs",
              "section":"Documentation",
              "hidden":true
            },
            {
              "type":"feat",
              "section":"Features"
            },
            {
              "type":"fix",
              "section":"Bug Fixes"
            },
            {
              "type":"perf",
              "section":"Performance Improvements"
            },
            {
              "type":"refactor",
              "section":"Code Refactoring"
            },
            {
              "type":"revert",
              "section":"Reverts"
            },
            {
              "type":"style",
              "section":"Styles",
              "hidden":true
            },
            {
              "type":"test",
              "section":"Tests",
              "hidden":true
            }
          ]
        }
      }
    ]
  ]
}

- CI logs (open for more details):

✖ EINVALIDNEXTVERSION The release 1.0.1 on branch 1.0.x cannot be published as it is out of range

[5:20:27 PM] [semantic-release] › ℹ Running semantic-release version 17.1.1 [5:20:28 PM] [semantic-release] › ✔ Loaded plugin “verifyConditions” from “@semantic-release/exec” [5:20:28 PM] [semantic-release] › ✔ Loaded plugin “analyzeCommits” from “@semantic-release/commit-analyzer” [5:20:28 PM] [semantic-release] › ✔ Loaded plugin “analyzeCommits” from “@semantic-release/exec” [5:20:28 PM] [semantic-release] › ✔ Loaded plugin “verifyRelease” from “@semantic-release/exec” [5:20:28 PM] [semantic-release] › ✔ Loaded plugin “generateNotes” from “@semantic-release/release-notes-generator” [5:20:28 PM] [semantic-release] › ✔ Loaded plugin “generateNotes” from “@semantic-release/exec” [5:20:28 PM] [semantic-release] › ✔ Loaded plugin “prepare” from “@semantic-release/exec” [5:20:28 PM] [semantic-release] › ✔ Loaded plugin “publish” from “@semantic-release/exec” [5:20:28 PM] [semantic-release] › ✔ Loaded plugin “addChannel” from “@semantic-release/exec” [5:20:28 PM] [semantic-release] › ✔ Loaded plugin “success” from “@semantic-release/exec” [5:20:28 PM] [semantic-release] › ✔ Loaded plugin “fail” from “@semantic-release/exec” [5:20:28 PM] [semantic-release] › ⚠ This run was not triggered in a known CI environment, running in dry-run mode. [5:20:35 PM] [semantic-release] › ⚠ Run automated release from branch 1.0.x on repository miguel.cortecero.tor/semantic-release-test.git in dry-run mode [5:20:36 PM] [semantic-release] › ✔ Allowed to push to the Git repository [5:20:36 PM] [semantic-release] › ℹ Start step “verifyConditions” of plugin “@semantic-release/exec” [5:20:36 PM] [semantic-release] › ✔ Completed step “verifyConditions” of plugin “@semantic-release/exec” [5:20:36 PM] [semantic-release] › ℹ Found git tag v1.0.0 associated with version 1.0.0 on branch 1.0.x [5:20:36 PM] [semantic-release] › ℹ Found 2 commits since last release [5:20:36 PM] [semantic-release] › ℹ Start step “analyzeCommits” of plugin “@semantic-release/commit-analyzer” [5:20:36 PM] [semantic-release] [@semantic-release/commit-analyzer] › ℹ Analyzing commit: fix: change release preset to npm [5:20:36 PM] [semantic-release] [@semantic-release/commit-analyzer] › ℹ The release type for the commit is patch [5:20:36 PM] [semantic-release] [@semantic-release/commit-analyzer] › ℹ Analyzing commit: fix: this is a manteinance fix [5:20:36 PM] [semantic-release] [@semantic-release/commit-analyzer] › ℹ The release type for the commit is patch [5:20:36 PM] [semantic-release] [@semantic-release/commit-analyzer] › ℹ Analysis of 2 commits complete: patch release [5:20:36 PM] [semantic-release] › ✔ Completed step “analyzeCommits” of plugin “@semantic-release/commit-analyzer” [5:20:36 PM] [semantic-release] › ℹ Start step “analyzeCommits” of plugin “@semantic-release/exec” [5:20:36 PM] [semantic-release] › ✔ Completed step “analyzeCommits” of plugin “@semantic-release/exec” [5:20:36 PM] [semantic-release] › ℹ The next release version is 1.0.1 [5:20:36 PM] [semantic-release] › ⚠ Skip step “fail” of plugin “@semantic-release/exec” in dry-run mode [5:20:36 PM] [semantic-release] › ✖ EINVALIDNEXTVERSION The release 1.0.1 on branch 1.0.x cannot be published as it is out of range. Based on the releases published on other branches, only versions within the range >=1.0.0 <1.0.0 can be published from branch 1.0.x.

The following commits are responsible for the invalid release:

* fix: change release preset to npm (acba93f)
* fix: this is a manteinance fix (e627471)

Those commits should be moved to a valid branch with git merge (https://git-scm.com/docs/git-merge) or git cherry-pick (https://git-scm.com/docs/git-cherry-pick) and removed from branch 1.0.x with git revert (https://git-scm.com/docs/git-revert) or git reset (https://git-scm.com/docs/git-reset).

A valid branch could be master.

See the workflow configuration documentation (https://github.com/semantic-release/semantic-release/blob/master/docs/usage/workflow-configuration.md) for more details.

This was a great thread to read, and ultimately a show stopper for me. @Kehrlann comment above convinced me that this may never be a supported workflow for semantic-release. I’m not sure that @grv87 “semantic-release principle to release on each push” means that the workflow that this issue wants is unachievable. I am using gitversion now instead (https://gitversion.net/) My two cents are below - but i want to be 100% clear, like @Kehrlann i’m not suggesting this product changes as it’s doing lots already !

I believe there is an impedance between branching models and release workflows. This comes from an unclear definition of how version numbers will be reserved relating to release channels - and from the constraints around artifact repositories and git.

I’m working in an enterprise delivering internal and external software. These can be libraries and applications. It’s delivered through a sequence of stages or environments. Releases are to internal and external channels. Libraries builds are fully automated - but I’m not sure i should call that continuous deployment (one of many points that aren’t formal enough) - but otherwise we aim for continuous delivery - not continuous deployment.

We use githubflow, and oneflow as branching models https://www.abtasty.com/blog/git-branching-strategies/, https://www.endoflineblog.com/oneflow-a-git-branching-model-and-workflow - and are automating them, hence the investigation of semantic-release and gitversion. I aimed to use one of these two tools to automate the version numbering

Gitversions doco and tool revolves around the known branching models of githubflow and gitflow more. It has a couple of different strategies for calculating version numbers (branch name based) and config based, and commit based numbering is not quite as prominent. As a result these possibly allow for more strategies to

  • Reserve a version range ahead of time (without knowing that it will be a breaking change)
  • Retrospectively used a version or a version range (hotfix)
  • What are it’s version ranges (major minor patch, or include build/metadata). This in turn relates to being able to “Publish” a pre-release (to an internal channel). Interestingly this then depends on the nature of the repository for the channel - is it mutable (like snapshot repositories in maven), immutable for artifacts but mutable for tags (docker tags e.g latest), and how does it interpret versions (does it allow build numbers or ignore build metadata (nuget repostories)
  • How does it record a version - e.g do you throw away the pre-release part when you’ve arrived at your actual release ? e.g I’d like to stablise a release on a release branch, with each intermediate build getting a version like 1.1.0-prerelease1, … and then ultimately tag it 1.1.0 to record this version. This means the stablisation “fixes” shouldn’t consume patch numbers - this means we know it will be released every time to an internal channel, but we don’t know which build will be released to an external channel - so we can’t use the 1.1.0 version number ahead of time on the first build (hope this makes sense !). This relates to the distinction between continuos delivery and continuous deployment - a concept gitversion makes a bit more prominent.

So, oneflow and github flow model, that support stabilising before external releasing OR mainline fixes to prerelease channels with retrospective hotfixes aren’t easily compatible with choosing at commit time a major.minor.patch number. Since semantic release is really aiming to make version numbering strongly convention (unromantic), I’m not sure this can be easily reconciled !

I hope by introducing some of these terms that it might be possible to clarify what the limits of semantic release are and improve it’s doco. Since you might have arrived here like i did hoping to automate versioning on top of a branching model, that should also include how those limts relates to what branching model you can have.

The issue is still present on 19.0.x

I’ve made other tests with the configuration and the workflow that are described in the documentation (maintenance release and pre-releases) and I can replicate the problem. I’ve combined both recipes to have my use case, pretty similar to what @stratosgear said.

This is my current git graph

image

Branches

  • master: where 3.0.0 version was released
  • beta: where the next features are being developed (pre-release)
  • 3.0.x: where maintenance versions will be created for the 3.0.x users (maintenance)

What I would like to accomplish would be…

After releasing v3.0.0, I started adding new features to the beta branch for the future v3.1.0. But while I was developing these new features, a new bug was reported in the v3.0.0, so I created 3.0.x branch to fix it. In that branch, I added a commit "fix: maintenance fix" and pushed to the branch 3.0.x.

What I expected is that the version 3.0.1 would have been released in that branch. Instead I got the "EINVALIDNEXTVERION" error

image

I keep thinking that this should be a valid workflow. But if it’s not I’d appreciate some guidance 😉

It may or may not be a develop branch. That takes in a lot of assumptions. It is trunk. And the intention is to not have long-lived branches. At the same time, the project is not ready for continuous delivery.

Also does the “semantic-release principle to release on each push” mean that every release contains only single feature or fix (in its changelog)?

So my question is: can this scenario work? As an opt-in feature? You would remove the check and thrown error. My only concern is determining the next release on trunk after such hotfix.

@travi, could you please give some guidance on the situation (this issue and the open PR #1971)? Thank you!

I forgot to mention it here, but I created a PR with the possible fix for the workflow that I mentioned before. Just letting you know in case Github hasn’t sent a notification 😉

@mrmartan I think in this case, it does not matter if it’s a maintenance branch or hotfix branch, essencially is the same concept and the wrong behavior is present in both cases.

For example, try following the next steps. If you take exactly that state of your example and:

  1. Perform a release in the next branch. Lets say with a new feature: feat: add new feature
  2. It will release 6.6.0 version in that branch
  3. And if you try now to release the previous fix in your 6.5.x branch, a 6.5.1 will be released without that EINVALIDNEXTVERSION error.

That last step was not possible before having the 6.6.0 because of the bug.

From what I’ve seen, semantic-release isn’t able to release from maintenance/hotfix branches when:

  1. That maintenance/hotfix branch was created from the last tag/HEAD of the release branch
  2. And there hasn’t been released any new version still in that release branch since we create the maintenance/hotfix branch.

I don’t think this is a bug. I think this is rather a hotfix release feature request,

I am currently trying to implement just that on my project and I am running into this error.

image

Now I have new additions on my trunk (next branch) that I do not want to release just yet. I still need to publish a hotfix release 6.5.1 from branch 6.5.x (I could be cherry-picking the fix commit from trunk but that changes nothing).

I think this a different workflow to what maintenance branches of semantic-release offer.

EDIT: job log

[semantic-release] › ℹ  The next release version is 6.5.1
[semantic-release] › ✖  EINVALIDNEXTVERSION The release `6.5.1` on branch `6.5.x` cannot be published as it is out of range.
Based on the releases published on other branches, only versions within the range >=6.5.0 <6.5.0 can be published from branch 6.5.x.
The following commit is responsible for the invalid release:
    * fix: hotfix test commit (379277c)
This commit should be moved to a valid branch with git merge (https://git-scm.com/docs/git-merge) or git cherry-pick (https://git-scm.com/docs/git-cherry-pick) and removed from branch 6.5.x with git revert (https://git-scm.com/docs/git-revert) or git reset (https://git-scm.com/docs/git-reset).
A valid branch could be next.
See the workflow configuration documentation (https://github.com/semantic-release/semantic-release/blob/master/docs/usage/workflow-configuration.md) for more details.
SemanticReleaseError: The release `6.5.1` on branch `6.5.x` cannot be published as it is out of range.
    at module.exports (/node_modules/semantic-release/lib/get-error.js:6:10)
    at run (/node_modules/semantic-release/index.js:172:11)
    at processTicksAndRejections (internal/process/task_queues.js:93:5)
    at async module.exports (/node_modules/semantic-release/index.js:259:22)
    at async module.exports (/node_modules/semantic-release/cli.js:55:5) {
  code: 'EINVALIDNEXTVERSION',
  details: 'Based on the releases published on other branches, only versions within the range `>=6.5.0 <6.5.0` can be published from branch `6.5.x`.\n' +
    '\n' +
    'The following commit is responsible for the invalid release:\n' +
    '- fix: hotfix test commit (379277c)\n' +
    '\n' +
    'This commit should be moved to a valid branch with [git merge](https://git-scm.com/docs/git-merge) or [git cherry-pick](https://git-scm.com/docs/git-cherry-pick) and removed from branch `6.5.x` with [git revert](https://git-scm.com/docs/git-revert) or [git reset](https://git-scm.com/docs/git-reset).\n' +
    '\n' +
    'A valid branch could be `next`.\n' +
    '\n' +
    'See the [workflow configuration documentation](https://github.com/semantic-release/semantic-release/blob/master/docs/usage/workflow-configuration.md) for more details.',
  semanticRelease: true
}

it’s okay to ping me if you think I can help, thank you! I don’t have time to look more into it right now but I’ll get back to it eventually. Thanks for helping out!