Is there an MSBuild property providing the repository root?
Asked Answered
M

2

7

When running from Visual Studio, MSBuild is given the $(SolutionDir) macro/property. Running from Azure DevOps, this property does not exist (rightfully so).

Azure DevOps has the Build.SourceBranch variable which can be passed to MsBuild as a property. This variable is better because it points directly to the repository root while $(SolutionDir) may point to a sub-directory if the solution is not in the root.

Is there a consistent MsBuild property I can use in both Visual Studio and Azure DevOps which can point to the repository root?

One way to achieve this is to have a Directory.Build.props file in the repository root and Specify a property <RepositoryRoot>$(MSBuildThisFileDirectory)</RepositoryRoot> however one restriction I have prevents me from doing this.

Mowry answered 24/5, 2019 at 1:43 Comment(0)
L
1

I would strongly recommend not using .gitignore to find the root of a Git repo. It's possible to have that file in any directory.

I assume Azure DevOps uses Git as the underlying SCM and not TFS these days.

Here's a more direct way to get your Git repo root.

  <Target Name="GetGitRoot" BeforeTargets="BeforeBuild">
    <Exec Command="git rev-parse --show-toplevel" ConsoleToMSBuild="true">
      <Output TaskParameter="ConsoleOutput" PropertyName="GitRootDirectory"/>
    </Exec>
  </Target>

  <PropertyGroup>
    <RootDirectory>$(GitRootDirectory)</RootDirectory>
  </PropertyGroup>

The property below is just showing how to use it. You can use $(GitRootDirectory) directly. Just make sure your BeforeTargets happens before you use it.

Learn answered 23/8 at 21:52 Comment(2)
@Mowry I know this is from quite a while ago, but for those who happen on this, I think this would be a better accepted answer. – Learn
Thanks for your diligence @Jamie. I agree, just switched the accepted answer πŸ‘ – Mowry
R
6

Short answer: No, there isn't a default understanding of source control systems in MSBuild.

The Directory.Build.props file is likely the most robust approach, showing up regardless of building a solution or individual projects, since it stays the same regardless of the VCS system you use or migrate to/from.

Other approaches would need to hard code the VCS structure, e.g. looking for the a directory that contains a .gitignore file (which will not work if you don't use such a file):

<PropertyGroup>
  <RepoRoot>$([System.IO.Path]::GetDirectoryName($([MSBuild]::GetPathOfFileAbove('.gitignore', '$(MSBuildThisFileDirectory)'))))</RepoRoot>
</PropertyGroup>
Request answered 24/5, 2019 at 2:3 Comment(0)
L
1

I would strongly recommend not using .gitignore to find the root of a Git repo. It's possible to have that file in any directory.

I assume Azure DevOps uses Git as the underlying SCM and not TFS these days.

Here's a more direct way to get your Git repo root.

  <Target Name="GetGitRoot" BeforeTargets="BeforeBuild">
    <Exec Command="git rev-parse --show-toplevel" ConsoleToMSBuild="true">
      <Output TaskParameter="ConsoleOutput" PropertyName="GitRootDirectory"/>
    </Exec>
  </Target>

  <PropertyGroup>
    <RootDirectory>$(GitRootDirectory)</RootDirectory>
  </PropertyGroup>

The property below is just showing how to use it. You can use $(GitRootDirectory) directly. Just make sure your BeforeTargets happens before you use it.

Learn answered 23/8 at 21:52 Comment(2)
@Mowry I know this is from quite a while ago, but for those who happen on this, I think this would be a better accepted answer. – Learn
Thanks for your diligence @Jamie. I agree, just switched the accepted answer πŸ‘ – Mowry

© 2022 - 2024 β€” McMap. All rights reserved.