⬆️ ⬇️

Automating the assembly of web applications on the .NET platform

NAnt logo

Good day!



I tried to describe here my experience in automating the assembly of .NET applications (mainly, we are talking about web applications).



Because It turned out many letters had to break article two into parts. Now I am posting the first part, if someone needs it, I will post the rest. Do not kick hard.

')





Suppose we have the following tasks:



  1. 1. It is necessary to assemble a web application from source codes located in the version control system, configure it in a certain way and put it on the server (as well as update the database structure with which the application works. For example, such a task may arise during development when necessary lay out the current version for testers.
  2. 2. There are several clients of the company, for each of which you need to prepare a separate distribution of the web application that is configured specifically for this client.


Usually these tasks, having appeared once, begin to repeat periodically (and sometimes they are repeated very often). Let's try to automate the solution of these problems using NAnt.



Just a few comments:

- A long time ago there was a link to a great article about building a development process on a .NET platform. Although it describes a solution to a slightly different problem, NAnt is very well described there. In addition, this article has a lot of interesting and useful information about other stages of the development process. I highly recommend reading.

- there is a utility MsBuild - analogue of NAnt from Microsoft - it has almost the same set of features. The choice of tools to automate the build is a personal matter for each developer. I subjectively like NAnt more. I would be happy to discuss in the comments the advantages and disadvantages.



To begin, briefly tell you what is NAnt



Nant is a console utility to automate the software build process. The actions that NAnt must perform are set in a special configuration file (usually such a file has the extension .build) in XML format.

When you run NAnt, the path to the required build file is passed through the command line parameter -buildfile. If there is only one build file in the working directory, then the -buildfile parameter can be omitted.



Sample command line to run NAnt

NAnt -buildfile: .. \ main.build

The root element of the .build file is “project”. The project contains a set of “tasks” (“target”), each of which contains a description of a certain sequence of actions.



Contents of the build file

Example of the structure of a build file:

<project>

<target>

<_1 />

<_2 />

<_3 />

</target>

<target>

<_1 />

<_2 />

</target>

</project>




(A list of "actions" can be found here )



In addition, in the build-file you can set "properties" ("property"). The property is a name-value pair, which can be specified both inside the project element and inside the target element (in the second case, the property value will be set only when the target element in which the property is located).



<property name="zip.filename" value="..\build\application.zip" />



Property values ​​can be passed through command line parameters when running NAnt (parameter: -D: property = value)



NAnt -buildfile:..\main.build -D:zip.filename=..\build\application.zip



For a task, you can specify a list of tasks on which it depends (for the correct order of execution) and the conditions under which its execution is allowed. For most actions, you can also specify the condition for their execution.



<target name="pack" depends="compile, configure" "${property::exists('zip.filename')}" >

...

</target>




As you can see in the previous example, you can use embedded expressions as parameters of the elements of the configuration file. For example, the expression "$ {property :: exists ('zip.filename')}" checks whether the property "zip.filename" is defined. The list of expressions can be found here .

It is also worth noting that when editing build files in Visual Studio (2008, 2010) there is syntax highlighting (similar to XLM files) and IntelliSense works (including for embedded expressions).



Let's start writing a build file.



Here is our action plan for building the application:

1. Compile the application from source codes;

2. Delete the "extra" files (for example, * .aspx.cs, * .csproj, etc.) and copy the missing (not used during development);

3. Configure the application;

4. Run the scripts to bring the database to the desired state for the application;

5. Run unit tests

6. Copy the application to the working directory.



1. Building the application from source codes



There are several ways to compile an application using NAnt. The most convenient of them is to use for compiling MsBuild (only for compiling).

The fact is that, in any case, the application will be compiled using a compiler (for example, csc.exe for C #). To build a project, the compiler needs to pass the paths to all files included in the project, a list of all connected external assemblies (References), a list of resource files, etc. Those. the compiler does not know how to handle files like * .sln and * .csproj and all parameters must be passed to it by hand.

The * .sln files and project files are nothing but the MsBuild configuration files that Visual Studio automatically generates while working with the project. Accordingly, when you press Ctrl + Shift + B or build a project in VS in any other way, Visual Studio uses MsBuild to launch the compiler with the necessary parameters.

Accordingly, the easiest way to build an application from source codes is, like VS, to run MsBuild, passing in the parameters the path to the .sln file or the project file. NAnt allows you to do this in the following ways:



- With the EXEC command



<property name="msbuild.path" value="C:/WINDOWS/Microsoft.NET/Framework/v3.5/MSBuild.exe" />

<exec program="${msbuild.path}">

<arg value="src\test.sln" />

<arg value="/p:Configuration=Release" />

<arg value="/p:WarningLevel=0" />

</exec>




The EXEC command allows you to run any program. The “arg” elements correspond to the command line parameters.



- Using the MSBUILD command located in the NAntContrib project. In order to use this method, you need to put the NAnt.Contrib.Tasks.dll library in the folder with the NAnt files. The libraries on which it depends.



<msbuild project="src\test.sln">

<property name="Configuration" value="Release" />

<property name="Platform" value="Any CPU" />

</msbuild>




In this case, you do not need to specify the path to MsBuild. In the NAnt settings, there are paths to various utilities, depending on the version of .NET (including to MsBuild). When executing the MsBuild command, the desired path will be automatically used. The “property” elements correspond to the command line parameters.



- You can also use the commands CSC (for C #), VBC (for VB), etc., which will be similar to manually running the compiler. A description of these commands can be found in the NAnt documentation (for example, you can read about the csc command here ).



In my opinion, the most convenient way is to use the MSBUILD command from the NAntContrib library. Immediately the question arises: if we use MsBuild to build the application, why not perform all other actions using it. As I said before, the differences between MsBuild and NAnt are not very large, and the choice largely depends on the preferences of the developer. Personally, I prefer to use NAnt. Ready to discuss this issue in the comments.



2. Preparing the site for display



When compiling, a number of files that are needed during development but not needed during application operation (for example, * .csproj, * .cspx.cs, * .pdb, etc.) remain in the folder with the web application. Before laying out, you need to clean the application from these files. Again, there are several ways to do this.



- Use the WebDeploymentProject project ( for VS2008 , for VS2010 ). A WebDeploymentProject type project can only be created for an existing web application project. In Visual Studio, in the properties of the WebDeploymentProject project, you can configure various parameters of the application (for example, signing assemblies, automatically creating a virtual directory in IIS, etc.). If you try to subtype a type project in a WebDeploymentProject, then you will get a ready-to-work application with output that is associated with WebDeploymentProject and which will not have the files necessary for development.



- Use the utility aspnet_compiler.exe.

WebDeploymentProject, like other VS projects, is essentially just a configuration file for MsBuild. During the build of the WebDeploymentProject project, application preparation for work is performed using the aspnet_compiler.exe utility (also, depending on the WebDeploymentProject settings, aspnet_merge.exe, aspnet_regiis.exe, etc. can be run). Nothing prevents us from running this utility with our hands. In NAnt, this can be done in the following way:



<property name="aspnet_compiler.dir" value="C:\Windows\Microsoft.NET\Framework64\v2.0.50727\" />

<property name="publish.project.dir" value="C:\Work\MyWebSite\" />

<property name="publish.output.dir" value="C:\Published\MyWebSite\" />

<exec program="aspnet_compiler.exe" basedir="${aspnet_compiler.dir}" >

<arg value="-p" />

<arg value="${publish.project.dir}" />

<arg value="${publish.output.dir}" />

</exec>


The disadvantage of this method is that you need to explicitly specify the path to aspnet_compiler.exe.



You can learn more about the aspnet_compiler.exe utility here .

Description of the ASP.NET command line tools here .



- Hands to delete unnecessary files (or copy the application to another folder, except for unnecessary files, so as not to spoil the folder with the source codes). With NAnt, this can be done with the COPY command:

<copy todir = "$ {destination.dir}">

<fileset basedir = "$ {app.dir}">

<include name = "** \ *" />

<exclude name = "** \ *. cs" />

<exclude name = "** \ *. scc" />

<exclude name = "** \ *. pdb" />

<exclude name = "** \ *. csproj" />

<exclude name = "** \ *. vspscc" />

<exclude name = "** \ PageList.xml *" />

<exclude name = "** \ *. csproj.user" />

</ fileset>

</ copy>

On the one hand, this method is less convenient than WebDeploymentProject, on the other hand, here we have more control. In general, you decide what is best suited.



To be continued..?

Source: https://habr.com/ru/post/101183/



All Articles