How do I change target filename in NuGet Package? - msbuild

JavaScript naming convention requires version number in the file name such as jQuery.1.34.min.js, and I have text template which will output my-library.js in output folder.
I want to create NuGet Package with my-library.js in such way that on installation it should be deployed as my-library.1.34.js
If I build nuget package as part of msbuild process, there is no way I can rename my output js file.
I already have a long workaround, in which I have a console app which copies files to folder structure as given version number and then it builds a nuspec file and then it is passed onto nuget.exe, if there is any easy, I would like to avoid such long steps.

I found I could rename include files by specifying a full file name for the target.
For example (nuspec snippet):
<files>
<file src="my-library.js" target="content/my-library.$VERSION$.js">
</files>
and nuget would be run like:
nuget.exe pack mypackage.nuspec -Prop VERSION=1.34
Note: The File extension in src and target must match or the specified target will be treated like a directory.

Related

Consuming nuget package containing .targets file via PackageReference

I have .NET452 project - lets call it Consumer.csproj that I want to consume nuget lets call it SharedTargets that contained some custom targets files (SharedTargets.targets) from msbuild.
I'm using PackageReference format and now (compared to what it used to be) nuget packages are being restored to shared folder (%userprofile%.nuget\packages), and I'm not sure if it is good idea to reference it via that (doesn't feel right).
Eg:
<PackageReference Include="SharedTargets">
<Version>1.0</Version>
</PackageReference>
<Import
Project="$(USERPROFILE)\.nuget\packages\SharedTargets\1.0\SharedTargets.targets"
/>
Also this works only in VS, running this from command line (msbuild) I'm getting chicken-egg problem:
Confirm that the path in the <Import> declaration is correct, and that
the file exists on disk.
Obviously since I need to restore nuget first before I can use it :)
So question:
is there some more elegant way how to resolve path to the nuget package inside project file
is there a way how to make msbuild succeed (i.e. restore packages before SharedTargets.target is imported)
You shouldn't try to manually import targets distributed via NuGet.
Put your .targets file inside a build subfolder inside the package and name it SharedTargets.targets (package id + .targets) and NuGet will automatically include the targets - for packages.config projects it will modify the project file on install and for PackageReference projects the targets will be imported by modifying an implicitly generated targets file in the obj\ directory.

Add Zip Files to TARGETDIR in WiX

In my Visual Studio 2017 solution, I have a WiX 3 setup project that pulls in the output several other projects (libraries, executables, assets, content). Under the directory structure for the solution but not added to the solution as a project, I have a project that compiles some browser extensions using webpack. This webpack project outputs to an artifacts folder with subdirectories for each browser. Inside each subdirectory is the compiled extension with the version number included in the file name like:
artifacts
Chrome
myextension-0.1.0.0.zip
myextension-0.1.0.1.zip
myextension-0.1.0.2.zip
At compile time, ultimately I want to include the files matching the version number i.e. myextension-\$(var.VERSION).zip into the MSI package so it can then be placed into the application folder during installation. Even when I hard-code the version number i.e. myextension-0.1.0.2.zip into the component, I get an error from light:
LGHT0001: The system cannot find the path specified. (Exception from HRESULT: 0x80070003)
I'm getting the directory with a define like this:
<?define ChromeTargetDir=$(var.SolutionDir)Extensions\artifacts\chrome\?>
And then my component looks like this:
<Component Id="ChromeExt"
Location="local"
Guid="GUID_HERE">
<CreateFolder/>
<File Id="ChromeExtension"
Name="myextension-0.1.0.2.zip"
Source="$(var.ChromeTargetDir)myextension-0.1.0.2.zip"
KeyPath="yes"/>
</Component>
When I look in the wixobj created by candle, I see the full correct path replaced for the file where it resides on my system:
<field>C:\Users\me\source\repos\mysolution\Extensions\artifacts\chrome\myextension-0.1.0.2.zip</field>
So my question is, what is the correct way to include "arbitrary" files in my WiX project?
1) Solution vs Project Dir: The first thing I would try would be to replace $(var.SolutionDir) with $(var.ProjectDir) and try a recompile. I'll follow up if the problem is something else. Let's just rule that out first.
2) Quotes: I also use quotes around my paths:
<?define ChromeTargetDir="C:\Sources\Packages\MyChromeExtension\Files\" ?>
3) Project Variables: And finally you need a reference added to your project for project references and variables to work: WiX: How to use relative path to SolutionDir.
Maybe add: %ProgramFiles (x86)%\WiX Toolset v3.11\bin\WixUIExtension.dll
WiX Documentation: Using Project References and Variables
Obscure: More obscure causes could be lacking access rights (file not seen by the build process and light.exe - running impersonated?). Corrupted file or folder? (try to replace). And whatever else might conspire against you. Locked files?

How to build NuGet package containing a .nuspec template file?

I'm trying to create a NuGet package for an MSBuild Extension that should contain a template .nuspec file.
However when I specify a .nuspec file to be content of my package, I'm not able to install it in a .nuget folder of the target project.
As you can see in the screenshot, it will create a .nuget\NuSpecTemplate.nuspec folder in which the embedded .nuspec file will be created. I've named the template .spec, since NuGet will ignore the source file if it is named .nuspec.
Is this by design, or is it a bug in NuGet?

Nuget fails to include files listed in the nuspec file when paths contain certain msbuild properties

I'm trying to create a nuget package using certain MSbuild properties for the path to a file I want in my nuget package. However, if I use certain MSbuild pre-defined properties in the path, nuget fails to include them in the package (but does not throw any errors).
In my .nuspec, I have something that looks like this:
<files>
<file src="$MSBuildProjectDirectory$\..\..\Setup\CommonWebScripts\CreateIISSite.ps1" target=".\"/>
</files>
I can verify that the substitution is working because if I change the path to have an non-existent folder in it, nuget throws an error saying that the path is invalid. Similarly, if I hardcode the path to the file without using the MSbuild property, the package will be created with the file included.
I've tried using nuget 2.8.1 and 2.8.2, but it seems to be broken either way.
Turns out this was a bug in nuget code, which was fixed after I posted the problem on codeplex. Link to the issue on codeplex:
https://nuget.codeplex.com/workitem/4153
Updating nuget should fix the issue.

How do I set input path for binaries in WIX project to MSBuild output path on TFS?

I want MSBuild to build WIX 3.5 project containing static files and binaries from another project's output folder. While with static files it all works just fine: I just set Source attribute of File element to "..\AnotherProject\Static\StaticFile.ext", I can't reference binaries, because they aren't in "..\AnotherProject\bin\Release\" folder, they're in MSBuild output folder which I don't know how to reference.
The only way to do so is set some variable in .wixproj file in for Release build configuration and then use it, but it seems wrong. What do I miss?
You want "bind paths". The documentation isn't great about this but you can specify BindInputPaths on the Light MSBuild Task. Any File/#Source or #SourceFile that starts with "SourceDir\" or is a relative path (doesn't start with an "X:\" or "\") will be searched in those bind paths. You can use MSBuild variables to get the BindInputPaths set correctly.
Tried $(var.Web.TargetDir) - working.