目前我有一个发布管道,当我们准备发布一个包到一个私有的NPM
注册表时,这个管道会运行,这个管道有一些参数(比如版本号),用来在管道中完成以下操作:
- 更新
package.json
文件中的版本(使用npm version
) - 更新
package-lock.json
文件中的版本(使用npm version
) - 更新
CHANGELOG.md
- 添加带注解的
git
标记
然后提交这些更改,并使用以下PowerShell
代码段将其推送到源代码:
git switch -c $(Build.SourceBranchName)
# Stage all the changed files (only showing the staging of one file for brevity).
git add package.json
# The variable 'version' was supplied to the pipeline via a parameter.
git commit -m "chore(release): v$(version) [skip ci]"
# Push the changes to remote.
git push -u origin $(Build.SourceBranchName)
# Create the tag and push it to origin.
git tag "v$(version)" -a -m "chore(release): v$(version) [skip ci]"
git push origin "v$(version)"
我的担忧
我对checkout任务的理解是,它在运行管道时 checkout main
分支当前指向的提交,使我们处于分离头状态(这就是我在上面使用git switch
的原因)。
现在假设另一个开发人员创建了一个PR
,它在我的发布管道的最后阶段(我在这里执行上面的PowerShell
)之前被批准并与main
合并。
在这种情况下,我可能会遇到merge
冲突,或者(可能性更大)管道中的push
到origin
将与从PR
合并的任何更改合并,这意味着新的commit
实际上不会指向与发布的内容对应的object
图。
我想在我的情况下,我可以做以下之一:
1.创建一个release/v**
分支并将更改推送到那里(使标记无用)
1.确保运行释放管道时不接受PR
对于第一个选项(创建一个branch
版本),我不确定如何使用更改日志更新。
我很好奇在这种情况下我还有什么其他的选择?我也想知道我是不是在小题大做。
当更新软件包的版本和自动添加更改日志时,你们中的一些人会做什么?
请注意,NPM
的使用对该问题并不重要。
1条答案
按热度按时间qlvxas9a1#
将pipeline中所做的更改推至原点是否会导致问题?
不是你想的那样。
现在想象一下,另一个开发人员创建了一个PR,它在我的发布管道的最后阶段之前被批准并与
main
合并...在这种情况下,我可能会遇到合并冲突,或者(可能更有可能)管道中对origin
的推送将与PR中合并的任何更改合并。这是不可能的,您的
push
将失败,因为本地main
分支的尖端将与远程分支分叉(origin/main
)。发生这种情况时,您必须强制推送以清除远程更改(显然您不希望在main
这样的共享分支上执行此操作),或者您必须合并远程更改,然后再次尝试推送。后者可能是您在此场景中应该做的。因此,你面临的实际问题是,有时候你的渠道会出现故障。这里有几个潜在的解决方案:
1.您可以通过在推送之前先拉
main
来最大限度地降低失败的可能性。(在这种情况下,请确保使用默认的merge
而不是rebase
。如果你将新提交移到最新的origin/main
之上,那么你实际构建的内容将是错误的。考虑使用git pull --no-rebase
,以防拉取时配置被更改为偏好重定基。)注意在这短短的时间内仍然有可能(也许几秒钟),其他人仍然完成了 * 另一个 * PR到main
,但这种可能性通常相当低。如果你有太多的活动,甚至这还不够,你可以把它放入一个循环,比如说,5或10次尝试,在推送错误时,它会重试。在这种情况下,你可以做的一件巧妙的事情是,在循环中,在再次尝试拉(合并)之前,硬重置回你的构建生成的新提交。这样,即使需要5次尝试,你也只会有1次新的合并提交,而不是一行5次。1.一些repos会创建和标记与
main
分离的新提交。然后你只需要推送它就可以了,你根本不需要推送main
。这样做的好处是它不会失败,而且你不会因为大量的构建提交而污染main
。缺点是当你查看main
的历史记录时,你不能看到所有的构建。这使得回答"在main
上包含此更改的第一个构建版本是什么?"的问题变得稍微困难一些(在您的情况下,这可能根本不起作用,因为您的脚本更新了一个changelog文件,我认为该文件需要每个构建版本的历史记录)。1.完全避免进行新的提交,而只是标记在
main
上构建的提交。这通常涉及到一些构建号注入到过程中,这样你就不需要在代码中捕捉构建号的变化,并且main
上的标记足以知道构建中有什么。(同样,如果您需要将变更日志历史记录作为构建的一部分,这可能不起作用。1可能是您的情况下最容易实现的,您只需在步骤"#Push the changes to remote"之前向脚本添加一个
pull
调用即可。git push -u
,这意味着此时您的main
可能没有跟踪origin/main
。如果您决定使用pull
,但您还没有跟踪,则可以在脚本前面设置跟踪,或者可以将pull
替换为fetch
和merge
,如下所示: