我来自GitLab及其.gitlab-ci.yml,我正在尝试使用Azure DevOps多阶段管道,但是即使在{{3}阅读了几篇文档文章之后,我仍对它的工作原理和最佳策略感到困惑}
请允许我针对我正在尝试的基本场景提出几个相关问题,即编译,运行单元测试,打包整个解决方案的nuget包(它可能包含多个项目/ nuGet包),然后将包发布到nuGet提要(如果分支是master,则为发行版,否则为预发行版)。 这是我从中获取代码的存储库:https://docs.microsoft.com/en-us/azure/devops/pipelines/?view=azure-devops 它只会生成nuGet程序包,但我还有其他的多项目解决方案,应该会生成许多nuGet程序包
到目前为止,这是我的azure-pipelines.yml
:
trigger:
- master
- feature/*
pool:
vmImage: ubuntu-latest
variables:
NUGET_FOLDER_NAME: nupkgs
NUGET_REPOSITORY: https://whatever
PRERELEASE_SUFFIX: $(Build.BuildId)
PIpelINE_ARTIFact_NAME: $(Build.BuildNumber)
stages:
- stage:
displayName: 'Build'
jobs:
- job: 'Build'
steps:
- task: NuGetauthenticate@0
displayName: 'Authenticate in NuGet feed'
- script: dotnet restore --no-cache --force
displayName: 'Restore dependencies'
- script: dotnet build --configuration Release --no-restore
displayName: 'Build for Release'
- script: ls $(System.DefaultWorkingDirectory)
displayName: 'List content'
- publish: $(System.DefaultWorkingDirectory)
artifact: $(PIpelINE_ARTIFact_NAME)
- stage:
displayName: 'Automated Tests'
condition: succeeded()
jobs:
- job:
displayName: 'Unit Tests'
steps:
- download: current
artifact: $(PIpelINE_ARTIFact_NAME)
- script: ls -a
displayName: 'View'
- script: ls ./test
displayName: 'View test'
- script: ls ./test/Sasw.TestSupport.UnitTests
displayName: 'View folder'
- script: dotnet vstest test/*UnitTests/bin/Release/**/*UnitTests.dll
displayName: 'Run unit tests'
- stage:
displayName: 'NuGet Package'
condition: succeeded()
jobs:
- job:
displayName: 'Pack Preview Version'
condition: ne(variables['Build.SourceBranch'],'refs/heads/master')
steps:
- script: dotnet pack *.sln --configuration Release --output $(NUGET_FOLDER_NAME)
displayName: 'Pack'
- job:
displayName: 'Pack Stable Version'
condition: eq(variables['Build.SourceBranch'],'refs/heads/master')
steps:
- script: dotnet pack *.sln --configuration Release --output $(NUGET_FOLDER_NAME) --version-suffix $(PRERELEASE_SUFFIX) --include-source --include-symbols -p:SymbolPackageFormat=snupkg
displayName: 'Pack'
- 哪个是多阶段的“最佳”策略?我看到Azure DevOps管道具有“阶段”>“作业”>“任务”的概念,但它们看上去都与我相似。因此,我决定将流程划分为多个阶段,例如
Build - AutomatedTests - NuGet Package - Publish
如您所见,这是一个顺序过程,其中每个阶段都需要上一个阶段的内容。自动化测试需要构建的代码(dll),nuGet包也需要访问构建的代码,发布需要访问生成的nupkg,等等。我不知道遵循这种策略是否可以,还是最好一个具有多个任务的阶段,甚至一个具有多个任务的任务。正如我说的那样,我不完全了解拥有这么多概念的好处以及它们如何满足我的需求。 - Azure多级管道是否应该取代旧的Build和Release作为单独的概念?对我来说,将CI / CD放在一个地方并采用多阶段方法是有意义的,并且可以通过脚本编写使其在源代码控制存储库中进行版本控制。但是我仍然将发布概念视为当前在Azure DevOps上使用的单独概念。因此,大概我应该使用azure管道yml直到软件包“ step”,然后通过Release抓取该nupkg并将其发布到某些提要上。不确定会有什么好处。
- 我在将一个阶段的输出作为下一个阶段的输入时遇到问题,可能是因为我没有完全理解它。在上面的yml中,构建阶段成功,但是自动测试阶段的运行单元测试作业失败,错误为
No test source files were specified
。我验证了这种情况的发生,因为根本没有生成的文件夹bin
。因为我要复制上一阶段的所有内容(并且上一阶段使用dll生成bin文件夹),所以这似乎很奇怪,但是接下来的下一阶段,尽管能够下载所有内容,却找不到测试。
这是失败阶段的日志:https://github.com/sasw-diego/sasw-test-support
如果有人发现我缺少的东西以能够理解此过程,这将非常有帮助。任何澄清所有这些概念的链接将不胜感激。塔
PS:这是我在GitLab中使用的类似的通用CI / CD,用于将1个或多个nuGet上传到提要: https://gist.github.com/sasw-diego/df66eccf71bbfc044a4d72be96268c9a
更新: 感谢您的回答。我使用多阶段管道成功创建了一个CI / CD yml,它可以还原,构建,执行测试,运行容器(例如:eventStore主机)以对其进行集成测试,并释放nuGet in文物。任务完成了!我将其分为不同的阶段和工作,以探讨一些要点
trigger:
- master
- feature/*
pool:
vmImage: ubuntu-18.04
variables:
- group: sasw-common-variables
- name: NUGET_FOLDER_NAME
value: nupkgs
- name: PIpelINE_ARTIFact_NAME
value: $(Build.BuildNumber)
- name: PATH_PIpelINE_ARTIFact_NAME
value: $(Pipeline.Workspace)/$(PIpelINE_ARTIFact_NAME)
- name: NUGET_API_KEY
value: $(nuget-api-key)
- name: NUGET_FEED
value: $(nuget-feed)
- name: PRERELEASE_SUFFIX
value: $(nuget-prerelease-suffix)
resources:
containers:
- container: eventstore
image: eventstore/eventstore:release-5.0.2
ports:
- 1113:1113
env:
EVENTSTORE_INT_TCP_PORT: 1113
EVENTSTORE_EXT_TCP_PORT: 1113
EVENTSTORE_INT_HTTP_PORT: 2113
EVENTSTORE_EXT_HTTP_PORT: 2113
EVENTSTORE_EXT_HTTP_PREFIXES: http://*:2113/
stages:
- stage:
displayName: 'Build'
jobs:
- job: 'Build'
displayName: 'Build & Create nuGet Package'
services:
eventstore: eventstore
steps:
- task: NuGetauthenticate@0
displayName: 'Authenticate in NuGet feed'
- script: dotnet restore --no-cache --force
displayName: 'Restore dependencies'
- script: dotnet build --configuration Release --no-restore
displayName: 'Build with Release Configuration'
- script: dotnet vstest test/*UnitTests/bin/Release/**/*UnitTests.dll
displayName: 'Run unit tests'
- script: dotnet vstest test/*IntegrationTests/bin/Release/**/*IntegrationTests.dll
displayName: 'Run integration tests'
- script: dotnet pack *.sln --configuration Release --output $(NUGET_FOLDER_NAME)
condition: and(succeeded(),eq(variables['Build.SourceBranch'],'refs/heads/master'))
displayName: 'Create release nuGet'
- script: dotnet pack *.sln --configuration Release --output $(NUGET_FOLDER_NAME) --version-suffix $(PRERELEASE_SUFFIX) --include-source --include-symbols -p:SymbolPackageFormat=snupkg
condition: and(succeeded(),ne(variables['Build.SourceBranch'],'refs/heads/master'))
displayName: 'Create pre-release nuGet'
- publish: $(System.DefaultWorkingDirectory)/$(NUGET_FOLDER_NAME)
artifact: $(PIpelINE_ARTIFact_NAME)
displayName: 'Publish pipeline artifact'
- stage:
displayName: 'Release'
condition: succeeded()
jobs:
- job: 'Publish'
displayName: 'Publish nuGet Package'
steps:
- download: current
artifact: $(PIpelINE_ARTIFact_NAME)
displayName: 'Download pipeline artifact'
- script: ls $(PATH_PIpelINE_ARTIFact_NAME)
displayName: 'Display contents of downloaded articacts path'
- task: NuGetauthenticate@0
displayName: 'Authenticate in NuGet feed'
- task: UseDotNet@2
displayName: 'Use latest .NET Core sdk 3.x'
inputs:
packageType: sdk
version: 3.x
includePreviewVersions: true
installationPath: $(Agent.ToolsDirectory)/dotnet
- script: dotnet nuget push $(PATH_PIpelINE_ARTIFact_NAME)/**/*.nupkg --source $(NUGET_FEED) --api-key $(NUGET_API_KEY) --skip-duplicate
displayName: 'Uploads nuGet packages'