You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Azure DevOps多阶段Pipeline迁移咨询与问题排查

Let’s work through your Azure DevOps Pipeline questions step by step, based on your transition from GitLab CI and the progress you’ve already made.

1. Fixing the "No test source files were specified" Error

This error typically boils down to one of two issues: either your test task isn’t looking in the right place for compiled test assemblies, or your build and test steps are running in separate jobs without sharing artifacts. Here’s how to resolve it:

  • Keep build and test in the same job (simplest fix): If you run dotnet build and dotnet test in the same job, they’ll share the same filesystem, so the test task can automatically find the compiled bin directories. Just make sure your build task doesn’t clean up output files before testing runs.
  • Adjust test task pathing: If you need separate jobs, first publish your build artifacts in the build job, then download them in the test job. For the test task itself, explicitly target your test assemblies with patterns that exclude irrelevant files:
    - task: VSTest@2
      inputs:
        testAssemblyVer2: |
          **/*Tests.dll
          !**/obj/**
          !**/bin/**/*TestAdapter.dll
        searchFolder: '$(System.DefaultWorkingDirectory)'
    
  • Specify build output directory: When running dotnet build, use the --output flag to send binaries to a predictable location (like $(Build.ArtifactStagingDirectory)/bin), then point your test task to that folder.
2. Stage > Job > Task Hierarchy & Build/Release Separation

Let’s clarify the hierarchy and how it compares to GitLab CI and traditional Azure DevOps Build/Release pipelines:

  • Stage: Think of this as a high-level phase of your pipeline (e.g., Build, Test, Package, Release). Stages are independent and can be set to run sequentially or in parallel, with dependencies (e.g., Release only runs if Test passes).
  • Job: A job is a set of tasks that run on a single agent (virtual machine or container). Jobs in the same stage share nothing by default—if you need to pass files between jobs, you have to use artifacts. This is similar to GitLab CI’s jobs section.
  • Task: The smallest unit of work—individual commands like dotnet build, NuGet pack, or running tests. Tasks are grouped into jobs.

As for replacing the old Build/Release separation:

  • You absolutely can use multi-stage pipelines to replace the separate Build and Release pipelines. This keeps your entire CI/CD workflow in a single, version-controlled YAML file, which is easier to maintain than managing two separate pipelines.
  • If you prefer to keep them separated (e.g., for legacy workflows), you can still do that: use a Build pipeline to compile, test, and package artifacts, then a Release pipeline to pull those artifacts and publish to NuGet based on the branch. But multi-stage pipelines are the modern, recommended approach.
3. Confirming Your Full CI/CD Pipeline (Integration Tests + Containerization)

Now that you’ve expanded to include integration tests and container services, here are key checks to validate your setup:

  • Branch-based versioning: Ensure master branch produces official NuGet versions (e.g., semantic versions like 1.2.3) while other branches generate pre-release versions (e.g., 1.2.3-preview.456). You can automate this with a PowerShell task to set a version variable:
    - task: PowerShell@2
      inputs:
        targetType: 'inline'
        script: |
          $branchName = "$(Build.SourceBranchName)"
          $buildId = "$(Build.BuildId)"
          if ($branchName -eq "master") {
            $nugetVersion = "1.0.$buildId"
          } else {
            $nugetVersion = "1.0.$buildId-preview"
          }
          Write-Host "##vso[task.setvariable variable=NuGetVersion]$nugetVersion"
    
  • Integration test dependencies: If your integration tests rely on external services (like databases), use Azure DevOps Service Connections to access them, or spin up containerized versions of those services directly in your pipeline job (e.g., with the DockerCompose@0 task to start a test database).
  • Container image tagging: Tag your container images based on the branch—use latest for master builds, and a preview tag (like preview-$(Build.BuildId)) for other branches to avoid overwriting production images.
  • Conditional NuGet publishing: Use Azure DevOps conditions to push to the correct NuGet feed based on the branch. For example:
    # Publish to official feed for master
    - task: NuGetCommand@2
      inputs:
        command: 'push'
        packagesToPush: '$(Build.ArtifactStagingDirectory)/**/*.nupkg;!$(Build.ArtifactStagingDirectory)/**/*.symbols.nupkg'
        nuGetFeedType: 'external'
        publishFeedCredentials: 'Official-NuGet-Feed'
        versioningScheme: 'byEnvVar'
        versionEnvVar: 'NuGetVersion'
      condition: eq(variables['Build.SourceBranchName'], 'master')
    
    # Publish to preview feed for non-master branches
    - task: NuGetCommand@2
      inputs:
        command: 'push'
        packagesToPush: '$(Build.ArtifactStagingDirectory)/**/*.nupkg;!$(Build.ArtifactStagingDirectory)/**/*.symbols.nupkg'
        nuGetFeedType: 'external'
        publishFeedCredentials: 'Preview-NuGet-Feed'
        versioningScheme: 'byEnvVar'
        versionEnvVar: 'NuGetVersion'
      condition: ne(variables['Build.SourceBranchName'], 'master')
    

内容的提问来源于stack exchange,提问作者diegosasw

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:35:54