如何修复在Github上具有向后标签版本的go发布版本?

huangapple go评论73阅读模式
英文:

How to fix go release versioning on Github that has backward tag version?

问题

我有一个发布到Github的Go模块。
一开始,我给它打了一个标签为v1.0.0,在我的主程序中直接从Github导入该模块时,它运行得很完美。

但是在下一个发布中,我将它的标签回退到了v0.1.1,因为我认为我的模块还不稳定(根据语义化版本规范,不稳定版本应以0.x.y开头)。

这在今天引发了一个问题,因为我使用了golint和这个工具,它显示go-mod-outdated。目前的版本是v0.5.x,在我使用lint和一些lint工具之前有很多发布版本。

有什么解决办法吗?

英文:

I have a go module release to Github.
At the beginning, I tagged it to v1.0.0
it was running perfectly on my main program importing that module directly from Github.

But on the next release, I've tagged it backward to v.0.1.1 because I think my module is not stable yet -> (based on semantic versioning unstable version must begin with 0.x.y).

This makes an issue today because I use golint and this tool, it says go-mod-outdated. Currently, the version is v0.5.x and there is a lot of release before it (before I use lint and some tool for lint)

Any ideas to fix it?

答案1

得分: 2

Semver方面的事情

根据语义化版本规范(semver),不稳定的较新版本可以通过连字符标记,如规范项9所述:

预发布版本可以在修补版本后附加连字符和一系列点分隔的标识符来表示。标识符只能包含ASCII字母数字和连字符[0-9A-Za-z-],不能是空的。数字标识符不能包含前导零。预发布版本的优先级低于相关的正常版本。预发布版本表示该版本不稳定,可能无法满足其相关正常版本所指定的兼容性要求。示例:1.0.0-alpha、1.0.0-alpha.1、1.0.0-0.3.7、1.0.0-x.7.z.92、1.0.0-x-y-z.。

因此,问题是你做了什么更改?如果你只是添加了一些功能,但没有对API进行任何破坏性更改,你应该将不稳定的发布标记为:v1.1.0-alpha.1。对不稳定版本的修复可以使用v1.1.0-alpha.2等标记。

如果你以一种破坏性的方式更改了包的API,发布应该标记为v2.0.0-alpha.1。对alpha版本的修复应该以相同的方式进行标记:增加-alpha后缀后的最后一位数字。

最后,如果你没有以任何方式更改API,也没有添加任何功能,那么你只需将版本标记为v1.0.1-alpha。基本上,这是标准的语义化版本规范。如果你处于这种特殊情况下,那么事实上你过早地将你的包标记为v1.0.0,因为推送补丁仍然会导致不稳定性。

你可以通过以下命令重新标记现有的v1.0.0版本:

# 检出要重新标记的版本
$ git checkout v1.0.0
# 使用所需的标记对版本进行标记
$ git tag v0.1.1
# 推送标记
# 如果你勇敢的话,可以直接使用 git push --tags,但这不是理想的做法
$ git push origin v0.1.1
# 现在删除错误的标记
$ git tag -d v1.0.0
# 远程删除标记
$ git push origin :refs/tags/v1.0.0

好了,GitHub仓库不再有v1.0.0标记。仓库的任何克隆可能仍然具有旧的标记,如果有人推送git push --tags,那么将恢复v1.0.0标记(这就是我说git push --tags不理想的原因)。如果你的包在外部使用,这就需要与所有包的用户进行沟通。

最后,向前看,你应该了解如何使用go mod处理版本(要点是:遵循语义化版本2.0,你应该没问题)。伪发布和预发布有特定的格式你应该使用

Golang(go mod)的特殊情况

一旦模块被标记和发布,它就存在了。你应该使用retract指令撤销一个错误的版本。

正如@bcmills在评论中指出的那样:retract指令仅适用于较新的版本。对于你的特殊情况(实际上是在版本v0.5.x上,但想要撤销发布v1.0.0),可以通过标记一个较新的版本并撤销它来解决:

retract (
    v1.0.0
    v1.0.1 // 发布撤销自身的新版本
)

从此时开始,你的包的最新版本将是未撤销的v0.5.x,你应该一切就绪。

要撤销你乐观地标记的发布。如果你将此发布重新标记为v0.1.0,那么你可以尝试使用replace指令。老实说,我从未使用过replace将模块的一个版本指向同一模块的另一个版本,但这可能值得一试:

replace (
    github.com/your/package v1.0.0 => github.com/your/package v0.1.0
)

我必须说:即使这样可以工作,它也是一种技巧,我不能保证它与新版本的你的包一起正常工作。我强烈建议你撤销v1.0.0标记,重新标记它(可以说v0.0.0是要使用的版本),从此时开始,遵循语义化版本和Golang预发布/伪发布版本的标准。

英文:

Semver side of things

According to semver, unstable more recent versions can be marked as such with a hyphen, as per spec item 9

> A pre-release version MAY be denoted by appending a hyphen and a series of dot separated identifiers immediately following the patch version. Identifiers MUST comprise only ASCII alphanumerics and hyphens [0-9A-Za-z-]. Identifiers MUST NOT be empty. Numeric identifiers MUST NOT include leading zeroes. Pre-release versions have a lower precedence than the associated normal version. 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. Examples: 1.0.0-alpha, 1.0.0-alpha.1, 1.0.0-0.3.7, 1.0.0-x.7.z.92, 1.0.0-x-y-z.–.

So the question here is what have you changed? If you've just added some features, but not introduced any breaking changes to the API, you should tag the unstable release as: v1.1.0-alpha.1. Fixes to the unstable release can then be tagged as v1.1.0-alpha.2 and so on.

If you've changed the API of your package in a breaking way, the release should be tagged as v2.0.0-alpha.1. Fixes to the alpha should be tagged in the same way as before: increasing the last digit after the -alpha suffix.

Lastly, if you've not changed the API in any way, nor added any features, then you just tag your version as being v1.0.1-alpha. Basically, standard semver stuff.<br>
Of course, if you're in this particular situation, then the truth is you've prematurely tagged your package as v1.0.0 prematurely, as pushing patches is still causing instability.

You can address/retag the existing v1.0.0 version by removing the tag, and tag that version accordingly. This can be easily done using the following commands:

# check out the version to re-tag
$ git checkout v1.0.0
# tag the version with the desired tag
$ git tag v0.1.1
# push the tag
# if you&#39;re brave, you could just git push --tags, but that&#39;s not ideal
$ git push origin v0.1.1
# now delete the offending tag
$ git tag -d v1.0.0
# remove the tag remotely
$ git push origin :refs/tags/v1.0.0

OK, the github repository no longer has the v1.0.0 tag. Any clone of the repository might still have the old tag, and if anyone there pushes git push --tags, that'll restore the v1.0.0 tag (hence my comment saying git push --tags is not ideal). If your package is being used in the wild, this requires some communication with all of the users of the package.

Lastly, moving forwards, you'd do well reading up on how go mod handles versions (the gist of it is: follow semver 2.0 and you should be fine). pseudo-releases and pre-releases have a particular format you should use

Golang (go mod) specifics

Once a module is tagged and released, it's out there. What you should do is issue a retraction of a broken version using the retract directive

As @bcmills kindly pointed out in the comments: the retract directive only works for later versions. The solution for your particular case (actually being on version v0.5.x, but wanting to retract release v1.0.0) can be done by tagging a later version and retracting it:

retract (
    v1.0.0
    v1.0.1 // the new version that issues the retraction retracts itself
)

From this point on, the latest version of your package that hasn't been retracted would be v0.5.x, and you should be all set.

To issue the retraction of your optimistically tagged release. If you've re-tagged this release as being, for example, v0.1.0, then you may be able to use the replace directive. I'll be honest, I've never used replace to point one version of my module to another version of the same module, but it's might be worth a shot:

replace (
    github.com/your/package v1.0.0 =&gt; github.com/your/package v0.1.0
)

I must say: even if this works, it's a hack, and I can't vouch for it playing nice with new versions of your package being released. I'd strongly recommend you to issue a retraction of the v1.0.0 tag, re-tag it (arguably v0.0.0 is the version to use here), and from this point on, follow the semver and golang pre-release/pseudo-release versioning standards.

huangapple
  • 本文由 发表于 2021年10月19日 17:35:01
  • 转载请务必保留本文链接:https://go.coder-hub.com/69628425.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定