git 将pipeline中所做的更改推至原点是否会导致问题?

v8wbuo2f  于 2023-02-28  发布在  Git
关注(0)|答案(1)|浏览(137)

目前我有一个发布管道,当我们准备发布一个包到一个私有的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冲突,或者(可能性更大)管道中的pushorigin将与从PR合并的任何更改合并,这意味着新的commit实际上不会指向与发布的内容对应的object图。
我想在我的情况下,我可以做以下之一:
1.创建一个release/v**分支并将更改推送到那里(使标记无用)
1.确保运行释放管道时不接受PR
对于第一个选项(创建一个branch版本),我不确定如何使用更改日志更新。
我很好奇在这种情况下我还有什么其他的选择?我也想知道我是不是在小题大做。
当更新软件包的版本和自动添加更改日志时,你们中的一些人会做什么?
请注意,NPM的使用对该问题并不重要。

qlvxas9a

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替换为fetchmerge,如下所示:
git fetch
git merge origin/main
# Push the changes to remote.
git push -u origin $(Build.SourceBranchName)

相关问题