Search code examples
.netmsbuildnuget

Create nuget package that only contains msbuild.targets


I'm trying to create a nuget package that only contains MSBuild *.targets files. I can create a C# class library and add my targets file, but I don't need the overhead of a C# build process. Is there a way to author a nuget package that only contains static content or build files?

I've seen answers that suggest just having a raw nuspec file and use nuget pack to create the package. I would like to use dotnet pack if it is possible but it doesn't seem to support nuspec files directly. Does anyone know if this is possible?


Solution

  • This page lists targets for use in various (non-typical) build scenarios. The Microsoft.Build.NoTargets...

    Supports utility projects that do not compile an assembly.

    Which sounded exactly like what I want. If you look at this page, it provides more detail on exactly what this Project Sdk does, which is basically copy files @(FilesToCopy) to the $(OutDir) directory.

    I didn't really want that, but... I created a project, my-project, with the following file structure.

    my-project   # base project folder
    |-- PackageLayout
    |   |-- buildTransitive
    |   |   |-- my-project.props
    |   |   |-- my-project.targets
    |   |-- icon.png
    |   |-- README.md
    |-- my-project.msbuildproj
    

    The PackageLayout directory are the files and layout I want in my nuget package. The my-project.msbuildproj file is where I define all the package metadata, PackageId, PackageVersion, etc.

    <?xml version="1.0" encoding="utf-8"?>
    <Project Sdk="Microsoft.Build.NoTargets/3.7.56">
      <PropertyGroup>
        <TargetFramework>netstandard1.0</TargetFramework>
        <GeneratePackageOnBuild>true</GeneratePackageOnBuild>
        
        <!-- Don't warn about no binaries, there aren't supposed to be any -->
        <NoWarn>NU5128</NoWarn>
      </PropertyGroup>
    
      <PropertyGroup>
        <!-- Package metadata -->
        <PackageId>my-project</PackageId>
        <PackageVersion>1.0.0</PackageVersion>
        <DevelopmentDependency>true</DevelopmentDependency>
        <IsTool>true</IsTool>
    
        <PackageReadmeFile>README.md</PackageReadmeFile>
        <PackageIcon>icon.png</PackageIcon>
      </PropertyGroup>
    
      <ItemGroup>
        <!--
        * Display project root files in the project         : `Include="*"`
          * But don't include them in the nuget package     : `Pack="false"`
          * Exclude the msbuildproj file as it is displayed
            at the project level                            : `Exclude="$(MSBuildProjectFile)"`
        -->
        <None Include="*" Pack="false" Exclude="$(MSBuildProjectFile)"/>
      </ItemGroup>
    
      <ItemGroup>
        <!--
        Include everything in the PackageLayout directory in the package
        and maintain the same directory structure (but from the package
        root)
        -->
        <None Include="PackageLayout\**\*" Pack="true" PackagePath="\" />
    
        <!--
        Anything in buildTransitive directory, also pack in the build directory
        for backwards compatability.
        
        https://github.com/NuGet/Home/wiki/Allow-package%2d%2dauthors-to-define-build-assets-transitive-behavior
        -->
        <None Include="PackageLayout\buildTransitive\**\*" Pack="true" PackagePath="build\" />
      </ItemGroup>
    </Project>
    

    If I run dotnet build on this project it produces my-project.1.0.0.nupkg in the $(OutDir) with the correct icon.png, readme and targets/props files.