NuGet doesn't copy config file - deployment

I've tried many different things now, none of which seem to work out as expected.
I would like to share an example config(or image or whatever) file with my library that someone would be able to use and derive from. I tried to default to just To do so I tried to include it in the nuget package via *.nuspec and via *.csproj. None of which worked.
For the *.nuspec part, I've tried this:
<file src="bin\$configuration$\example.mylib.config" target="lib\net45" />
<file src="bin\$configuration$\example.mylib.config" target="build" />
<file src="bin\$configuration$\example.mylib.config" target="bin" />
I've also tried this, but that only copies the file to the other projects sources, which is not what I want. I would like it to only show up in the output of the build.
<file src="bin\$configuration$\example.mylib.config" target="content" />
For the *.csproj part, I've tried to set the build action of the file to content, resource, embedded resource and None.
Is there a way at all?
Is there a way to tell nuget, take this file, and behave like the dll I'm providing needs this by it's side, wherever you build?

One thought might be to perform a config file transformation. Rather than just deploying a config file directly, you could modify the app.config or web.config on the project with a sample for the user to apply. Alternatively, as you mentioned in your comment, you could add in a Powershell script to perform the manipulations you were considering.

Related

Wix not able to find the .NET 6 exe

I have a console application that has <TargetFramework>net6.0</TargetFramework>. I am trying to use the exe of this console application in the wix project for creating the setup as shown below:
<Component Id="_COMP_ConsoleApp_exe" Guid="{34407E06-98A0-4CF3-8021-F9533CFE537D}">
<File Id="_FILE_ConsoleApp_exe" Name="ConsoleApp.exe" KeyPath="yes" Source="$(var.ProjectSourceDir)\ConsoleApp.exe" />
</Component>
But during the build it gives the error "The system cannot find the file ..\Release\ConsoleApp.exe". The ConsoleApp.exe is getting created in the Release folder.
That error indicates the file is not in the location you specified. To debug, try putting the full path to the file on your computer in the File/#Source attribute. Once you know you have the right path, then try using BindPaths or, if you must, preprocessor variables to make the location more generic.
I expect you'll find the folder ..\Release\ is not the one you thought it was.
Note: the Name and KeyPath attributes are unnecessary as they will default to those values.

How to instruct RestorePackages to use the NuGet.config file's repositoryPath for the package output path?

I am attempting to migrate a CCNET based build script to a F# Fake based one. I am having difficulty understanding how to modify the RestorePackages method to honor the NuGet.config file that instructs NuGet to place the packages in a folder named 'External' several layers deep in our repository.
NuGet.config Example:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<config>
<add key="repositoryPath" value="Code\DotNet\External\" />
</config>
</configuration>
NuGET CCNET Example:
<exec executable="Tools\NuGet\nuget.exe">
<buildArgs>restore $[$CCNetWorkingDirectory]\Code\DotNet\Web\All.sln</buildArgs>
</exec>
In the above examples I am simply telling NuGet to restore packages for all the projects in the solution. This honors the settings in NuGet.config.
NuGet Fake Example:
Target "RestorePackages" (fun _ ->
RestorePackages()
)
However, calling RestorePackages() does not honor NuGet.config (as this method simply uses default parameters) and so my packages are updated in the wrong location.
Ideally I would like to instruct RestorePackages to look specifically at the Visual Studio solution file as I do with CCNET. Is this possible?
If that is not doable, I would like to instruct RestorePackages to honor the settings in the NuGet.config file.
However, if neither are doable, I'll need to be able to override the Output path. Unfortunately, I am having difficult time understanding the documentation and I am not sure how to construct this.
I have been reading over the documentation and the source code for the RestorePackagesHelper module and found that it does not support what I want to acheive, at least not directly due to two limitations.
Limitation 1: No Solution File Support - The current RestorePackage implementation uses the NuGet Install Command which does not support passing in a solution file. In order to pass in a solution file one would need to use the NuGet Restore Command. Therefore this is not a direct Fake equivalent for what the CCNET snippet listed in the question.
Limitation 2: No ConfigFile Support - Further, the RestorePackageParams type does not have a ConfigFile parameter so I am unable to specify the ConfigFile that I want to use in for the NuGet restoration.
These are current limitations of Fake. Not NuGet.
A Reasonable Solution - However, I can achieve a similar effect with Fake by scanning for all packages.config files in a given directory and calling RestorePackage for each one; each time specifying the OutputPath as shown below.
Fake NuGet RestorePackages Example
Target "RestorePackages" (fun _ ->
!! "./**/packages.config"
|> Seq.iter (RestorePackage (fun p ->
{ p with
OutputPath = "./Code/DotNet/External"}))
)

How to set nuget package version using build number with nugetter

We're using nugetter to make a nupkg as part of our build process for a solution that only builds occasionally, and that we want to distribute in the future. We also want to use this package in other solutions we have. So far, I've been able to generate a package that we can install. Now, I want to be sure that this package updates its version every time it's built so we can update the package easily. I'm thinking that using the build number would be a good way to do this, but I'd be willing to use just about any incrementing scheme if I don't have to start writing a powershell script to update the nuspec for package on every build.
Is there a way to do this automatically in nugetter?
If not, is there something easier than modifying the nuspec with powershell?
We're trying to do the same thing. NuGetter ships with a build process template that builds on top of TfsVersioning. Are you using that already? If so, all you have to do is add a special element for your NuGet package ID to the VersionSeed.xml file.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<VersionSeed>
<Solution name="Your Solution Name">
<!-- This is the pattern used to replace the AssemblyVersion value. -->
<AssemblyFileVersionPattern>1.0.J.B</AssemblyFileVersionPattern>
<!-- This is the pattern used to replace the AssemblyVersion value. -->
<AssemblyVersionPattern>1.0.0.0</AssemblyVersionPattern>
</Solution>
<NuGetPackage id="Your NuGet Package ID">
<!-- This is the pattern used to replace the version attribute in the NuSpec file. -->
<VersionPattern>1.0.J.B</VersionPattern>
</NuGetPackage>
</VersionSeed>
It's not a very well documented NuGetter feature, but it's in their help file somewhere.
Also, you still have to set the <version> attribute in the NuSpec file. Currently, I force it to 0.0.0.0 because it is overridden by the build process anyway. Removing the <version> element completely seems to always result in a crash.

How to modify the csdef defined in a cspkg

To deploy to different azure environments I modify the csdef as part of the compilation step to change the host headers. Doing so requires building the cspkg once for each environment instead of being able to reuse the cspkg and specify different configs for deployment.
I would like to instead modify the csdef file of a cspkg after it has been created, without recompiling. Is that possible, and if so how?
I've done something similar to what you're after to differentiate between test and live environments. First of all you need to create a new .csdef file that you want to use for your alternate settings. This needs to be the complete file as we're just going to swap it out with the original one. Now we need to add this to the cloud project. Right click on the cloud project and select unload project. Right click on it again and select Edit [Name of project]. There's a section that looks a bit like this:
<ItemGroup>
<ServiceConfiguration Include="ServiceConfiguration.Test.cscfg" />
<ServiceDefinition Include="ServiceDefinition.csdef" />
<ServiceConfiguration Include="ServiceConfiguration.cscfg" />
</ItemGroup>
Add a new ServiceDefinition item that points to your newly created file. Now find the following line:
<Import Project="$(CloudExtensionsDir)Microsoft.WindowsAzure.targets" />
Then add this code block, editing the TargeProfile check to be the build configuration you're wanting to use for your alternate and ensuring that it points to your new .csdef file
<Target Name="AfterResolveServiceModel">
<!-- This should be run after it has figured out which definition file to use
but before it's done anything with it. This is all a bit hard coded, but
basically it should remove everything from the SourceServiceDefinition
item and replace it with the one we want if this is a build for test-->
<ItemGroup>
<!-- This is an interesting way of saying remove everything that is in me from me-->
<SourceServiceDefinition Remove="#(SourceServiceDefinition)" />
<TargetServiceDefinition Remove="#(TargetServiceDefinition)" />
</ItemGroup>
<ItemGroup Condition="'$(TargetProfile)' == 'Test'">
<SourceServiceDefinition Include="ServiceDefinition.Test.csdef" />
</ItemGroup>
<ItemGroup Condition="'$(TargetProfile)' != 'Test'">
<SourceServiceDefinition Include="ServiceDefinition.csdef" />
</ItemGroup>
<ItemGroup>
<TargetServiceDefinition Include="#(SourceServiceDefinition->'%(RecursiveDirectory)%(Filename).build%(Extension)')" />
</ItemGroup>
<Message Text="Source Service Definition Changed To Be: #(SourceServiceDefinition)" />
</Target>
To go back to normal, right click on the project and select Reload Project. Now when you build your project, depending on which configuration you use, it will use different .csdef files. It's worth noting that the settings editor in is not aware of your second .csdef file so if you add any new settings through the GUI you will need to add them manually to this alternate version.
If you would want to just have a different CSDEF then you can do it easily by using CSPACK command prompt directly as below:
Open command windows and locate the folder where you have your CSDEF/CSCFG and CSX folder related to your Windows Azure Project
Create multiple CSDEF depend on your minor changes
Be sure to have Windows Azure SDK in path to launch CS* commands
USE CSPACK command and pass parameters to use different CSDEF and Output CSPKG file something similar to as below:
cspack <ProjectName>\ServiceDefinitionOne.csdef /out:ProjectNameSame.csx /out:ProjectOne.cspkg /_AddMoreParams
cspack <ProjectName>\ServiceDefinitionTwo.csdef /out:ProjectNameSame.csx /out:ProjectTwo.cspkg /_AddMoreParams
More about CSPACK: http://msdn.microsoft.com/en-us/library/windowsazure/gg432988.aspx
As far as I know, you can't easily modify the .cspkg after it is created. I guess you probably technically could as the .cspkg is a zip file that follows a certain structure.
The question I'd ask is why? If it is to modify settings like VM role size (since that's defined in the .csdef file), then I think you have a couple of alternative approaches:
Create a seperate Windows Azure deployment project (.csproj) for each variation. Yes, I realize this can be a pain, but it does allow the Visual Studio tooling to work well. The minor pain may be worth it to have the easier to use tool support.
Run a configuration file transformation as part of the build process. Similiar to a web.config transform.
Personally, I go with the different .csproj approach. Mostly because I'm not a config file transformation ninja . . . yet. ;) This was the path of least resistance and it worked pretty well so far.

NetBeans ANT: <zip> is not including hidden files?

At the end of my Clean/Build, I wanted to always automatically copy the project folder into a zip for easy transfer. So I added this to my post build <target> in build.xml:
<zip zipfile="../project-xyz.zip" basedir=".." includes="project-xyz/**" excludes="*/dir/lib/**"/>
This works great on Windows, but on Linux, it removes any .hidden folders and all their children. I even tried
<zip zipfile="../project-xyz.zip" basedir=".." includes="project-xyz/**,project-xyz/.hidden/**" excludes="*/dir/lib/**"/>
and it still doesn't work.
What can I do to bring those files into the zip?
I am not opposed to detecting non-Windows environments and using <exec> on the zip command, though I am not sure how I would do that, and I am not sure I really want to, especially if there is a better way!
You can see what gets excluded by default from the zip by adding the following line in ant
<defaultexcludes echo="true"/>
And then use
<defaultexcludes add=.../>
and
<defaultexcludes remove=.../>
to customize what gets excluded by default.
Reference: Ant docs for DefaultExcludes
EDIT
You can also do
<zip defaultexcludes="no" .../>
Reference: Ant docs for Zip