Monday, 25 June 2018

Packaging "Assemblies in GAC Installed with SDKs" in Build and Getting Deployed to Target Machine GAC

There can be projects depending on assemblies in Global Assembly Cache installed with may be a internal company SDK, which would even be installed in developer machines and in build servers. These assemblies should be packaged with the project and deployed to the GAC of target machines such as QA,staging and Production etc.  as well. Since the code repo does not include such assemblies in the build server it may be required to extract those assemblies from GAC and packaged with the builds. Let’s see how we can get the assemblies in GAC packaged and get deployed to targets, using VSTS build and release management.
There is a PowerShell module developed by Lars Truijens available in PowerShell gallery and source is in GitHub. This module has really useful commands which does not depend in the gacutil coming with Visual Studio, which is  not useful in this scenario as gacutil cannot be used in deployment targets even if there is a possibility of usage of it in the build servers, since we cannot install Visual Studio in deployment targets Smile.
You can use below PowerShell script in VSTS/TF build to extract the required assemblies using assembly names (wild cards supported). This script makes sure NuGet package provider exists and then installs the PowerShell Module GAC, before using the GAC related commands.
param (
    [string] $AssemblyMask,
    [string] $AssemblyTargetPath
)

Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force

Install-Module Gac -Force

md -Path $AssemblyTargetPath

$AssemblyMaskValues = $AssemblyMask.Split(';')

foreach ($AssemblyMaskValue in $AssemblyMaskValues)
{
    Get-GacAssembly $AssemblyMaskValue | Get-GacAssemblyFile | Copy-Item -Destination $AssemblyTargetPath -Verbose
}

You can use the script as inline PowerShell task as shown below. Pass the arguments for assembly mask and the path to download assemblies from GAC. (The latest version of out of the box PowerShell task in VSTS does not have Arguments, you can use the extension from VS Marketplace which has a inline PowerShell task which is really flexible)
-AssemblyMask '$(DemoSDKAssemblyMask)' -AssemblyTargetPath '$(GacAssemblyPath)'image
These variables can be configured similar to shown below. You can use .nuspec files to make sure the assemblies are packaged into NuGet package if you are using NuGet packages as the build artifact. Or you can copy the assemblies to build drop by putting them in build staging directory.image
Then in your release definition you can use the script below to deploy the assemblies to the target machine GAC. This script also makes sure NuGet package provider exists and then installs the PowerShell Module GAC, before using the GAC related commands.
param (
    [string] $AssemblyTargetPath
)

Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force

Install-Module Gac -Force

$items = Get-ChildItem -Path $AssemblyTargetPath

 
foreach ($item in $items)
{
    $fullAssemblyPath = Join-Path $AssemblyTargetPath $item.Name
    Write-Host 'Adding to GAC ' $fullAssemblyPath

    Add-GacAssembly -Path $fullAssemblyPath -Force -Verbose
}
In the release definition you have to provide the path to the download and copied location of the GAC assemblies in the target machine.image
The assemblies will be deployed to GAC in the target machine when the release is executed. If you are using Octopus deploy same PowerShell script can be used to get the assemblies deployed to GAC.

No comments:

Popular Posts