仅在项目已更改时创建 Nuget 包
Only create Nuget package if project has changed
给出的解决方案同时包含 Web Api 项目、Api 客户端项目和包含共享 Dto 对象的程序集项目,如下所示:
- 解决方案
- Web Api 项目
- 共享 Dto 项目
- Api 客户项目
- 单元测试
我有一个 Azure Devops 构建管道来构建和测试所有项目。
在该构建管道中,我有一个步骤为 Api 客户端和共享 Dto 项目创建 2 个 Nuget 包。
但是,我不需要一直创建新包,比如我只是添加了一个单元测试或修复了 Web Api 项目中的一个错误,我不想创建新包如果 Api 客户端项目(或其依赖项)中没有任何内容发生变化,Nuget 包(或担心会影响包版本),但我仍然想对其进行回归测试。
我想也许我可以通过多个构建管道来做到这一点,一个用于 Web Api 项目,另一个用于 Api 客户端和共享项目,然后使用路径过滤器来触发适当的构建。
还有其他方法可以实现吗?
最佳做法是什么?
我不想维护比我需要的更多的构建定义。
Are there any other ways to achieve this? Whats the best practice? I don't want to have to maintain more build definitions than I need.
有多种实现方式,但不确定哪种方式是最佳做法,这完全取决于您的要求或品味。
简单方法和你的想法差不多。还需要创建一个新的构建管道。不同的是我们不需要维护这个构建定义。
详情:
- 在此管道中添加一个没有任何任务的新管道,并使用
path
过滤器以触发适当的构建(Api 客户端和
共享 Dto 项目)。
- 将构建完成 添加到您的原始 Azure Devops 构建管道:
为基于Build.Reason
创建2个Nuget包的步骤添加一个custom condition,如:
and(succeeded(), eq(variables['Build.Reason'], 'BuildCompletion'))
现在,创建 2 个 Nuget 包的步骤仅在文件更改来自特定项目时执行。当然这个解决方案的局限性是,如果你已经有一个构建完成,它就不起作用了。
如果上述方法不是您想要的,我们可以调用 REST API commits 来获取每个构建的提交信息:
GET https://dev.azure.com/{organization}/{project}/_apis/git/repositories/{repositoryId}/commits/{commitId}?changeCount=100&api-version=5.1
我们可以在返回的正文中找到 changes/path:
"changes": [
{
"item": {
"gitObjectType": "blob",
"path": "/.gitattributes",
"url": "https://dev.azure.com/fabrikam/_apis/git/repositories/278d5cd2-584d-4b63-824a-2ba458937249/items/.gitattributes?versionType=Commit"
},
"changeType": "add"
},
{
"item": {
"gitObjectType": "blob",
"path": "/.gitignore",
"url": "https://dev.azure.com/fabrikam/_apis/git/repositories/278d5cd2-584d-4b63-824a-2ba458937249/items/.gitignore?versionType=Commit"
},
"changeType": "add"
},
{
"item": {
"gitObjectType": "tree",
"path": "/MyWebSite",
"isFolder": true,
"url": "https://dev.azure.com/fabrikam/_apis/git/repositories/278d5cd2-584d-4b63-824a-2ba458937249/items/MyWebSite?versionType=Commit"
},
"changeType": "add"
},
然后我们可以使用powershell脚本遍历这些路径,看是否包含ApiClient和Shared Dto项目,如果是,我们设置一个变量,并根据这个值添加条件用于创建 2 个 Nuget 包的步骤。
注意:在使用 REST API commits 之前,我们需要使用 Commits - Get Commits 来获取最新的提交 ID:
GET https://dev.azure.com/{organization}/{project}/_apis/git/repositories/{repositoryId}/commits?$top=1&api-version=5.1
希望这对您有所帮助。
我最终对
# Checks which files have been updated to determine if new Nuget packages are required
$editedFiles = git diff HEAD HEAD~ --name-only
echo "$($editedFiles.Length) files modified:"
$editedFiles | ForEach-Object {
echo $_
Switch -Wildcard ($_ ) {
'Whds.Configuration.Models/*' {
# If the Models project is updated, we need to create both packages
Write-Output "##vso[task.setvariable variable=CreateModelsPackage]True"
Write-Output "##vso[task.setvariable variable=CreateClientPackage]True"
}
'Whds.Configuration.Standard/*' { Write-Output "##vso[task.setvariable
variable=CreateClientPackage]True" }
# The rest of your path filters
}
}
此脚本设置变量,然后在构建管道的 dotnet pack 步骤中的自定义条件中引用这些变量:
and(succeeded(), eq(variables['CreateModelsPackage'], 'True'))
如果更改了 Dto 项目,则设置两个变量以创建两个包。
如果只有客户端(又名标准)项目发生了变化,则不会创建 Dto 项目的包。
给出的解决方案同时包含 Web Api 项目、Api 客户端项目和包含共享 Dto 对象的程序集项目,如下所示:
- 解决方案
- Web Api 项目
- 共享 Dto 项目
- Api 客户项目
- 单元测试
我有一个 Azure Devops 构建管道来构建和测试所有项目。 在该构建管道中,我有一个步骤为 Api 客户端和共享 Dto 项目创建 2 个 Nuget 包。
但是,我不需要一直创建新包,比如我只是添加了一个单元测试或修复了 Web Api 项目中的一个错误,我不想创建新包如果 Api 客户端项目(或其依赖项)中没有任何内容发生变化,Nuget 包(或担心会影响包版本),但我仍然想对其进行回归测试。
我想也许我可以通过多个构建管道来做到这一点,一个用于 Web Api 项目,另一个用于 Api 客户端和共享项目,然后使用路径过滤器来触发适当的构建。
还有其他方法可以实现吗? 最佳做法是什么? 我不想维护比我需要的更多的构建定义。
Are there any other ways to achieve this? Whats the best practice? I don't want to have to maintain more build definitions than I need.
有多种实现方式,但不确定哪种方式是最佳做法,这完全取决于您的要求或品味。
简单方法和你的想法差不多。还需要创建一个新的构建管道。不同的是我们不需要维护这个构建定义。
详情:
- 在此管道中添加一个没有任何任务的新管道,并使用
path
过滤器以触发适当的构建(Api 客户端和 共享 Dto 项目)。 - 将构建完成 添加到您的原始 Azure Devops 构建管道:
为基于
Build.Reason
创建2个Nuget包的步骤添加一个custom condition,如:and(succeeded(), eq(variables['Build.Reason'], 'BuildCompletion'))
现在,创建 2 个 Nuget 包的步骤仅在文件更改来自特定项目时执行。当然这个解决方案的局限性是,如果你已经有一个构建完成,它就不起作用了。
如果上述方法不是您想要的,我们可以调用 REST API commits 来获取每个构建的提交信息:
GET https://dev.azure.com/{organization}/{project}/_apis/git/repositories/{repositoryId}/commits/{commitId}?changeCount=100&api-version=5.1
我们可以在返回的正文中找到 changes/path:
"changes": [
{
"item": {
"gitObjectType": "blob",
"path": "/.gitattributes",
"url": "https://dev.azure.com/fabrikam/_apis/git/repositories/278d5cd2-584d-4b63-824a-2ba458937249/items/.gitattributes?versionType=Commit"
},
"changeType": "add"
},
{
"item": {
"gitObjectType": "blob",
"path": "/.gitignore",
"url": "https://dev.azure.com/fabrikam/_apis/git/repositories/278d5cd2-584d-4b63-824a-2ba458937249/items/.gitignore?versionType=Commit"
},
"changeType": "add"
},
{
"item": {
"gitObjectType": "tree",
"path": "/MyWebSite",
"isFolder": true,
"url": "https://dev.azure.com/fabrikam/_apis/git/repositories/278d5cd2-584d-4b63-824a-2ba458937249/items/MyWebSite?versionType=Commit"
},
"changeType": "add"
},
然后我们可以使用powershell脚本遍历这些路径,看是否包含ApiClient和Shared Dto项目,如果是,我们设置一个变量,并根据这个值添加条件用于创建 2 个 Nuget 包的步骤。
注意:在使用 REST API commits 之前,我们需要使用 Commits - Get Commits 来获取最新的提交 ID:
GET https://dev.azure.com/{organization}/{project}/_apis/git/repositories/{repositoryId}/commits?$top=1&api-version=5.1
希望这对您有所帮助。
我最终对
# Checks which files have been updated to determine if new Nuget packages are required
$editedFiles = git diff HEAD HEAD~ --name-only
echo "$($editedFiles.Length) files modified:"
$editedFiles | ForEach-Object {
echo $_
Switch -Wildcard ($_ ) {
'Whds.Configuration.Models/*' {
# If the Models project is updated, we need to create both packages
Write-Output "##vso[task.setvariable variable=CreateModelsPackage]True"
Write-Output "##vso[task.setvariable variable=CreateClientPackage]True"
}
'Whds.Configuration.Standard/*' { Write-Output "##vso[task.setvariable
variable=CreateClientPackage]True" }
# The rest of your path filters
}
}
此脚本设置变量,然后在构建管道的 dotnet pack 步骤中的自定义条件中引用这些变量:
and(succeeded(), eq(variables['CreateModelsPackage'], 'True'))
如果更改了 Dto 项目,则设置两个变量以创建两个包。 如果只有客户端(又名标准)项目发生了变化,则不会创建 Dto 项目的包。