semantic-release: The local branch master is behind the remote one, therefore a new version won't be published

Current behavior

I have a pipeline which is running for some time. It runss unit tests, it deploys the current commit into a test stage, it runs e2e against it and then waits for a manual approval.

When it is approved, semanic-release is started to build tag the version which should go into production.

When in the meantime there are new commits on the master branch, the manual approved version can not be deployed anymore as semantic release is throwing the following error:

The local branch master is behind the remote one, therefore a new version won’t be published

This comes from index.js: 68

if (!(await isBranchUpToDate(options.branch, {cwd, env}))) {
        logger.log(
          `The local branch ${options.branch} is behind the remote one, therefore a new version won't be published.`
        );
        return false;
      }

An every build which is not on the latest version of a branch semantic-release exits with the error explained above.

Expected behavior

In longer running pipelines or when a certain version is approved manually the execution of a deicated commit should not run in a failure but build this dedicated version.

Environment

  • semantic-release version:

@semantic-release/changelog”: “^3.0.4”, “@semantic-release/gitlab”: “^3.1.5”, “semantic-release”: “^15.13.16”, “semantic-release-slack-bot”: “^1.0.4”,

- CI environment: gitlab
- Plugins used: gitlab
- **semantic-release** configuration: 

branch: master plugins:

- CI logs:

[14:04:55] [semantic-release] › ℹ Running semantic-release version 15.13.16 [14:04:55] [semantic-release] › ✔ Loaded plugin “verifyConditions” from “@semantic-release/gitlab” [14:04:55] [semantic-release] › ✔ Loaded plugin “analyzeCommits” from “@semantic-release/commit-analyzer” [14:04:55] [semantic-release] › ✔ Loaded plugin “generateNotes” from “@semantic-release/release-notes-generator” [14:04:55] [semantic-release] › ✔ Loaded plugin “publish” from “@semantic-release/gitlab” [14:04:55] [semantic-release] › ✔ Run automated release from branch master [14:04:56] [semantic-release] › ℹ The local branch master is behind the remote one, therefore a new version won’t be published.

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Comments: 28 (12 by maintainers)

Commits related to this issue

Most upvoted comments

@pvdlg I’ve got a fairly simple use case where this is failing. I’ve added semantic-release to a large repo that has a lot of engineers contributing to it. Our CI is set to run only one build at a time and takes ~10 minutes to run. Since the repo is being committed to very often, the semantic-release step is very rarely up-to-date with the remote repo (there’s almost always a commit between the time the build is first kicked off and when the release step runs). Reading through the code, things don’t look hopeful, but is there any way to make semantic-release work with such an active repo?

Is there a method to error when you get “The local branch master is behind the remote one, therefore a new version won’t be published.” The rest of my pipeline needs to fail in this case.

@pvdlg Can you reopen this issue or should I create another one ?

I think answers were provided and it was explained why what you request is not possible, but I can further comment.

At the beginning of the pipeline, we use semantic-release in dry-run to get the next release version and use this version to build and publish our artifacts. Then, we run semantic-release again without dry-run to create the tag.

I don’t know why you do that, maybe working around some Jenkins limitation, but we won’t make any change to support that. The workflow we support is to run semantic-release to make the release from the release branch when a commit hit the branch. It’s not possible to publish your artifacts outside of semantic-release. If you want to do so you should look for another tool with a more limited scope.

Even if the next build would create a release with the two commits, our build fails because we end up trying to override our artifacts pushed with the same version by the previous build.

That’s related to the workflow you are using where you do a dry-run but still publish artifact. It’s not a semantic-release issue. Again I don’t know why you are doing that but that’s not the way semantic-release was meant to be used so we won’t make changes to accommodate that.

So I think it is a valid use case to have an option we can configure to allow semantic-release to push tags from a local branch behind the remote that would be disabled by default to keep the backward compatibility.

I don’t know what you refer to by backward compatibility. Doing so never really worked. It was allowed by mistake in certain limited cases.

@priyajeet I had the same problem. So to debug this I ran locally ./node_modules/.bin/semantic-release --dry-run and got an error that I trying to load status from wrong git-repository (hopefully I don’t have access rights):

{ Error: Command failed with exit code 128: git ls-remote --heads https://***.kz/packages/app-server.git
remote: HTTP Basic: Access denied

So I found that wrong repo was written in my package.json:

"repository": {
    "type": "git",
-    "url": "https://***.kz/packages/app-root.git"
+    "url": "https://***.kz/packages/app-server.git"
  },

We also hit that issue today as more of our teams are adopting semantic-release and continuous delivery.

Basically, we have a Jenkins pipeline that runs with disableConcurrentBuilds() on each commit to master branch to make sure we do not run two builds at the same time. At the beginning of the pipeline, we use semantic-release in dry-run to get the next release version and use this version to build and publish our artifacts. Then, we run semantic-release again without dry-run to create the tag and run other extensions. This workflow works for javaScript, Go, Maven, Gradle projects. We do not use semantic release to publish these artifacts since it does not support most of them.

Unfortunately, the run failed with The local branch master is behind the remote one, therefore a new version won't be published. because another pull request was merged during the build.

Even if the next build would create a release with the two commits, our build fails because we end up trying to override some of our artifacts pushed with the same version by the previous build.

We are also not using the @semantic-release/git plugin because our master branch is protected and pull request are enforced.

So I think it is a valid use case to have an option we can configure to allow semantic-release to push tags from a local branch behind the remote that would be disabled by default to keep the backward compatibility.

We currently have this issue. We only have 1 release job that runs, nothing parallel, at a certain time of the day. Nor does it write any new files back to the repo. But the builds take a while, so by the time semantic release tries to run, it fails because someone else pushed some new PR to the repo during that time. Wondering if a config or option could be added to ignore this.

I know this is closed, but I wanted to clarify for @pvdig:

What’s the difference if instead of 2 publishes within 8 minutes you get one that contains the commit of both?

By merging the changes it can complicate versioning for downstream users as well as make reverting things unnecessarily more complex at the commit level rather than tag level. More importantly, we just encountered a situation where a fix was running, and someone from another team released a feature.

I was robbed of my tag including only my fix, and now only have a version with both things combined. As you imply, this is a great feature. But for a downstream user who only wanted the fix and not the feature they are out of luck.

Oh man this is such a good point. 🤦‍♀ You are absolutely right, if in my case the other team had also done only a fix-level change, what versions would I expect?

That’s unpredictable. It would depends on the specific in which the repo is cloned and tags pushed.

Thinking it through, I think semantic-release would have to detect the tags and bump versions more and try again until it succeeds.

I don’t think so. There can be multiple reason for a tag conflict. Just assuming it’s due to a race condition and increasing the version is dangerous. In addition it can create the weird situation were a 1.0.1 and 1.0.2 can be created out of order from the git history perspective which would probably create other issues.

Overall I think it’s probably better to leave the code as is and to find external solution such as limiting the job that make the release to 1 concurrent instance if possible.

Thanks for the follow ups! That is great that I wasn’t too far off base from what is possible. It seems like we are on the right trail for a solution.

I think having to increase the API surface of plugins isn’t ideal, but having richer core-plugin communication could be beneficial and possibly enable plugin-plugin communication.

Another problem if we allow releases from outdated local branch is a possible race condition. If the last release on the branch is 1.0.0 and we merge to fix commits quickly then the 2 CI jobs will race each other and might both try to release 1.0.1 almost at the same time leaving you in a very difficult to solve situation.

Oh man this is such a good point. 🤦‍♀ You are absolutely right, if in my case the other team had also done only a fix-level change, what versions would I expect?

Thinking it through, I think semantic-release would have to detect the tags and bump versions more and try again until it succeeds.

For example: if we were at 1.0.0, my fix (assuming it was first) would become 1.0.1, and then their fix would race and try to do 1.0.1 but would detect 1.0.1 exists and then try 1.0.2.

(Versus the current behavior of my fix bailing after it encounters the newer commit. Then their fix includes mine and theirs in 1.0.1.)

I think it would still leave a failure case open, or at least a weird behavior, where different (more likely if more than 2) versions could race and potentially re-order themselves depending on the outcome of their racing. E.g. 1.0.0, my fix could become 1.0.1, but while their fix is determining to use 1.0.2, ANOTHER third fix could be determining to use 1.0.2 as well. One will likely reach git remote first, and In that case the remaining one could fail again and try to increment to 1.0.3 and try again and would succeed.

That might be acceptable, but definitely sounds gross. Like you say, the current sequential way avoids the whole mess altogether.

This is the intended behavior. There is many reasons for that but the main one is that some plugins can affect the repository on release, for example @sematnic-release/git create a new commit with the updated package.json and CHANGELOG.md. If the build is not running on the latest commit this would fail.

Even if semantic-release exit with this message, the following run will trigger the release. So instead of releasing 1.0.1 with commit X and then 1.0.2 with commit Y a few minutes later, you will just release 1.0.1 with both commits. How does that make a difference in your case?