Deploy a .NET project with powershell and git

In this topic I want to share my experience in writing a powershell script to compile and publish a .NET project.

I use Git and a GitHub repository, so in my mind the script should restore the nuget packages, build the project with MSBuild, take the last tag (version) from the master branch of the GitHub repository and apply (if valid) the version found in the tag in the project assembly.

Finally, it have to produce a folder with the deployment package.

So, let’s start with the steps to implement this script.

Project configuration

Before to write the powershell script, I need to setup the configuration for the project deploy.

So right click on the project (in my case a web project) and select Publish, it will appear this window:

configuration1

Then we need to create a new profile and select (in my case) the folder option:

configuration2

After that, we will have the a new pubxml file in the solution:

configuration3

We will use this file in our powershell script.

Source code versioning

Now it’s the time to implement the script and the first step that I want to do is apply a version to the assembly and use it in the name of the folder where the application will be published.

My repository provider is GitHub and everytime I release a version on the master branch, I apply a tag on the commit with the release number, like 0.2.0.

So my script have to be able to get the last tag from the master branch and apply it to the assembly.

We have some options to apply the version on a .NET application, the most standard way is use the AssemblyInfo.cs file, where we could have attributes like AssemblyVersion, AssemblyFileVersion, and also AssemblyInformationalVersion.

If the first two attributes need to have a version in standard format, the last attribute leave us the freedom to use a custom versioning, for example if we want to include in the versioning the current date, or the the name of the git branch and so on.

For this reason I’ll update the AssemblyInformationalVersion.

So, first of all I need to retrieve the version from the tag applied on the GitHub repository:

$version = $(git describe --abbrev=0 --tag)

By executing this git command from the solution folder, I can retrieve the last tag applied and use it as the new version, or part of it.

Now I can check if the version has a specific format, for example I want that the version is composed by two or three numbers:


$versionRegex1 = "\d+.\d+.\d+"
$versionData1 = [regex]::matches($version,$versionRegex1)
$versionRegex2 = "\d+.\d+"
$versionData2 = [regex]::matches($version,$versionRegex2)

if ($versionData1.Count -eq 0 -and $versionData2.Count -eq 0) { Throw "Version " + $version + " has a bad format" }

If these checks are satisfied, I can apply the version and I search the AssemblyVersion.cs files in the solution:


$files = Get-ChildItem $sourceDirectory -recurse -include "*Properties*" |
?{ $_.PSIsContainer } |
foreach { Get-ChildItem -Path $_.FullName -Recurse -include AssemblyInfo.* }

If I have found the files, I can apply the new version:


if ($files) {
Write-Host "Updating version" $version
foreach ($file in $files) {
$filecontent = Get-Content($file)
attrib $file -r
$informationalVersion = [regex]::matches($filecontent,"AssemblyInformationalVersion\(""$version""\)")

if ($informationalVersion.Count -eq 0) {
Write-Host "Version " $version " applied to " $file
$filecontent -replace "AssemblyInformationalVersion\(.*\)", "AssemblyInformationalVersion(""$version"")" | Out-File $file
}

}
}

I check that the attribute has not the new version value yet, otherwise nothing needs to do.

The hardest step is completed, now I can build and deploy my project.

Build and deploy

I order to build the project I need MSBuild 15, that in my case is already installed with Visual Studio 2017.

But, if you haven’t, you can download it from the Microsoft web site and this link.

If you have some nuget packages in the project, in order to restore the packages before to build you need the nuget executable as well, and you can download it from this link.

Now we are ready to write the code to build and deploy the project:


$msbuild = "C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\MSBuild\15.0\Bin\msbuild.exe"
$solutionFolder = $PSScriptRoot + "..\..\"
$solutionFile = $solutionFolder + "\EFContextMock.sln"
$projectFile = $solutionFolder + "\WebApp\WebApp.csproj"
$nuget = $solutionFolder + "\nuget\nuget.exe"
$version = $(git describe --abbrev=0 --tag)
$publishUrl = "c:\temp\EFContextMock\" + $version

SetAssemblyInfo $solutionFolder $version

Write-Host "Restore packages"

& $nuget restore $solutionFile

if ($LastExitCode -ne 0){
$exitCode=$LastExitCode
Write-Error "Build failed!"
exit $exitCode
}
else{
Write-Host "Build succeeded"
}

Write-Host "Building"

& $msbuild $projectFile /p:DeployOnBuild=true /p:PublishProfile=Publish.pubxml /p:PublishUrl=$publishUrl

if ($LastExitCode -ne 0){
$exitCode=$LastExitCode
Write-Error "Build failed!"
exit $exitCode
}
else{
Write-Host "Build succeeded"
}

After some variables setup I assign the version with the code discussed above and I restore the nuget packages.

The msbuild command uses the pubxml file created in the first step; one of the parameters of the command is the PublishUrl, that in my case is a local path.

You can find the complete powershell script here.

Advertisements
Deploy a .NET project with powershell and git

One thought on “Deploy a .NET project with powershell and git

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s