我们有一个包含12个.net standard
项目的解决方案。这些项目中的每一个都以nuget package
的形式发布。现在我们正在尝试使CI/CD
流程自动化,因此我们需要一种方法(git command
)来查找已更改的项目文件(.csproj
),因此我们只能pack
该特定项目(已更改)将发布到nuget repo
,而不是解决方案中的所有项目。
答案 0 :(得分:0)
我们用于解决此问题的Azure DevOps构建管道(YAML)是(仅相关部分):
# Definition of tags which trigger this pipeline.
# Asterisk is for version number, so the real tag is for example "proj1-v1.1.0".
trigger:
tags:
include: [ 'proj1-v*', 'proj2-v*', 'proj3-v*' ]
... # Other not relevant config.
# Among standard variables such as "buildConfiguration" and others, we have these.
# The values of "project.ProjX" variables are basically real project names without ".csproj" extension.
# These are not so important, we just want to use variables later in the build steps.
variables:
- name: project.Proj1
value: 'Company.Proj1'
- name: project.Proj2
value: 'Company.Proj2'
- name: project.Proj3
value: 'Company.Proj3.Extensions'
# This is variable for holding project for which the build was triggered - the one which will be pushed to NuGet.
- name: 'project.Current'
value: ''
# This is special variable. Some of the projects does not have unit tests,
# but test step is failing if it does not find any assembly with tests.
# So we count relevant assemblies and run test step only if there is some.
- name: 'project.TestProjectsCount'
value: 0
steps:
# These steps sets "project.Current" variable to the project name based on the tag which triggerd the build.
# Based on condition, only one of these steps is executed.
- powershell: echo '##vso[task.setvariable variable=project.Current]$(project.Proj1)'
displayName: 'Set project: $(project.Proj1)'
condition: startsWith(variables['Build.SourceBranch'], 'refs/tags/proj1-v')
- powershell: echo '##vso[task.setvariable variable=project.Current]$(project.Proj2)'
displayName: 'Set project: $(project.Proj2)'
condition: startsWith(variables['Build.SourceBranch'], 'refs/tags/proj2-v')
- powershell: echo '##vso[task.setvariable variable=project.Current]$(project.Proj3)'
displayName: 'Set project: $(project.Proj3)'
condition: startsWith(variables['Build.SourceBranch'], 'refs/tags/proj3-v')
# This should not happen, but this step is executed when the pipeline is started with incorrect tag name: variable "project.Current" is empty.
# We print info what happened and the pipeline is stopped (exit 1).
- script: |
echo No project was specified.
echo Build must be triggered with correct tag and based on the tag name, the project is selected.
echo Available tag names and their projects:
echo - proj1-v* - Company.Proj1
echo - proj2-v* - Company.Proj2
echo - proj3-v* - Company.Proj3.Extensions
exit 1
displayName: 'Check project name'
condition: eq(variables['project.Current'], '')
... # General steps: nuget restore, build ...
# This step counts test assemblies relevant for current project (we do not want to run tests for other projects).
# Number of relevant test projects is set into "project.TestProjectsCount" variable.
- powershell: |
$count = 0
Get-ChildItem -Path "$env:System_DefaultWorkingDirectory" -Filter "$(project.Current)*test*.csproj" -Recurse -File | ForEach-Object {
$count = $count + 1
}
Write-Host Test projects found: $count
Write-Output ("##vso[task.setvariable variable=project.TestProjectsCount;]$count")
displayName: Find Test Projects
# Final steps, which operates only with relevant project "project.Current".
# - Run all tests for current project, but only if we have test assemblies (project.TestProjectsCount > 0).
# - Pack NuGet package.
# - Copy NuGet package to the staging folder.
# - Publish NuGet package.
- task: DotNetCoreCLI@2
displayName: 'Tests'
condition: gt(variables['project.TestProjectsCount'], 0)
inputs:
command: test
projects: '**/$(project.current)*[Tt]ests*.csproj'
- task: DotNetCoreCLI@2
displayName: 'Pack'
inputs:
command: pack
projects: '**/$(project.current).csproj'
- task: CopyFiles@2
displayName: 'Copy package files to staging directory'
inputs:
Contents: '**/$(project.current)*.nupkg'
TargetFolder: '$(build.artifactStagingDirectory)'
FlattenFolders: true
# This is our template for pushing to nuget.
# It just calls "nuget push" with correct parameters: feed URL, feed API key...
- template: steps/nuget-push.yml@templates
parameters:
feed: '$(nuget.feed)'
packages: '$(Build.ArtifactStagingDirectory)/$(project.Current)*.nupkg'