AzsBuildUtilities.psm1
function WriteMessage( [Parameter(Mandatory=$true)] [string] $Message ) { Write-Host ("[{0}]: {1}" -f (Get-Date), $Message) } function GetBuildTrackerPageWithRetry( [Parameter(Mandatory=$true)] [string] $BuildTrackerUrl ) { $attempt = 1 do { $response = Invoke-WebRequest -Uri $BuildTrackerUrl -UseDefaultCredential $responseCode = $response.StatusCode $attempt += 1 if ($responseCode -ne 200) { WriteMessage ("[WARNING] Unexpected response code from BuildTracker: {0}. Retrying..." -f $responseCode) } } while ($responseCode -ne 200 -and $attempt -lt 3) if ($responseCode -ne 200 -and $attempt -ge 3) { throw "Error getting build tracker page with 3 retries." } return $response.Content } function GetJobStatus( [Parameter(Mandatory=$true)] [string] $BuildTrackerPageContent ) { $statusRegex = [regex]"<B>Status: </B><font color='\w+'><b>(\w+)</b></font>" $match = [regex]::Match($BuildTrackerPageContent, $statusRegex).captures.groups[1].value if ($match -eq $null) { throw "Could not find job status on BuildTracker page" } return $match } function GetReddogPath( [Parameter(Mandatory=$true)] [string] $BuildTrackerPageContent ) { $reddogRegex = [regex]"<BR><B>Drop: </B><a href='(.+)'>" $reddogPath = [regex]::Match($BuildTrackerPageContent, $reddogRegex).captures.groups[1].value if ($reddogPath -eq $null) { throw "Could not find reddog location on BuildTracker page" } return $reddogPath } function CopyBuildToShare( [Parameter(Mandatory=$true)] [string] $ShareRootPath, [Parameter(Mandatory=$true)] [string] $BuildTrackerPageContent ) { WriteMessage "Finding build packages..." $reddogPath = GetReddogPath($BuildTrackerPageContent) $packagesPath = $reddogPath + "\packages" WriteMessage ("reddog packages path: {0}" -f $packagesPath) $shareOutputPath = $packagesPath -replace "\\\\reddog",$ShareRootPath WriteMessage "Generating share output path..." WriteMessage ("Share output path: {0}" -f $shareOutputPath) if (Test-Path $shareOutputPath) { WriteMessage "Share output path already exists! Removing..." Remove-Item -Recurse -Path $shareOutputPath } WriteMessage "Copying to share..." Copy-Item -Recurse -Force -Path $packagesPath -Destination $shareOutputPath return $shareOutputPath } function GetShareLatestPath( [Parameter(Mandatory=$true)] [string] $ShareOutputPath ) { $latestPath = $ShareOutputPath -replace "\\[^\\]+\\packages", "_latest" if ($latestPath -eq $null) { throw "Could not find generate latest path" } return $latestPath } function UpdateLatestPath( [Parameter(Mandatory=$true)] [string] $ShareOutputPath ) { $latestPath = GetShareLatestPath($ShareOutputPath) $latestPackagesPath = $latestPath + "\packages" WriteMessage ("Latest packages path: {0}" -f $latestPackagesPath) if (Test-Path $latestPath) { WriteMessage "Latest path already exists! Removing..." Remove-Item -Recurse -Path $latestPath } WriteMessage "Copying to latest packages path..." Copy-Item -Recurse -Force -Path $ShareOutputPath -Destination $latestPackagesPath return $latestPackagesPath } function IsJobInProgress( [Parameter(Mandatory=$true)] [string] $JobStatus ) { return $JobStatus -eq "Queued" -or $JobStatus -eq "Submitted" -or $JobStatus -eq "Sequenced" -or $JobStatus -eq "Pending" -or $JobStatus -eq "Running" } function IsJobCompleted( [Parameter(Mandatory=$true)] [string] $JobStatus ) { return $JobStatus -eq "Completed" } function IsJobFailed( [Parameter(Mandatory=$true)] [string] $JobStatus ) { return $JobStatus -eq "Failed" -or $JobStatus -eq "Aborted" } function GetBuildTrackerUrl( [Parameter(Mandatory=$true)] [Object[]] $BuildreqOutput ) { $lines = $BuildreqOutput.Split([Environment]::NewLine) $buildUrlRegex = [regex]"Build (http://wabt/BuildTracker/Jobs/LegSummary.aspx\?Id=\d+) started$" # Find the build URL, checking each line of output in reverse for ($i = 0; $i -lt $lines.Count; $i++) { $captures = [regex]::Match($lines[$i], $buildUrlRegex).captures if ($captures -ne $null -and $captures.Groups.Count -ge 2) { $buildUrl = $captures.Groups[1].Value # Greedily take the first match if ($buildUrl -ne $null) { return $buildUrl } } } # If we reach here, we never found a build URL throw "Could not find BuildTracker URL in buildreq output" } function Watch-Build( [Parameter(Mandatory=$true)] [string] $BuildTrackerUrl ) { WriteMessage ("Watching build tracker job @ `"{0}`"..." -f $BuildTrackerUrl) do { $pageContent = GetBuildTrackerPageWithRetry($BuildTrackerUrl) $status = GetJobStatus($pageContent) WriteMessage ("Current job status: {0}" -f $status) $continue = IsJobInProgress($status) if ($continue) { Start-Sleep -Seconds 60 } } while ($continue) if ($(IsJobFailed($status)) -eq $true) { Write-Error "Job failed!" return $false } if ($(IsJobCompleted($status)) -eq $false) { Write-Error "Job did not complete." return $false } return $true } function Watch-BuildAndCopyToShare( [Parameter(Mandatory=$true)] [string] $BuildTrackerUrl, [string] $ShareRootPath = "\\ecg\teams\Solutions\AzureStack\Data\jecollet", [Switch] $ShutdownOnCompletion ) { if ($(Watch-Build($BuildTrackerUrl)) -eq $false) { return $false } WriteMessage "Job completed!" $pageContent = GetBuildTrackerPageWithRetry($BuildTrackerUrl) $outputPath = CopyBuildToShare -ShareRootPath $ShareRootPath -BuildTrackerPageContent $pageContent if ($outputPath -eq $null) { Write-Error ("Error copying to share: {0}!" -f $ShareRootPath) return $false } WriteMessage "Updating latest path..." UpdateLatestPath($outputPath) WriteMessage "Openning share output path..." Start $outputPath if ($ShutdownOnCompletion -eq $true) { WriteMessage "Shutdown on completion is enabled. Shutting down in 60 seconds..." Shutdown /f /s /t 60 } return $true } function Start-BuildAndCopyToShare( [string] $ShareRootPath = "\\ecg\teams\Solutions\AzureStack\Data\jecollet", [Switch] $Publish, [Switch] $Sign, [Switch] $ShutdownOnCompletion ) { WriteMessage ("Building repo and outputting to share `"{0}`"" -f $ShareRootPath) $buildReqCommand = "buildreq" if ($Sign -eq $true) { WriteMessage "Code signing enabled." $buildReqCommand += " --signing" } else { WriteMessage "Code signing disabled." } if ($Publish -eq $true) { WriteMessage "Code publishing enabled." $buildReqCommand += " --publish" if ($Sign -eq $false) { WriteMessage "[WARNING] Are you sure you want to publish unsigned code?" } } else { WriteMessage "Code publishing disabled." } WriteMessage ("Calling buildreq with command `"{0}`"..." -f $buildReqCommand) $buildReqOutput = Invoke-Expression $buildReqCommand Write-Host $buildReqOutput $buildTrackerUrl = GetBuildTrackerUrl($buildReqOutput) return $(Watch-BuildAndCopyToShare -ShutdownOnCompletion:$ShutdownOnCompletion -BuildTrackerUrl $buildTrackerUrl -ShareRootPath $ShareRootPath) } Export-ModuleMember Watch-Build, Watch-BuildAndCopyToShare, Start-BuildAndCopyToShare |