ScriptSharp compilation with NAnt script - nant

We've recently added the excellent script# to our project. Currently we have it so that our VS build simply copies the compiled .js file from the output directory to the scripts directory of our web app.
We've decided to make it a permanent feature and so would like to make it so that the .js file gets generated as part of our web build NAnt script to ensure that it's always up to date. Is there any way to do this nicely or do I need to call MSBuild from my NAnt script specifying the .csproj file to run the compilation?
Thanks
Stu

This isn't likely the full answer (given I don't have experience with NAnt), but I'll offer it anyway, as it may help.
A script# csproj is very much like any other csproj relying on msbuild. If you've got some way to integrate other msbuild projects into your NAnt build script, the same model should ideally apply to script# projects as well.
In the version of script# that is in the github repository, a web project can add a reference to a script# project (thereby becoming dependent on the script# project), and include an msbuild deploy task, that will copy over scripts from the built script# project into the web project. You can see this in action in the Todo sample (https://github.com/nikhilk/scriptsharp/tree/cc/samples/Todo)

Related

Create a NuGet package with only javascript files

I want to create a NuGet package that contains only javascript. I have no assembly that needs to be built and included.
So to do this I created an empty solution in vs, and created an empty project. In the project I created a Scripts directory with my javascript files. I have a package.nuspec and a packages.config
When I run "nuget pack" commandline I get an error:
C:\MyProject>nuget
pack
Attempting to build package from 'TestProject.csproj'.
MSBuild auto-detection: using msbuild version '16.1.76.45076' from
'C:\Program Files (x86)\Microsoft Visual
Studio\2019\Enterprise\MSBuild\Current\bin'.
Error NU5012: Unable to find 'C:\MyProject\TestProject.exe'. Make sure the project has been built.
C:\MyProject>
If I try to build the project in visual studio, I get an error...
Program does not contain a static 'Main' method suitable for an entry
point.
...which makes sense because I made this from an empty project.
I am not trying to deploy the assembly, just javascript, can I stop it from trying to build somehow?
Don't use a project. Have have your .nuspec and javascript files in the directory, then run nuget pack. If the nuspec doesn't contain a <files> section, then it will just copy the filesystem structure directly into the nupkg.
Having said that, new ASP.NET Core projects from Microsoft's templates no longer use front end resources (html, javascript, css) from NuGet packages, but rather use either LibMan or npm, to be more in-line with what the non-.NET front-end ecosystem uses. I suggest investigating those technologies and using them if possible.

What is nuget props file and what is it for?

I have looked around and read a lot but couldn't find a definitive answer that would explain as to what the "nuget.props" file is and what is it used for.
Any explanation and maybe with some example?
Starting with some background information, .NET projects are built with MSBuild. A C# project's .csproj is just a MSBuild project file with a file extension that signals by convention that it's C# and not some other language, but to MSBuild it's just a project file. MSBuild has only a few base types, properties, items, targets and tasks. By convention, properties and items go in files with extension .props, while tasks and targets go in files ending in .targets. That's why if you look at old-style csproj files you'll see <Import Project="path\to\Microsoft.Common.CSharp.props" /> and <Import Project="path\to\Microsoft.Common.CSharp.targets" />. New, SDK style projects is basically syntactic sugar to do exactly the same thing.
Next, the MSBuild and .NET teams made the build system extensible. So, rather than being limited to what Microsoft built into the C# compiler/build system, you can replace parts of the build system, or add additional things into it. Without NuGet, the way to do this is to create your own .props and .targets file somewhere, then edit your .csproj and add <Import ... /> statements. This can work fine if your props and targets are in the same source code repository as what's using it, but editing your csproj and hardcoding the path to the props and targets files doesn't work so well otherwise.
NuGet can help with this. If you create a package with the appropriate conventions, NuGet will make sure the props and targets are discovered and used in the build. With projects using packages.config, NuGet will edit the csproj for you on install/upgrade/uninstall. Projects using PackageReference, NuGet will write a file to the intermediate directory (obj/ folder) named nuget.g.props and nuget.g.targets, which imports all the props and targets files from all the referenced NuGet packages, and the build system uses these files.
The first example I could think of why someone would want to do this is if you want to use a newer version of the .NET compiler than is installed on your system. Simply reference the Microsoft.Net.Compilers package, and the .props and .targets in the package will replace the compile targets/tasks in the system-installed build system, and use the one from the package instead. This allows you to use new language features before the compiler is installed on your system, or if you want to make sure all builds of your code use the same compiler, even if different developers or CI agents have different versions of things installed.
Another example may be pre-compiled scripts. If you have your own scripting language, create build tools that converts them into C# files, then write MSBuild props and targets that will run before the "real build" to convert your custom language into C#, save the generated .cs files into the intermediate folder, add MSBuild Compile items for these generated files, then the C# compiler will compile it with all the other .cs files in the project. You'll need a reasonable amount of knowledge of MSBuild and the .NET build system, but it's possible.

NUnit step in TeamCity tries to run tests against business logic .dlls because they're in the same folder as my test .dlls

I'm setting up a CI server for my company and integrating Unit Testing. I've chosen to use TeamCity and NUnit, as they've worked well for other organizations I've worked for in the past.
I have TeamCity up and running and I've created just a test Unit Test project for now so I can verify that TC is handling my NUnit configuration properly.
My solution file contains 6 C# projects, one VB.NET project and one unmanaged c++ project. For each of those (where required) there is one separate C# project that houses the test cases for the associated project, and contains a reference to that project.
When the NUnit step runs and finds .dlls where I've told it to look, it complains that the .dll files are not the right architecture, not the right .NET version, not the right alignment of the stars etc... This is because it's trying to run NUnit against business logic .dll files, as they're built and output from the test project along with the test .dll. The test .dll file is the correct architecture, .NET version etc... as is required by NUnit.
My question is this:
How can I tell TeamCity to either
Not care if the .dll file is the correct architecture, just skip it if it isn't
Only look for the proper .dlls
I've tried to keep just a folder called Test Dlls at my root, but I can't figure out how to get every project to only put the test .dll file there.
Lastly, I will be having my coworkers generating their own unit tests for their solution files, which are not of the same layout and configuration as I described above. I really don't want to have to tell my coworkers to name their files a certain way, or set their projects to build in a particular fashion etc... if at all avoidable.

Using TFS Build to Deploy Console Application with Continuous Integration

I have a solution that contains a number of projects. Some MVC Web Applications, Some Class Libraries and some Console Applications.
For the Web Applications we simply used Publish Profiles and created TFS Builds referring to those profiles for building deployment packages. We then used those to deploy the web apps.
How can I configure the Build Definition to give me the same results for my console applications?
The desired result here is to try and work towards automatic deployments using TFS and Release Management.
Update:
Ok, It seems I need to explain myself better.
We use TFS (MSBuild) to build the project. By simply "checking in" the code, it triggers our build which builds the project and creates a nice Website_Package.zip file in the drop folder.
What I am looking for, is for MSBuild to do the same for my Console Application. ie. I want it to produce a "ConsoleApp_Package.zip" file and dump it into my drop folder.
You can use the Zip task from MSBuild Extension Pack at http://msbuildextensionpack.codeplex.com/.
See http://www.msbuildextensionpack.com/help/4.0.8.0/index.html for an example.
You should just build, using MSBuild task, filling the Project with your console app .csproj and leave MSBuild Arguments empty.
Then you use a Copy Files task to get your files from bin folder to staging directory.
Example:
Source Folder: \bin\$(BuildConfiguration)
Contents: **
Target Folder: $(Build.ArtifactStagingDirectory)
After that you can add task to zip the files from staging directory.

NuGet package files not being copied to project content during build

I am building an MVC4 web application with VS2012 professional with NuGet Package Manager version 2.2.31210. I have multiple projects in my solution, all sharing various packages I installed using NuGet. One of my projects is an MVC4 web application where I am using packages such as bootstrap, jquery UI, etc, all installed using NuGet.
When I clone a fresh copy of my entire solution from my repository and build my MVC4 project, the package restore feature seems to be working: it creates the packages directory under the solution direcotry and populates it will all the versions of the packages I expect to see. However, the content files do not get copied to the appropriate places in the MVC app directory. The weird thing is that it does create directories for the content, but does not copy the content files themselves.
For example, I am using the Twitter Bootstrap package which appears in the packages/Twitter.Bootstrap.2.2.2. In the MVC project a directory called bootstrap (containing css, img, and js directories) gets created in the Content directory. But, no css or js files are copied into those directories!
Does anyone have a clue what magic incantation I must utter to get the build to copy these content files from the NuGet packages directory?
This is a very common issue we are all having. I've created an MSBuild Task NugetContentRestoreTask that will do this trick for you. Run the following command in the Package Manager Console:
Install Nuget Content Restore MSBuild Targets
PM> Install-Package MSBuild.NugetContentRestore
The only thing left is to call it from your BeforeBuild Target with something like this:
Project File Targets
<Target Name="BeforeBuild">
<NugetContentRestoreTask SolutionDir="$(SolutionDir)" ProjectDir="$(ProjectDir)" />
</Target>
You can take a look at the source repo and find it on nuget.org
Additional Content Folders
This nuget only includes the default folders scripts, images, fonts, and content, it is not a recursive directory includes. For additional content subfolders - you must assign the property AdditionalFolders.
<Target Name="BeforeBuild">
<NugetContentRestoreTask SolutionDir="$(SolutionDir)" ProjectDir="$(ProjectDir)"
AdditionalFolders="less;sass;common" />
</Target>
I have found a workaround, but it is ugly. By executing the following command in the NuGet Package Manager Console: Update-Package -Reinstall all the files are indeed copied to their proper places within the Mvc project Content and Scripts directories.
Unfortunately, this is risky because you are likely to end up with the wrong versions of certain packages. For example, in my case after the command finishes executing (which takes quite a while by the way), I end up with jQuery version 1.4.4. This is way old, and I assume it must be an explicit dependency of some other package that is being updated. So it appears that the order in which the packages actually get updated by NuGet is significant (it does not appear to parse the entire dependency tree for all packages and pick only the latest versions from the union of all dependencies, which seems like it would be the preferred behavior). Rather, as the command executes I see it replacing the jQuery package several times with different versions as it works its way through all the packages and their dependencies, only to end up with a very old version.
A similar approach is the execute the Update-Package -Reinstall command explicitly for each package that is causing my problem, but this is incredibly tedious and error prone.
The NuGet Package Restore feature should yield the same result as manually executing the Install-Package or Update-Package -Reinstall command for a package, but it does not.
I don't like to have the thirdparty JavaScript files under source control either. Thats why I've followed Jeff Handley advice in http://nuget.codeplex.com/workitem/2094 to create a solution my self. I didn't go the executable way, but created a nuget solution level package which does the trick.
http://www.nuget.org/packages/Baseclass.Contrib.Nuget.GitIgnoreContent/
It's tied to git, as it automatically updates the .gitignore file.
Short description:
Ignore nuget content files in git:
Generate entries in the .gitignore file to exclude nuget content files from the source repository
Restore nuget content files before building (Automatically in VS and manually with a powershell script
I've written a blog post describing how to use it.
http://www.baseclass.ch/blog/Lists/Beitraege/Post.aspx?ID=9&mobile=0
In Visual Studio 2015 Update 1, they now support contentFiles. The caveat with this is that it only works in projects that use project.json.
In reference to the problem that you are having, there is a good blog post that explains why you see this behaviour: NuGet Package Restore Common Misconceptions.
For my projects it turned out that content files work with PackageReferences only:
Existing project with nuget references via packages.config
Installed NuGet package with content files
Build project
No content files in output directory
Conversion of packages.config to PackageReferences
Build project
Content files have been copied to output directory
IDE is Visual Studio 2017. The project is an application project which means it is in the old csproj format.