在Azure DevOps CI管道中用$(SolutionDir)替代

时间:2020-04-24 07:01:43

标签: azure-devops msbuild

我有以下情况:

其中安装了nuget软件包的SQL项目。该程序包(仅是PS脚本)负责解压缩DB所需的DACPAC,使用对解决方案文件夹的相对路径的引用(查找package /和dacpacs /文件夹,并浏览从中提取的项目。 sln文件)。这称为预构建事件。

在构建整个解决方案时,如预期的那样(本地和ADO)定义了$(SolutionDir)。

构建测试项目时,$(SolutionDir)是''或'* Undefined *'。同样,正如预期的那样,因为msbuild在构建单个项目时不了解解决方案。我可以在本地接受此警告,没问题。

问题是这样的:在Azure DevOps中是否可以使用某些“神奇的东西”来实现这项功能?

尽管有人想要一种干净的解决方案,但如果有人知道这种方法,我可以尝试各种黑客手段。

到目前为止已尝试:

1)添加以下PropertyGroup:

<PropertyGroup>
  <SolutionDir Condition="'$(SolutionDir)' == '' Or '$(SolutionDir)' == '*Undefined*'">.\</SolutionDir>
</PropertyGroup>

到测试项目。

2)提出以下建议:Prebuild event in Visual Studio replacing $(SolutionDir) with *Undefined*

没有效果。

1 个答案:

答案 0 :(得分:1)

如果您的文件夹结构类似于:

1.Azure Devops存储库包含解决方案文件夹(其中存在xx.sln文件)。

2。这些项目位于同一解决方案文件夹下。

您可以尝试我的脚本:

  <PropertyGroup>
    <ProjectFolder>$([System.IO.Directory]::GetParent($(ProjectDir)))</ProjectFolder>
    <MySolutionDir>$([System.IO.Directory]::GetParent($(ProjectFolder)))\</MySolutionDir>
  </PropertyGroup>

$(MySolutionDir)代表sln文件和项目文件夹所在的路径。像$(SolutionDir)一样,它也有\。所以它的格式看起来像SomePath\

建议,将我的脚本插入PreBuild事件的脚本上方。像这样:

  <PropertyGroup>
    <ProjectFolder>$([System.IO.Directory]::GetParent($(ProjectDir)))</ProjectFolder>
    <MySolutionDir>$([System.IO.Directory]::GetParent($(ProjectFolder)))\</MySolutionDir>
    It's recommended to add my script and PreBuildEvent in same propertyGroup, and mine should be in the first.
    <PreBuildEvent>echo $(MySolutionDir)</PreBuildEvent> 
  </PropertyGroup>

编辑1:

您还可以添加条件:

  <PropertyGroup>
    <ProjectFolder>$([System.IO.Directory]::GetParent($(ProjectDir)))</ProjectFolder>
    <MySolutionDir>$([System.IO.Directory]::GetParent($(ProjectFolder)))\</MySolutionDir>
    <SolutionDir Condition="xxxx">$(MySolutionDir)</SolutionDir>
    It's recommended to add my script and PreBuildEvent in same propertyGroup, and mine should be in the first.
    <PreBuildEvent>echo $(MySolutionDir)</PreBuildEvent> 
  </PropertyGroup>

编辑2:

嗯,我现在可以重现这个问题。这是一个很奇怪的行为,我不确定这个问题的根本原因。但是一种快速的解决方法是创建一个新的PropertyGroup来插入我们的自定义脚本,而不是从默认模板将其插入到现有的PropertyGroup中:

它曾经是:

  ....
  <PropertyGroup>
    <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">11.0</VisualStudioVersion>
    <!-- Default to the v11.0 targets path if the targets file for the current VS version is not found -->
    <SSDTExists Condition="Exists('$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v$(VisualStudioVersion)\SSDT\Microsoft.Data.Tools.Schema.SqlTasks.targets')">True</SSDTExists>
    <VisualStudioVersion Condition="'$(SSDTExists)' == ''">11.0</VisualStudioVersion>
    <ProjectFolder>$([System.IO.Directory]::GetParent($'(ProjectDir)'))</ProjectFolder>
    <ParentFolder>$([System.IO.Directory]::GetParent($'(ProjectFolder)'))\</ParentFolder>
    <SolutionDir Condition=" '$(SolutionDir)' == '' Or '$(SolutionDir)' == '*Undefined*' ">$(ParentFolder)</SolutionDir>
    <PreBuildEvent>echo $(SolutionDir)</PreBuildEvent>
  </PropertyGroup>
  <Import Condition="'$(SQLDBExtensionsRefPath)' != ''" Project="$(SQLDBExtensionsRefPath)\Microsoft.Data.Tools.Schema.SqlTasks.targets" />
  <Import Condition="'$(SQLDBExtensionsRefPath)' == ''" Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v$(VisualStudioVersion)\SSDT\Microsoft.Data.Tools.Schema.SqlTasks.targets" />
  <ItemGroup>
    <Folder Include="Properties" />
  </ItemGroup>
  <ItemGroup>
    <Build Include="test.sql" />
  </ItemGroup>
  <PropertyGroup>
    <PreBuildEvent>echo $(SolutionDir)</PreBuildEvent>
  </PropertyGroup>
</Project>

现在将其更改为:

  <PropertyGroup>
    <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">11.0</VisualStudioVersion>
    <!-- Default to the v11.0 targets path if the targets file for the current VS version is not found -->
    <SSDTExists Condition="Exists('$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v$(VisualStudioVersion)\SSDT\Microsoft.Data.Tools.Schema.SqlTasks.targets')">True</SSDTExists>
    <VisualStudioVersion Condition="'$(SSDTExists)' == ''">11.0</VisualStudioVersion>
  </PropertyGroup>
  <Import Condition="'$(SQLDBExtensionsRefPath)' != ''" Project="$(SQLDBExtensionsRefPath)\Microsoft.Data.Tools.Schema.SqlTasks.targets" />
  <Import Condition="'$(SQLDBExtensionsRefPath)' == ''" Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v$(VisualStudioVersion)\SSDT\Microsoft.Data.Tools.Schema.SqlTasks.targets" />
  <ItemGroup>
    <Folder Include="Properties" />
  </ItemGroup>
  <ItemGroup>
    <Build Include="test.sql" />
  </ItemGroup>
  <PropertyGroup>
    <ProjectFolder>$([System.IO.Directory]::GetParent($(ProjectDir)))</ProjectFolder>
    <ParentFolder>$([System.IO.Directory]::GetParent($(ProjectFolder)))\</ParentFolder>
    <SolutionDir Condition=" '$(SolutionDir)' == '' Or '$(SolutionDir)' == '*Undefined*' ">$(ParentFolder)</SolutionDir>
    <PreBuildEvent>echo $(SolutionDir)</PreBuildEvent>
  </PropertyGroup>

也请删除'中多余的$(ProjectDir)。它应该是$(ProjectDir),而不是$'(ProjectDir)'$'(ProjectFolder)'。我还看到您有两个PreBuildEvent属性,只需将其保留在我们的自定义脚本中即可。完成上述步骤后,您的项目现在在我这一边运作良好:

enter image description here