Xamarin.Forms项目无法在Azure Pipelines中构建

时间:2019-09-12 19:11:07

标签: c# .net xamarin.forms xamarin.android azure-devops

我有一个适用于Android的Xamarin.Forms项目,可以在本地构建/测试/部署/打包程序而不会出现任何错误,并且该应用程序可以在手机上正常运行。完美!

现在,我想开始使用Azure DevOps Pipelines for CI,使用向导创建Xamarin Pipeline,启动Pipeline,它失败并出现编译错误:

  /Users/vsts/agent/2.155.1/work/1/s/MyProject/MyService.cs(41,64): error CS1503: Argument 1: cannot convert from 'char' to 'string' [/Users/vsts/agent/2.155.1/work/1/s/MyProject/MyProject.Android.csproj]

为什么它在本地构建而不在管道中构建?错误消息中引用的代码是以下功能:

var x = string.Join(',', nextStations);  // nextStations is IEnumerable<string>

我发现string.Join(char, IEnumerable<T>)函数仅在.NET Core Framework中可用,而在.NET for Xamarin.Android 7.1之类的其他版本中不可用-仅存在string.Join(string, IEnumerable<T>)函数。

当然,我现在可以将所有代码更改为不使用仅.net Core中可用的功能。实际上,我尝试过此操作,但随后Azure Build失败了,因为我引用的NuGet程序包之一也使用了此类.Net Core-only字符串功能,因此在管道中链接应用程序失败。所以这不是解决方案。

因此,无论出于何种原因,Azure管道似乎都尝试根据不同的框架来构建我的项目。为什么?有没有一种配置方式?还是Azure DevOps中的错误? 即使当我从“管道”日志中获取msbuild命令并针对我的项目在本地执行该命令时,该命令也不会出现任何错误。那么,为什么不在管道中呢?

msbuild /Users/vsts/agent/2.155.1/work/1/s/MyProject/MyProject.Android.csproj /t:PackageForAndroid /p:OutputPath=/Users/vsts/agent/2.155.1/work/1/b/Release /p:Configuration=Release

我猜这与这里的问题是相同的:How to fix 'Error processing method: 'System.Void Prism.Navigation.PageNavigationService' error in Azure Pipelines但是这个问题没有真正的答案(切换到Debug并不能解决问题),我发现了更多细节,即有所不同框架版本。

那么有什么主意如何使Pipeline构建项目?

Visual Studio 2019,Xamarin.Forms 4.2.0.778463,Android Target Framework v9.0

我的azure-pipelines.yml文件供参考:

trigger:
- master

pool:
  vmImage: 'macos-latest'

variables:
  buildConfiguration: 'Release'
  outputDirectory: '$(build.binariesDirectory)/$(buildConfiguration)'

steps:
- task: NuGetToolInstaller@1

- task: NuGetCommand@2
  inputs:
    restoreSolution: '**/*.sln'

- task: XamarinAndroid@1
  inputs:
    projectFile: '**/*droid*.csproj'
    outputDirectory: '$(outputDirectory)'
    configuration: '$(buildConfiguration)'

2 个答案:

答案 0 :(得分:0)

我不确定为什么要在您的本地计算机上构建它,但是如果我不得不猜测这可能是因为您的某些代码的缓存版本在某些时候可以正常工作。

尽管如此,如果您为string.Join()方法(对于NETStandard)查看https://github.com/docusign/eg-01-java-jwt,您将看到没有将char作为第一个参数的重载。它们全部取string。因此,您需要做的是使用双引号"<your_string_separator>",而不是单引号'<your_char_separator>'

我相信您的错误线路应该是这样

var x = string.Join(",", nextStations); // Notice that double quotes "", instead of single ones ``

EDIT :抱歉,我没有阅读您的全部问题,我只是意识到您实际上是在提到您已经检查过string.Join()的.NET Core。但是,这是令人困惑的部分,您可能尚未意识到这一点,.NET Core与Mono的兼容性部分(Xamarin框架)是通过NETStandard完成的(请参见docs

  

兼容:.NET Core通过.NET Standard与.NET Framework,Xamarin和Mono兼容。

EDIT2 :更多链接

单声道兼容性-> docs

深入探讨Mono和.NET Core之间的区别-> https://www.mono-project.com/docs/about-mono/compatibility/

答案 1 :(得分:0)

一周前我遇到了同样的问题,并且发现了this。仔细检查管道日志,我发现托管的MacOS使用的是Mono版本5.12,因此我在XamarinAndroid任务之前添加了一个步骤,在其中设置了新版本,这是我的azure-pipelines.yaml文件:

trigger:
- master

pool:
  vmImage: 'macos-latest'

variables:
  buildConfiguration: 'Release'
  outputDirectory: '$(build.binariesDirectory)/$(buildConfiguration)'

steps:
- task: NuGetToolInstaller@1

- task: NuGetCommand@2
  inputs:
    restoreSolution: '**/*.sln'
- task: Bash@3
  inputs:
    targetType: 'inline'
    script: |
      echo 'Selecting Mono version...'
      sudo $AGENT_HOMEDIRECTORY/scripts/select-xamarin-sdk.sh 5_18_1
- task: XamarinAndroid@1
  inputs:
    projectFile: '**/*Droid*.csproj'
    outputDirectory: '$(outputDirectory)'
    configuration: '$(buildConfiguration)'
- task: CopyFiles@2
  inputs:
    SourceFolder: '$(build.binariesDirectory)/$(buildConfiguration)'
    Contents: '*.apk'
    TargetFolder: '$(build.artifactstagingdirectory)'
- task: PublishBuildArtifacts@1
  inputs:
    PathtoPublish: '$(Build.ArtifactStagingDirectory)'
    ArtifactName: 'drop'
    publishLocation: 'Container'

您可以找到更多信息here和工具版本here

致谢!