Team Service Erweiterung – Download Artifacts

Mit dem Tool Download Artifacts können Sie einzelne Artifacts auf den lokalen Zielsystemen, auf dem die Build Agent installiert sind, bereitstellen.

Über den folgenden Link bekommen Sie das komplette Paket Download Artifacts – als ZIP bereitgestellt. Das Skript ist kostenfrei und kann nach Ihren wünschen angepasst werden. Downlaod Team Service Erweiterung Downlaod Artifacts

  • Als Vorraussetzung ist wie beschrieben, dass der Build Agent auf dem Zielsystem installiert ist. Eine Anleitung für die Konfiguration finden Sie hier: Deploy an agent on Windows
  • Entpacken Sie das Zip und Importieren den PowerShell Task. Eine Beschreibung für den Import finden Sie hier:  Eigene TFS Build / Release Aufgaben bereitstellen
  • Erstellen Sie eine neue Release definition. Infos finden Sie hier: Define your CD release process
  • Fügen Sie jetzt Ihre Aufgaben wie SPS Deploy hinzu.
  • Geben Sie nun alle notwendigen Werte ein und führen die Bereitstellung aus.

Folgende Parameter können Sie mitgeben:

  • : Artifactsnamen
Team Service Erweiterung Download Artifacts
Team Service Erweiterung Download Artifacts

Datei DownlaodArtifacts.ps1

[CmdletBinding(DefaultParameterSetName = ‚None‘)]
param(
[Parameter()]
[string]$ArtifactNames = „*“,
[Parameter()]
[string]$ArtifactDestinationFolder
)

$ErrorActionPreference = „Stop“
Write-Output „Artifact Names: $ArtifactNames“
Write-Output „Artifact Destination Folder: $ArtifactDestinationFolder“

$buildDefinitionName = $Env:BUILD_DEFINITIONNAME
if ([string]::IsNullOrEmpty($ArtifactDestinationFolder))
{
$ArtifactDestinationFolder = $Env:SYSTEM_DEFAULTWORKINGDIRECTORY
}

Add-Type -assembly ’system.io.compression.filesystem‘
#————————–CreateCleanDirectory———————-

function CreateOrCleanDirectory($DirectoryPath)
{
if ([IO.Directory]::Exists($DirectoryPath))
{
$DeletePath = $DirectoryPath + „\*“
Remove-Item $DeletePath -recurse -Force
[IO.Directory]::CreateDirectory($DirectoryPath) | Out-Null
}
else
{
[IO.Directory]::CreateDirectory($DirectoryPath) | Out-Null

}
}

[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12

$artifactNamesArray = [regex]::split($ArtifactNames, „;“)

$vssEndPoint = Get-ServiceEndPoint -Name „SystemVssConnection“ -Context $distributedTaskContext
$personalAccessToken = $vssEndpoint.Authorization.Parameters.AccessToken
$headers = New-Object „System.Collections.Generic.Dictionary[[String],[String]]“
$headers.Add(„Authorization“ ,“Bearer $personalAccessToken“)

$tfscollection = $Env:SYSTEM_TEAMFOUNDATIONCOLLECTIONURI
$tfsUrl = $Env:SYSTEM_TEAMFOUNDATIONCOLLECTIONURI
$relAPIUrl = $Env:SYSTEM_TEAMFOUNDATIONSERVERURI + $Env:SYSTEM_TEAMPROJECT
$releaseId = $Env:RELEASE_RELEASEID

$releaseInfoURI = $relAPIUrl +’/_apis/release/releases/‘ + $releaseId + ‚?api-version=3.0-preview.2‘

#get the release
Write-Output „Get Releseinfo: Invoke-RestMethod -Uri $releaseInfoURI -Method GET -Headers $headers“
$releaseInfo = Invoke-RestMethod -Uri $releaseInfoURI -Method GET -Headers $headers

# Clean Destination
CreateOrCleanDirectory -DirectoryPath $ArtifactDestinationFolder

foreach ($linkedArtifact in $releaseInfo.artifacts)
{
<#$BuildDefUri = ($tfsURL + ‚/_apis/build/definitions?api-version=2.0&name=‘ + $buildDefinitionName) #Get Build Defintion ID Write-Host „REST Call [$BuildDefUri]“ $buildDefinition = Invoke-RestMethod -Uri $BuildDefUri -Method GET -Headers $headers #-UseDefaultCredentials $buildDefinitionId = ($buildDefinition.value).id;#>
$buildDefinitionId = $linkedArtifact.definitionReference.definition.id
$buildDefinitionName = $linkedArtifact.alias
$buildDefinitionProject = $linkedArtifact.definitionReference.project.name
Write-Output „Build Def.Id: [$buildDefinitionId]“
Write-Output „Build Def.Name: [$buildDefinitionName]“
Write-Output „Build Def.Project Name: [$buildDefinitionProject]“

$buildId = $linkedArtifact.definitionReference.version.id
Write-Host „Build Id: [$buildId]“

#get artifacts
$buildArtifactsURI = $tfsURL + $buildDefinitionProject + ‚/_apis/build/builds/‘ + $buildId + ‚/artifacts?api-version=2.0‘
Write-Output „REST Call [$buildArtifactsURI]“
$buildArtifacts = Invoke-RestMethod -Uri $buildArtifactsURI -Method GET -Headers $headers #-UseDefaultCredentials

$dropDestination = join-path $ArtifactDestinationFolder $buildDefinitionName

# Clean Destination
CreateOrCleanDirectory -DirectoryPath $dropDestination

foreach($buildArtifact in $buildArtifacts.value)
{
$buildartifactFullName = join-path $buildDefinitionName $buildArtifact.name # Createing full artifact naem similar to ArtfactSourceAlias\Drop1

foreach($artifactPathName in $artifactNamesArray) # Try for each Artifact Path
{
$artifactPathPartsArray = [regex]::split($artifactPathName, „\\“)

if(($artifactPathName -eq „*“) -or ($artifactPathName -eq $buildartifactFullName) -or (($artifactPathPartsArray[0] -eq $buildDefinitionName ) -and ($artifactPathPartsArray[1] -eq $buildArtifact.name)))
{
<# Only * (default) as artifat path allow all artifacts download. Artifact name allows to download given artifact. Multiple artifacts can be specified with pattern Drop1;Drop2 Artifact name with subpath allows to download sub item of a given artifact. Multiple can be specified with pattern ArtifactsourceAlias\Drop1\MyWebProj;ArtifactsourceAlias\Drop1\ReleaseNote.html;ArtifactsourceAlias\Drop2;ArtifactsourceAlias\Drop3\MyWebProj2 Wild cards in paths are NOT Supported. * value as default supported to specify all artifacts. #>
Write-Output „Downloading artifact: “ + $artifactPathName

if($buildArtifact.resource.type -eq „FilePath“)
{
# UNC Path
$droppath = $buildArtifact.resource.downloadUrl -replace „file://“,“\\“
$droppath = $droppath -replace „%20″,“ “
$droppath = $droppath -replace „/“,“\“

if (($artifactPathName -ne „*“) -and ($artifactPathName -ne $buildartifactFullName))
{
for($i=1;$i -lt ($artifactPathPartsArray.Length);$i++)
{
$dropDestination = Join-Path $dropDestination $artifactPathPartsArray[$i]
$droppath = Join-Path $droppath $artifactPathPartsArray[$i]
}

#Subpath used – Create the destination path by drop folder
if (-not([IO.Directory]::Exists($dropDestination)))
{
Write-Output „Creating destination path: “ + $dropDestination
[IO.Directory]::CreateDirectory($dropDestination) | Out-Null
}

}
else
{
$droppath = Join-Path $droppath $buildArtifact.name # Creating drop path with specified artifact path
}

$start_time = Get-Date
Write-Output „Downloading run: Copy-Item -Path $droppath -Destination $dropDestination -Recurse -Verbose“
Copy-Item -Path $droppath -Destination $dropDestination -Recurse -Verbose
Write-Output „Time taken: $((Get-Date).Subtract($start_time).Seconds) second(s)“
}
else
{ # Drop available as server

if (($artifactPathName -eq „*“) -or ($artifactPathName -eq $buildartifactFullName))
{
$dropArchiveDestination = Join-path $dropDestination („{0}.zip“ -f $buildArtifact.name)
$droppath = $buildArtifact.resource.downloadUrl # If only artifact name default download url can be used
}
else
{
$tempArtifactPath= $buildArtifact.name
for($i=2;$i -lt ($artifactPathPartsArray.Length);$i++)
{
$tempArtifactPath = Join-Path $tempArtifactPath $artifactPathPartsArray[$i]
Write-Output „temp artifact path: “ + $tempArtifactPath
}

$dropArchiveDestination = Join-path $dropDestination („{0}.zip“ -f ($tempArtifactPath -replace „\\“, „.“))
# for sub path generate download url. Using the data ID.
$droppath = $tfscollection + „_apis/resources/Containers/“ + $buildArtifact.resource.data.Split(„/“)[1] + „?itemPath=“ + ($tempArtifactPath -replace „\\“, „%2F“) + „&`$format=zip“
}

$start_time = Get-Date
Write-Output „Downloading run: Invoke-WebRequest -uri $droppath -OutFile $dropArchiveDestination -Headers $headers“
Invoke-WebRequest -uri $droppath -OutFile $dropArchiveDestination -Headers $headers #-UseDefaultCredentials
Write-Output „Time taken: $((Get-Date).Subtract($start_time).Seconds) second(s)“

Write-Output „Extracting artifact: “ + $buildArtifact.name
Write-Output „Extracting to: “ + $dropDestination
[io.compression.zipfile]::ExtractToDirectory($dropArchiveDestination, $dropDestination)
Write-Output „Extracting completed for: {0} to: {1}“ -f $buildArtifact.name, $dropDestination
}
}
}
}
}
Write-Output „##vso[task.complete result=Succeeded;]DONE“


Weitere Links:
Release Management

Team Service Erweiterung – Application Pool Start / Stop

Team Service Erweiterung – Deploy

Team Service Erweiterung – Remote Deploy