仅当 tfs 构建中的版本更改时 npm 发布

Only npm publish when version changes in tfs build

我创建了一个发布到 Azure Artifacts 的私有 npm 包。为了发布我的 npm 包,我在我的 tfs 构建定义中有一个 npm 发布步骤。我使用的是 tfs 版本 16.131.28507.4.

这一切都按预期进行。但是,如果在 npm 包版本未更改的情况下触发构建,则 npm 发布将失败并显示 403 禁止。此错误导致我的其余构建失败。 npm 包是一个更大项目的一部分,因此在 npm 包未更改的情况下进行构建的情况并不少见。

如果我的包提要中的当前版本与包中指定的版本相同,是否可以阻止从 运行 执行 npm publish 的 tfs 构建步骤 json?

我知道构建步骤中的 "Custom Conditions",但不确定如何 link Azure Artifacts 当前发布的版本与我 package.json 中的版本。我也知道构建定义中的 "Continue on Error" 选项,但这会创建一个部分成功的构建,我想在这种情况下避免这种情况。

If a build is triggered where the npm package version is unchanged the npm publish will fail with a 403 forbidden.

这是预期的行为。因为你的包 name/version 没有改变。具有该名称的包之前已发布,因此您需要在 package.json 文件中使用不同的名称,然后再次 npm 发布。

在你的情况下,最简单的解决方案是更新你的 npm 包的最低版本,即使没有任何改变。正如您所指出的,另一个是在构建定义中使用 "Continue on Error" 选项,但这会创建部分成功的构建。

我们没有任何带有 Azure Artifacts 的内置 settings/configurations,或者 npm 任务可以判断您的包 feed 中的当前版本是否与包 json 中指定的版本相同。

而且对于客户的情况,我们也没有提供这样的表达来控制这个任务什么时候应该运行。为此,你可以看看这个官方link--Conditions.

另一种解决方法应该是分离您的构建管道,一个用于构建某些东西,npm 发布包。一个用于构建某些东西,请在 azure 包提要中引用你的 npm 包。如果您希望每次 npm 版本更改时自动触发第二次构建。您可以使用 Trigger Build Task 链接构建。

这是我们当前在将包发布到 Azure Artifacts 时在 Azure Pipelines 中使用的解决方案。

首先,将当前构建的包版本与所有已发布的版本进行比较,并设置变量以供其他任务使用:

- bash:
        PACKAGE_VERSION="$(node -p -e "require('./package.json').version")"
        PACKAGE_NAME="$(node -p -e "require('./package.json').name")"

        FOUND_VERSION=$(npm view $PACKAGE_NAME versions | grep \'$VERSION\')
        
        if $FOUND_VERSION
        then
            IS_NEW_VERSION=true
        fi

        echo "##vso[task.setvariable variable=IS_NEW_VERSION]$IS_NEW_VERSION"

请注意,我们使用 npm view <package-name> versions,而不仅仅是 version。这是为了确保我们获得所有已发布的版本,而不仅仅是最新版本。

然后执行您需要执行的操作以发布新版本、构建新版本等

然后,仅当 $IS_NEW_VERSIONtrue 时才发布:

- bash: |
        npm publish
  displayName: 'Publish NPM package'
  condition: and(not(failed()), eq(variables.IS_NEW_VERSION, 'true'))

也许有点蛮力,bash 脚本当然可以精简或改进,但它们可以完成工作。