Octopack packaging windows service as if it were a web site - deployment

I have a windows service which contains the necessary components to allow it to render razor templates. This service listens on a message queue and sends emails, using the razor templates to generate rich html.
Everything is working fine, however, when it comes to deploying it with Octopus Deploy, it seems that OctoPack is seeing this service as a web site and packaging it incorrectly.
Before adding the razor template feature, this service used to get packaged correctly and was able to deploy with no worries.
The packaged output now looks like:
When in reality, it needs to just contain the contents of the bin folder. It seems to me as if OctoPack is treating the service as a website now.
I have tried adding a nuspec file, but that doesn't work, I end up with:
Nuspec file looks like:
<!-- cut for brevity -->
<files>
<file src="bin\**\*.*" target=""/>
</files>
So that doesn't work either.
What can I do to fix this??

I managed to hack something together to solve the problem I was having. After looking at the Octopus Deploy docs, I found that I could pass a OctoPackNuGetProperties property to msbuild and replace the config name in the nuspec file.
So the nuspec file now looks like this:
<files>
<file src="bin\$config$\**\*.*" target="" />
</files>
and I now pass /p:OctoPackNuGetProperties=config=Deploy to msbuild, which means that OctoPack now packages the service bin correctly.
I'm still interested to hear from someone at Octopus as to whether this is an issue with OctoPack or whether it's to do with how I've set things up though.

Related

Output Directory of native dll bundled with NuGet

I am trying to build a NuGet package that includes native DLLs which are to be placed in the output folder when a project uses the package. I have tried to use the several suggestions from this question, but I am always running in the same problem.
My current NuGet package layout is like this:
\build
packageId.targets
file1.dll
file2.dll
\lib
\netstandard1.4
assembly.dll
The contents of packageId.targets is:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<NativeLibs Include="$(MSBuildThisFileDirectory)\*.dll"/>
<None Include="#(NativeLibs)" Link="$(RecursiveDir)$(Filename)$(Extension)">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>
This should, according to the answers of the other questions, lead to my DLLs being placed in the bin\Debug directory of the project using the package. However, they are not. Instead, they are placed in bin\Debug\packages\packageId\build.
Now I have experimented a lot, and I noticed more and more strange behavior which I cannot make any sense of:
If I move the DLLs to the root of the NuGet package (like one answer suggests) and change the .targets file accordingly, they are not copied at all. There also is no error message.
If I change the .targets file to only reference file1.dll in both Include= and Link=, both files get copied anyway.
So I wondered if some policy just ignores the .targets file and copies whatever is in build to that path in the output folder, but when I remove the .targets file, the DLL files will not get copied anymore.
Now I understand even less what's happening.
What do I need to change to get the DLLs copied right into bin\Debug?
The new way to handle runtime-specific assents in NuGet is to use the runtimes folder to place native assets:
\lib
\netstandard2.0
ManagedWrapper.dll
\runtimes
\win-x86
\native
NativeThing.dll
\win-x64
\native
NativeThing.dll
\linux-x64
\native
libNativeThing.so
\osx-x64
\native
libNativeThing.dylib
If the package is consumed from a .NET Framework project, you may need to add a reference to the Microsoft.NETCore.Platforms package wich provides the runtime graph (runtimes.json) for NuGet to provide proper RID mappings if you don't use base RIDs (e.g. win10-x64 falls back to win-x64 resources).

Nesting files in Nuget package without PowerShell

The title says it all. I have files that I want to nest during the installation of a NuGet package but can't use PowerShell scripts since they won't be run any longer (see here).
Are there any other ways to achieve this goal?
UPDATE: By nested I mean like *.resx and *.Designer.cs or *.xaml and code-behind files *.xaml.cs. I know I can achieve that by adding a <DependentUpon> element in the *.csproj file but I don't know how I can add that element without using PowerShell.
UPDATE2: init.ps1 runs the first time a package is installed in a solution. That won't cut it though. I would need the script to run when the package is installed into a project just like install.ps1 was run up to NuGet3.
UPDATE3: What I want to do is to add 3 files into the Properties folder of the target projects (Resources.resx, Resources.tt and Resources.Designer.cs). They are a replacement for the usual resources implementation. These files are installed by the nuget package when it is added to the project.
This is the part of the *.nuspec file that adds them to the Content folder of the package. As only one of them is actually content (the others being an Embedded Resource and Compile respectively) it would be nice to be able to set their build actions accordingly but one step at a time.
<files>
<file src="Properties\Resources.resx" target="content\Properties\Resources.resx" />
<file src="Properties\Resources.tt.pp" target="content\Properties\Resources.tt.pp" />
<file src="Properties\Resources.Designer.cs" target="content\Properties\Resources.Designer.cs" />
</files>
As these files are added to the projects I want the nesting inside the *.csproj file and not happen via a separate *.props file if that is somehow possible.
Packages can add MSBuild items like this to a project by using a .props file in the package. It would contain the same content that you would put into the .csproj file.
The down side of this is that the content cannot be modified by the user. If you need to modify the user's actual project file and copy content to the project folder you would have to include a .targets file in your package and set BeforeTargets="Build" on your target. This would give you a chance to run before build and make changes as needed.
The build folder works for both packages.config and PackageReference (NETCore SDK) projects. You can find more out about it here: https://learn.microsoft.com/en-us/nuget/create-packages/creating-a-package#including-msbuild-props-and-targets-in-a-package

NuGet - only add post processed file to a web project

I have a nuget package that can be applied to any type of C# project.
It has a file that is added to the project as part of the package. The NuSpec looks like this:
<files>
<file src="Content\App_Start\StartUpCode.cs.pp" target="content\App_Start" />
I am using WebActivator to run the code in the file at application start.
I run into a problem when the nuget package is applied to several projects in the same solution. I get several instances of the StartUpCode.cs added, and as a result WebActivator runs the code several times.
How can I stop this code from being added to a project that is not web related? I.e. it's cool to add it to a WebAPI project, or a WebForms project, but not a class library.
I don't think there's anything in the Nuget spec that would allow you to do that easily. Maybe use a Powershell install script and detect the type of project it's being installed into and/or if the assembly has been referenced previously?
Personally, I'd split it into two Nuget packages. One with the business logic, and then another with the WebActivator dependency.

Call custom tool from TFS build

We are using TFS2010 for our web sites's builds and we're in the process of creating fully automated builds. At the moment the sites are built and deployed in remote servers.
The sites contains several configuration files that we would like to transform as part of the build. As there are some rules to create the correct config files we would like to use a custom tool for that purpose (.exe), not to use xml transformations for it.
From what we can see in the build template, MSBuild copies the files to a drop folder and then pushes them to the remote IIS site. We would like to hook our custom tool to this process and do the transformations in the build server before the site is published. The problem is that the MSBuild task is a single node in the build template and we can't find a place where to invoke our tool. Before the MSBuild step, there is no code deployed to the drop folder, after the MSBuild step the code was already deployed to the remote server.
Any ideas on how to plug the custom tool in the correct workflow step?
What is the msbuild target, that you use? I think you can define your own target in csproj file to do the following:
execute your custom tool against required files
run usual build target (or whatever target you normally use)
Edit
E.g. in a .csproj file you could define the following:
<Target Name="buildWithCustomTool">
<!-- Exec your custom tool -->
<Exec Command="your command" />
<!-- Call the build target which will run as normally -->
<CallTarget Targets="Build" />
</Target>
Hope it helps,
Ivan

How can a NuGet package include transformations for both app.config and web.config?

I'm trying to create a nuget package which will both add a DLL and configure it inside of the proper configuration file. The package can be used in either a console/form application or a web application, so I want to update the appropriate configuration file, either app.config or web.config.
My files section in the .nuspec file contains the following inside of the section.
<file src="config.transform" target="content\app.config.transform"/>
<file src="config.transform" target="content\web.config.transform"/>
The .nupkg file does contain both of the transforms inside of the content folder.
When I add my package to a project in VS2010 through Manage NuGet Packages, the only file which is ever modified is the app.config file. Web.config is never touched. In fact, in a web application with an existing web config, NuGet will create an app.config file which contains the modifications.
Is there a way of doing what I'm trying to do (and if so, how)?
According to a related bug report, it should already work how you want it to. Are you running the latest version of NuGet?