无法在 Azure Pipelines 中重复模板
Unable to Repeat Template in Azure Pipelines
我有一个共享模板,我在我的 Azure 管道中引用它来构建、测试、打包和发布 C# nuget 包。
DotNet-BuildTestPackPublish.yml
parameters:
- name: project
type: string
default: ''
- name: dotnetVersion
type: string
default: '5.0.x'
- name: isNugetPackage
type: boolean
default: false
- name: isFirstProjectInRepo
type: boolean
default: true
steps:
- task: UseDotNet@2
displayName: 'Add .NET ${{parameters.dotnetVersion}}'
condition: and(succeeded(), eq(${{parameters.isFirstProjectInRepo}}, true))
inputs:
packageType: 'sdk'
version: ${{parameters.dotnetVersion}}
- task: NuGetAuthenticate@0
displayName: 'NuGet Auth'
condition: and(succeeded(), eq(${{parameters.isFirstProjectInRepo}}, true))
- checkout: self
persistCredentials: true
displayName: "Git Checkout"
condition: and(succeeded(), eq(${{parameters.isFirstProjectInRepo}}, true))
- task: DotNetCoreCLI@2
displayName: "Build"
inputs:
command: 'build'
projects: '**/*.sln'
- task: DotNetCoreCLI@2
displayName: Unit Test
inputs:
projects: '**/*.sln'
command: 'test'
- task: PowerShell@2
displayName: "Extract Version"
condition: and(succeeded(), eq(${{parameters.isNugetPackage}}, true), eq(variables['Build.SourceBranch'], 'refs/heads/main'))
inputs:
targetType: 'inline'
script: |
Write-Host "Locating Project Path..."
$input_path = (Get-ChildItem -Include ${{parameters.project}}.csproj -File -Recurse)
Write-Host "Project Path = $input_path"
Write-Host "Getting version from csproj..."
$regex = '(?<=<Version>).*?(?=<\/Version>)'
$version = Select-String -Path $input_path -Pattern $regex -AllMatches | % { $_.Matches } | % { $_.Value }
Write-Host "Version = $version"
if([string]::IsNullOrWhiteSpace($version))
{
Write-Host "Version not in csproj. Defaulting to 1.0.0"
$version = "1.0.0"
}
Write-Host "Getting Build Number from Environment"
$buildNumber = '$(Build.BuildId)'
Write-Host "Build Number = $buildNumber"
$versionAndBuildNumber = "$version+$buildNumber"
Write-Host "Package Version = $versionAndBuildNumber"
$tagText = "${{parameters.project}}+$version+$buildNumber"
Write-Host "Tag Text = $tagText"
Write-Output "##vso[task.setvariable variable=gitTag]$tagText"
Write-Output "##vso[task.setvariable variable=versionNumber]$versionAndBuildNumber"
- task: PublishSymbols@2
inputs:
searchPattern: '**/bin/**/${{parameters.project}}.pdb'
symbolServerType: "teamServices"
- task: DotNetCoreCLI@2
displayName: "Nuget Pack"
condition: and(succeeded(), eq(${{parameters.isNugetPackage}}, true), eq(variables['Build.SourceBranch'], 'refs/heads/main'))
inputs:
command: 'pack'
packagesToPack: '**/${{parameters.project}}.csproj'
versioningScheme: byEnvVar
versionEnvVar: versionNumber
includesymbols: true
includesource: true
- task: NuGetCommand@2
displayName: "Nuget Push"
condition: and(succeeded(), eq(${{parameters.isNugetPackage}}, true), eq(variables['Build.SourceBranch'], 'refs/heads/main'))
inputs:
command: 'push'
packagesToPush: '$(Build.ArtifactStagingDirectory)/**/*.nupkg'
nuGetFeedType: 'internal'
publishVstsFeed: 'Internal'
allowPackageConflicts: true
- script: |
echo Current Directory:
cd
dir /s
git tag $(gitTag)
git push --tags origin $(gitTag)
workingDirectory: $(Build.SourcesDirectory)
displayName: "Git Tag Repository"
condition: and(succeeded(), eq(${{parameters.isNugetPackage}}, true), eq(variables['Build.SourceBranch'], 'refs/heads/main'))
如果我的存储库中只有一个项目,这会很有效:
azure-pipelines.yml(只有一个项目)
trigger:
branches:
include:
- '*'
pool:
vmImage: 'windows-latest'
resources:
repositories:
- repository: BuildScripts
name: Feldryn/BuildScripts
type: git
ref: main
trigger:
- main
variables:
- group: 'Pipeline Shared Variables'
steps:
- template: DotNet-BuildTestPackPublish.yml@BuildScripts
parameters:
project: 'Daemon.Domain.RumbleRunners.Values'
isNugetPackage: true
# the following step is superfluous for this example, but it DOES work
- task: PowerShell@2
displayName: "Replace Project Reference with Nuget"
inputs:
targetType: 'inline'
script: |
cd Daemon.Domain.RumbleRunners
dotnet remove reference ..\Daemon.Domain.RumbleRunners.Values\Daemon.Domain.RumbleRunners.Values.csproj
dotnet add package Daemon.Domain.RumbleRunners.Values
cd..
一旦我尝试在同一管道中为另一个项目再次调用模板,第一个就会开始失败。
这行不通:
azure-pipelines.yml(两个项目)
trigger:
branches:
include:
- '*'
pool:
vmImage: 'windows-latest'
resources:
repositories:
- repository: BuildScripts
name: Feldryn/BuildScripts
type: git
ref: main
trigger:
- main
variables:
- group: 'Pipeline Shared Variables'
steps:
- template: DotNet-BuildTestPackPublish.yml@BuildScripts
parameters:
project: 'Daemon.Domain.RumbleRunners.Values'
isNugetPackage: true
- task: PowerShell@2
displayName: "Replace Project Reference with Nuget"
inputs:
targetType: 'inline'
script: |
cd Daemon.Domain.RumbleRunners
dotnet remove reference ..\Daemon.Domain.RumbleRunners.Values\Daemon.Domain.RumbleRunners.Values.csproj
dotnet add package Daemon.Domain.RumbleRunners.Values
cd..
# the inclusion of following step is the only change
- template: DotNet-BuildTestPackPublish.yml@BuildScripts
parameters:
project: 'Daemon.Domain.RumbleRunners'
isNugetPackage: true
isFirstProjectInRepo: false
尝试 git 标记第一个项目时失败并显示 'fatal: not a git repository (or any of the parent directories): .git'。
我做了一些故障排除并确定:
- 不是我的 git 标记步骤有问题。
- 只有一个项目时有效
- 如果我评论 git 标记步骤,则失败将转移到以下步骤。
- 新错误:在
D:\a\s\Daemon.Domain.RumbleRunners\
中找不到任何项目。
- 我已经输出了我的工作目录的内容,可以看到所有预期的文件都存在,包括 .git 文件夹
- 工作目录在工作和非工作方法之间没有区别。
我不知道如何进一步排除故障。
为什么我不能调用我的模板两次?这里发生了什么?
checkout
任务behaves differently when there are multiple checkouts:
- 当只有一个
checkout: self
步骤时,它会将存储库检出到 /home/vsts/work/1/s/
。
- 当有多个
checkout
个步骤时(即使它们引用同一个存储库),它将检出到 /home/vsts/work/1/s/{repository_name}
。
即使您在第二次结帐时有条件,该步骤仍然重要,因此第 2 点适用。
要验证这一点,请检查两种情况下 checkout
任务的日志。您还可以尝试最小的重现管道:
steps:
- checkout: self # <-- /home/vsts/work/1/s/
对
steps:
- checkout: self # <-- /home/vsts/work/1/s/{repo_name}/
- checkout: self # <-- /home/vsts/work/1/s/{repo_name}/
condition: false
我有一个共享模板,我在我的 Azure 管道中引用它来构建、测试、打包和发布 C# nuget 包。
DotNet-BuildTestPackPublish.yml
parameters:
- name: project
type: string
default: ''
- name: dotnetVersion
type: string
default: '5.0.x'
- name: isNugetPackage
type: boolean
default: false
- name: isFirstProjectInRepo
type: boolean
default: true
steps:
- task: UseDotNet@2
displayName: 'Add .NET ${{parameters.dotnetVersion}}'
condition: and(succeeded(), eq(${{parameters.isFirstProjectInRepo}}, true))
inputs:
packageType: 'sdk'
version: ${{parameters.dotnetVersion}}
- task: NuGetAuthenticate@0
displayName: 'NuGet Auth'
condition: and(succeeded(), eq(${{parameters.isFirstProjectInRepo}}, true))
- checkout: self
persistCredentials: true
displayName: "Git Checkout"
condition: and(succeeded(), eq(${{parameters.isFirstProjectInRepo}}, true))
- task: DotNetCoreCLI@2
displayName: "Build"
inputs:
command: 'build'
projects: '**/*.sln'
- task: DotNetCoreCLI@2
displayName: Unit Test
inputs:
projects: '**/*.sln'
command: 'test'
- task: PowerShell@2
displayName: "Extract Version"
condition: and(succeeded(), eq(${{parameters.isNugetPackage}}, true), eq(variables['Build.SourceBranch'], 'refs/heads/main'))
inputs:
targetType: 'inline'
script: |
Write-Host "Locating Project Path..."
$input_path = (Get-ChildItem -Include ${{parameters.project}}.csproj -File -Recurse)
Write-Host "Project Path = $input_path"
Write-Host "Getting version from csproj..."
$regex = '(?<=<Version>).*?(?=<\/Version>)'
$version = Select-String -Path $input_path -Pattern $regex -AllMatches | % { $_.Matches } | % { $_.Value }
Write-Host "Version = $version"
if([string]::IsNullOrWhiteSpace($version))
{
Write-Host "Version not in csproj. Defaulting to 1.0.0"
$version = "1.0.0"
}
Write-Host "Getting Build Number from Environment"
$buildNumber = '$(Build.BuildId)'
Write-Host "Build Number = $buildNumber"
$versionAndBuildNumber = "$version+$buildNumber"
Write-Host "Package Version = $versionAndBuildNumber"
$tagText = "${{parameters.project}}+$version+$buildNumber"
Write-Host "Tag Text = $tagText"
Write-Output "##vso[task.setvariable variable=gitTag]$tagText"
Write-Output "##vso[task.setvariable variable=versionNumber]$versionAndBuildNumber"
- task: PublishSymbols@2
inputs:
searchPattern: '**/bin/**/${{parameters.project}}.pdb'
symbolServerType: "teamServices"
- task: DotNetCoreCLI@2
displayName: "Nuget Pack"
condition: and(succeeded(), eq(${{parameters.isNugetPackage}}, true), eq(variables['Build.SourceBranch'], 'refs/heads/main'))
inputs:
command: 'pack'
packagesToPack: '**/${{parameters.project}}.csproj'
versioningScheme: byEnvVar
versionEnvVar: versionNumber
includesymbols: true
includesource: true
- task: NuGetCommand@2
displayName: "Nuget Push"
condition: and(succeeded(), eq(${{parameters.isNugetPackage}}, true), eq(variables['Build.SourceBranch'], 'refs/heads/main'))
inputs:
command: 'push'
packagesToPush: '$(Build.ArtifactStagingDirectory)/**/*.nupkg'
nuGetFeedType: 'internal'
publishVstsFeed: 'Internal'
allowPackageConflicts: true
- script: |
echo Current Directory:
cd
dir /s
git tag $(gitTag)
git push --tags origin $(gitTag)
workingDirectory: $(Build.SourcesDirectory)
displayName: "Git Tag Repository"
condition: and(succeeded(), eq(${{parameters.isNugetPackage}}, true), eq(variables['Build.SourceBranch'], 'refs/heads/main'))
如果我的存储库中只有一个项目,这会很有效:
azure-pipelines.yml(只有一个项目)
trigger:
branches:
include:
- '*'
pool:
vmImage: 'windows-latest'
resources:
repositories:
- repository: BuildScripts
name: Feldryn/BuildScripts
type: git
ref: main
trigger:
- main
variables:
- group: 'Pipeline Shared Variables'
steps:
- template: DotNet-BuildTestPackPublish.yml@BuildScripts
parameters:
project: 'Daemon.Domain.RumbleRunners.Values'
isNugetPackage: true
# the following step is superfluous for this example, but it DOES work
- task: PowerShell@2
displayName: "Replace Project Reference with Nuget"
inputs:
targetType: 'inline'
script: |
cd Daemon.Domain.RumbleRunners
dotnet remove reference ..\Daemon.Domain.RumbleRunners.Values\Daemon.Domain.RumbleRunners.Values.csproj
dotnet add package Daemon.Domain.RumbleRunners.Values
cd..
一旦我尝试在同一管道中为另一个项目再次调用模板,第一个就会开始失败。
这行不通: azure-pipelines.yml(两个项目)
trigger:
branches:
include:
- '*'
pool:
vmImage: 'windows-latest'
resources:
repositories:
- repository: BuildScripts
name: Feldryn/BuildScripts
type: git
ref: main
trigger:
- main
variables:
- group: 'Pipeline Shared Variables'
steps:
- template: DotNet-BuildTestPackPublish.yml@BuildScripts
parameters:
project: 'Daemon.Domain.RumbleRunners.Values'
isNugetPackage: true
- task: PowerShell@2
displayName: "Replace Project Reference with Nuget"
inputs:
targetType: 'inline'
script: |
cd Daemon.Domain.RumbleRunners
dotnet remove reference ..\Daemon.Domain.RumbleRunners.Values\Daemon.Domain.RumbleRunners.Values.csproj
dotnet add package Daemon.Domain.RumbleRunners.Values
cd..
# the inclusion of following step is the only change
- template: DotNet-BuildTestPackPublish.yml@BuildScripts
parameters:
project: 'Daemon.Domain.RumbleRunners'
isNugetPackage: true
isFirstProjectInRepo: false
尝试 git 标记第一个项目时失败并显示 'fatal: not a git repository (or any of the parent directories): .git'。
我做了一些故障排除并确定:
- 不是我的 git 标记步骤有问题。
- 只有一个项目时有效
- 如果我评论 git 标记步骤,则失败将转移到以下步骤。
- 新错误:在
D:\a\s\Daemon.Domain.RumbleRunners\
中找不到任何项目。
- 新错误:在
- 我已经输出了我的工作目录的内容,可以看到所有预期的文件都存在,包括 .git 文件夹
- 工作目录在工作和非工作方法之间没有区别。
我不知道如何进一步排除故障。
为什么我不能调用我的模板两次?这里发生了什么?
checkout
任务behaves differently when there are multiple checkouts:
- 当只有一个
checkout: self
步骤时,它会将存储库检出到/home/vsts/work/1/s/
。 - 当有多个
checkout
个步骤时(即使它们引用同一个存储库),它将检出到/home/vsts/work/1/s/{repository_name}
。
即使您在第二次结帐时有条件,该步骤仍然重要,因此第 2 点适用。
要验证这一点,请检查两种情况下 checkout
任务的日志。您还可以尝试最小的重现管道:
steps:
- checkout: self # <-- /home/vsts/work/1/s/
对
steps:
- checkout: self # <-- /home/vsts/work/1/s/{repo_name}/
- checkout: self # <-- /home/vsts/work/1/s/{repo_name}/
condition: false