dotnet ef 迁移脚本在 CI 中失败,但在本地运行良好

dotnet ef migrations script fails in CI but works fine locally

问题背景:

我有一个 class 库项目,其中包含数据库迁移 (MyProject.MigrationProject.csproj)。并且在入门项目(Web API)的startup.cs中,我已经明确地包含了迁移程序集,如下所示。

 services.AddDbContext<ApplicationDbContext>(options =>
   options.UseSqlServer(
      configuration.GetConnectionString("DefaultConnection"),
      x => x.MigrationsAssembly("MyProject.MigrationProject")));

然后我 运行 dotnet ef migration 命令在本地使用 powershell。我使用的命令是:

dotnet ef migrations script --no-build -o D:\migrations\script.sql --idempotent --project D:\...\src\MyProject.MigrationProject\MyProject.MigrationProject.csproj --startup-project D:\...\src\MyProject.WebApi\MyProject.WebApi.csproj

以上命令在我的机器上成功执行,并在输出位置创建所需的 script.sql 文件。然后在 Azure Devops 的构建管道(使用命令行任务)中使用相同的命令,但由于某种原因它在那里失败了。 Devops 上的命令如下所示:

dotnet ef migrations script --no-build -o $(Build.ArtifactStagingDirectory)\migrations\script.sql --idempotent --project $(Build.SourcesDirectory)\src\MyProject.MigrationProject\MyProject.MigrationProject.csproj --startup-project $(Build.SourcesDirectory)\src\MyProject.WebApi\MyProject.WebApi.csproj

我从 Devops 得到的错误

Script contents:
dotnet ef migrations script --no-build -o D:\a\a\migrations\script.sql --idempotent --project D:\a\s\src\MyProject.MigrationProject\MyProject.MigrationProject.csproj --startup-project D:\a\s\src\MyProject.WebApi\MyProject.WebApi.csproj
##[debug]AGENT_VERSION: '2.193.1'
##[debug]AGENT_TEMPDIRECTORY: 'D:\a\_temp'
##[debug]Asserting container path exists: 'D:\a\_temp'
##[debug]Asserting leaf path exists: 'C:\Windows\system32\cmd.exe'
========================== Starting Command Output ===========================
##[debug]Entering Invoke-VstsTool.
##[debug] Arguments: '/D /E:ON /V:OFF /S /C "CALL "D:\a\_tempfc4a71-a144-4332-9a84-04e6138a2538.cmd""'
##[debug] FileName: 'C:\Windows\system32\cmd.exe'
##[debug] WorkingDirectory: 'D:\a\s'
"C:\Windows\system32\cmd.exe" /D /E:ON /V:OFF /S /C "CALL "D:\a\_tempfc4a71-a144-4332-9a84-04e6138a2538.cmd""

An error occurred while accessing the Microsoft.Extensions.Hosting services. Continuing without the applicgation service provider. Error: A certificate with the thumbprint 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' could not be found.
Unable to create an object of type 'ApplicationDbContext'. For the different patterns supported at design time, see https://go.microsoft.com/fwlink/?linkid=851728

##[debug]Exit code: 1
##[debug]Leaving Invoke-VstsTool.
##[error]Cmd.exe exited with code '1'.
##[debug]Processed: ##vso[task.logissue type=error]Cmd.exe exited with code '1'.
##[debug]Processed: ##vso[task.complete result=Failed]Error detected
##[debug]Leaving D:\a\_tasks\CmdLine_d9bafed4-0b18-4f58-968d-86655b4d2ce9.182.0\cmdline.ps1.
Finishing: CmdLine

有时,通过调整 YAML 文件,我能够消除第一个错误,但第二个错误在 devops 上从未消失。这个问题很大程度上是因为有单独的迁移项目,但我认为它应该是这样的......

我的构建管道的 YAML:

trigger:
- develop

pool:
  vmImage: 'windows-latest'

variables:
  solution: '**/*.sln'
  buildPlatform: 'Any CPU'
  buildConfiguration: 'Release'

steps:
- task: DotNetCoreCLI@2
  displayName: Restore
  inputs:
    command: restore
    projects: '**/MyProject.WebApi.csproj'

- task: DotNetCoreCLI@2
  displayName: Build
  inputs:
    projects: '**/MyProject.WebApi.csproj'
    arguments: '--no-restore'

- task: DotNetCoreCLI@2
  displayName: Test
  inputs:
    command: test
    projects: '**/*[Tt]ests/*.csproj'
    arguments: '--no-restore --no-build'

- task: DotNetCoreCLI@2
  displayName: 'Publish WebApi'
  inputs:
    command: publish
    publishWebProjects: false
    projects: '**/MyProject.WebApi.csproj'
    arguments: '--configuration $(BuildConfiguration) --output $(Build.ArtifactStagingDirectory) --runtime -r $(runtime)'

- task: CopyFiles@2
  inputs:
    Contents: '**'
    TargetFolder: '$(Build.ArtifactStagingDirectory)'

- task: UseDotNet@2
  inputs:
    packageType: 'sdk'
    version: '5.x'

- task: DotNetCoreCLI@2
  displayName: Install dotnet-ef
  inputs:
    command: 'custom'
    custom: 'tool'
    arguments: 'install --global dotnet-ef --version 5.0.10 --ignore-failed-sources'

- task: CmdLine@2
  inputs:
    script: dotnet ef migrations script --no-build -o $(Build.ArtifactStagingDirectory)\migrations\script.sql --idempotent --project $(Build.SourcesDirectory)\src\MyProject.MigrationProject\MyProject.MigrationProject.csproj --startup-project $(Build.SourcesDirectory)\src\MyProject.WebApi\MyProject.WebApi.csproj

- task: PublishBuildArtifacts@1
  displayName: 'Publish Artifact: drop'

我的猜测:

执行命令的目录可能有问题(在 ADO powershell 上)。我怀疑这是因为,在我的本地机器上,在调用方法 x.MigrationsAssembly("MyProject.MigrationProject") 之前,当我从目录执行它时,以下命令失败除了入口项目的目录,但是当我将 powershell 导航到入口项目并执行相同的命令时,它成功了。当时的命令是:

dotnet ef migrations script -o D:\migrations\script.sql --idempotent --project D:\...\src\MyProject.MigrationProject\MyProject.MigrationProject.csproj

我已经在另一个项目中使用相同的 YAML,但它包含单个 Web API 项目中的所有内容,因此,我在那里没有遇到任何问题。

问题:

我在这里做错了什么?我该怎么做才能解决这个问题?任何帮助将不胜感激。

项目详情

点网 5.0

EntityFramewokCore 5.0.10

Visual Studio 2019

如有遗漏,请追问。

更新:

我对执行 dotnet ef 命令的工作目录的怀疑似乎是错误的,因为我通过向命令行任务提供 workingDirectory 参数来尝试这样做。不过它可以在本地机器上运行。

谢谢@jane-ma-msft

错误消息表明这是一个证书错误。请按照变通方法解决问题。

  1. 尝试生成新证书或取消证书验证。

  2. 检查您的 .sln 文件。如果它有 PackageCertificateKeyFilePackageCertificateThumbprint,请尝试 删除 属性并 重新启动 管道。

    或者检查它是否配置正确并且您已经将正确的证书文件上传到适当的路径。

  3. 确保代理windows-latest具有您需要的所有.NET SDK 版本以及您的项目需要引用的所有软件。如果没有,请使用任务或命令行下载它们。单击 this link 查看安装在 windows-latest 代理上的软件。

  4. 如果您在管道中使用 Microsoft 托管的 Windows 代理,请尝试在您的管道中使用自托管代理。单击 this document 了解详细步骤。

参考这里Link 1 & Link 2