git icon indicating copy to clipboard operation
git copied to clipboard

[feature request] : push tag on publish phase

Open r1m opened this issue 3 years ago • 5 comments

We have issues when a publish step fails : the tag is already pushed and then we cannot retry the release because semantic-release will consider the branch as behind.

Is it possible to push tag only on publish phase ?

r1m avatar Jan 02 '23 14:01 r1m

I have run into similar situations myself.

If it helps, I have some suggestions to offer.

  • I think that this plugin only pushes git commits, not git tags. I think semantic-release pushes tags.
  • There is a discussion that tries to talk about what happens when a release fails and a git tag has been pushed.

From looking into this quite a bit myself, it seems that semantic-release pushing a git tag in prepare step is a good thing. I deploy iOS libraries and when I do that, it actually requires that before I push to the production server, a git tag exists already. So, I will need a git tag pushed even though deploying the iOS library could still fail after I push the tag. In reading lots of semantic-release's docs, it mentions this design decision - some deployment processes requires a git tag before publishing.

I am doing some experimenting myself with automating what happens on a semantic-release failure. I am automating deleting the pushed git tag on failure so a re-run can occur. There are more pieces to this, but this is one important step to allow semantic-release to retry deploying.

Hope this helps.

levibostian avatar Jan 05 '23 18:01 levibostian

I can see why pushing tag on prepare can be useful. My biggest problem is that, in case of failure, the bump version commits of npm package and the tag are already pushed. Even if the failure was a temporary network issue I cannot retry the pipeline job because : 1. The tag already exists, 2. The current commit used for the pipeline is now behind.

So I have to delete the tag (and hope that no other systems already pulled it), rerun a full pipeline with tests and all. It will mess my history (two release commits with the same comment) unless I force push an older history (!).

So I was hoping for a way to configure this behaviour.

r1m avatar Jan 05 '23 19:01 r1m

I understand. I run into the same issues.

I can see how pushing a tag until publish would be a nice option for some workflows. But because it wouldn't work for all workflows, I wonder if there is another solution to the problem that would work for all types of workflows.

My current idea for how to solve this problem (may not be solved by this plugin, however).

  • The git commit made by this plugin that adds asset file changes (such as version change to package.json file) gets made to a temporary branch. The plugin waits to merge this branch until one of the last steps of the deployment process. That way, you don't have to worry about commits being made that you need to revert if the deployment fails.
  • On failed deploy, delete the pushed git tag. Sure, hopefully other systems have not pulled it. However, if you use the semantic-release/github plugin that makes a github release during the deployment process, you could setup your system to ignore when a git tag is pushed to github, and only pull a tag if there is a github release for that tag?

levibostian avatar Jan 09 '23 14:01 levibostian

I also run into similar issues. I have a Kotlin project which uses the gradle-semantic-release-plugin plugin which publishes at the publish step. I've configured Gradle to build when the publish command is called if a build isn't already present (this will be important later).

How my workflow is configured currently is it builds the project before semantic-release is called. This way if the build fails, no bumping commit is pushed.

The issue is this means that if I ever want to include version information from the gradle.properties file into my project, that would mean that my built JAR file would contain the previous version, and not the bumped one.

If I remove the build step part (because Gradle will build on publish step, if a build is not present), @semantic-release/git will push a commit even if the build fails, because it runs on the prepare lifecycle, and not publish.

I'm thinking about PR'ing a feature that allows the user to configure when @semantic-release/git should commit.

{
  "branches": ["main"]
  "plugins": [
    "gradle-semantic-release-plugin",
    [
      "@semantic-release/git",
      {
        "assets": ["build/"],
        "lifecycle": "publish"
      }
    ]
  ]
}

In this example, the gradle-semantic-release-plugin gets its publish lifecycle function ran first, then if it fails the @semantic-release/git plugin will not be run at all, no commits pushed.


To do this, I can expose some more lifecycles functions (not all, only the ones after prepare) and check the lifecycle option given in the config. If it's not specified, we can default it to "prepare" so this is not a breaking change but rather a feature change.

// src/index.js

export function publish(pluginConfig, context) {
  if (pluginConfig.lifecycle === "publish") prepare(pluginConfig, context)
}

PalmDevs avatar Apr 27 '23 03:04 PalmDevs

I created a discussion which pitches the idea of adding an option to semantic-release to push a git tag after the publish step. Since this is a similar issue, the discussion would benefit from contributing an upvote or commenting on the idea when you have a chance.

levibostian avatar Oct 13 '23 12:10 levibostian