Reputation: 13006
I've read a few good posts on automating build processes, however, what I'm interested in is not just a build process, but publishing.
I have several websites and services that use a base model. When I change that model (which won't happen very often), all sites/services will have to be rebuilt and published to their appropriate target directories (already contained in their config).
All project folders exist in one folder.
The approach I am considering is to use MSBuild to run a script from the the main folder, with a named list of projects to build/publish.
I have found a good example on creating a build script for MSBuild here, however, this only satisfies the build for one project.
How would I have the process go through a named list of projects/directories to perform the same build/publish script on?
Thanks.
Upvotes: 0
Views: 3011
Reputation: 13006
So I finally had time to take a look at this again.
I created the following MSBuild script that resides in a folder at the same level of all the websites I have.
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name ="DeleteFiles">
<Delete Files="..\$(ProjectName)\$(ProjectName)\obj\debug\$(ProjectName).dll"></Delete>
<Delete Files="..\$(ProjectName)\$(ProjectName)\obj\release\$(ProjectName).dll"></Delete>
<Delete Files="..\$(ProjectName)\$(ProjectName)\bin\$(ProjectName).dll"></Delete>
<Delete Files="..\$(ProjectName)\$(ProjectName)\bin\$(ProjectName).pdb"></Delete>
</Target>
<Target Name="Compile" DependsOnTargets="DeleteFiles">
<MSBuild Projects="..\$(ProjectName)\$(ProjectName)\$(ProjectName).csproj"
Targets="Clean;Build"
Properties="OutputPath=..\$(ProjectName)\bin"/>
</Target>
<Target Name="Deploy" DependsOnTargets="Compile">
<MSBuild Projects="..\$(ProjectName)\$(ProjectName)\$(ProjectName).csproj"
Targets="ResolveReferences;_CopyWebApplication"
Properties="OutDir=C:\inetpub\wwwroot\$(ProjectName)\bin\;WebProjectOutputDir=C:\inetpub\wwwroot\$(ProjectName)" />
</Target>
</Project>
And is called like this:
msbuild build.xml /p:ProjectName="websitetopublish.com" /v:n
Works great for one site, however I'd like a batch-related solution that reads a text file. For each entry in that text file execute the build process.
I easily write a .Net console app to to this, but overkill, and I'd like to know how to accomplish this using some for looping mechanisms in batch files.
Upvotes: 0
Reputation: 13006
The final, reusable solution is as follows.
Recap:
I have several sites in a root folder who's directories and project file names are all named the value of the website. I want to be able to publish all sites (or a selected list) from the command line - running a script. The websites are then to be published to my IIS server directories.
First, create a MSBuild script that takes in the parameter of the website name:
<?xml version="1.0" encoding="utf-8" ?>
<Project DefaultTargets="Compile,Deploy" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name ="DeleteFiles">
<Delete Files="..\$(ProjectName)\$(ProjectName)\obj\debug\$(ProjectName).dll"></Delete>
<Delete Files="..\$(ProjectName)\$(ProjectName)\obj\release\$(ProjectName).dll"></Delete>
<Delete Files="..\$(ProjectName)\$(ProjectName)\bin\$(ProjectName).dll"></Delete>
<Delete Files="..\$(ProjectName)\$(ProjectName)\bin\$(ProjectName).pdb"></Delete>
</Target>
<Target Name="Compile" DependsOnTargets="DeleteFiles">
<MSBuild Projects="..\$(ProjectName)\$(ProjectName)\$(ProjectName).csproj"
Targets="Clean;Build"
Properties="OutputPath=..\$(ProjectName)\bin"/>
</Target>
<Target Name="Deploy" DependsOnTargets="Compile">
<MSBuild Projects="..\$(ProjectName)\$(ProjectName)\$(ProjectName).csproj"
Targets="ResolveReferences;_CopyWebApplication"
Properties="OutDir=C:\inetpub\wwwroot\$(ProjectName)\bin\;WebProjectOutputDir=C:\inetpub\wwwroot\$(ProjectName)" />
</Target>
</Project>
Next, create a text file with one website name per line. This can be easily generated by doing a "dir > sites.txt" then column editing out superfluous content.
ie.
site1.com
site2.com
site3.com
site4.com
Lastly, create a batch file that iterates through the list contained in sites.txt, and executes the MSBuild script:
@echo --------------------------------------------
@echo -- Iterating through list in sites.txt --
@echo --------------------------------------------
for /f %%X in (sites.txt) do msbuild build.xml /p:ProjectName="%%X" /v:n
This solution resides on in a directory on the same level as the rest of the websites from the root, which why the "..\$(ProjectName)" in the build script.
Great way of publishing a bunch of sites, and hope this helps someone.
Upvotes: 1
Reputation: 10602
Use an <ItemGroup />
element with custom metadata resulting in something like follows:
<ItemGroup>
<ProjectToPublish Include="WebApplication1\WebApplication1.csproj" >
<OutputDir>OutputDir1</OutputDir>
</ProjectToPublish>
<ProjectToPublish Include="WebApplication2\WebApplication2.csproj" >
<OutputDir>OutputDir2</OutputDir>
</ProjectToPublish>
</ItemGroup>
<Target Name="Publish" Inputs="@(ProjectsToPublish)" Outputs="%(Identity).Dummy">
<RemoveDir Directories="%(OutputDir)" ContinueOnError="true" />
<MSBuild Projects="%(Identity)"
Targets="ResolveReferences;_CopyWebApplication"
Properties="WebProjectOutputDir=$(OutputDir);
OutDir=%(OutputDir)\" />
</Target>
Upvotes: 0