* Add dockerfile and test so we can test simple remoting behaviors this docker file creates an image which can be used to test remoting with containers. We start with the microsoft/windowsservercore image and then set up the system for testing by adding a user, setting up configuration for basic auth, installing PowerShell Core, and creating a configuration endpoint for PSCore. The tests are very simple; it retrieve $PSVersionTable.PSVersion in the following connections: Full -> Full Full -> Core Core -> Full Core -> Core * Add new file to bootstrap the docker image fix the tests to be more resilient to changes in the version of the PSCore package * update script to use local user cmdlets rather than net.exe also remove pscore.msi at the end of the image build process to save space * clean up commented lines and remove an unused parameter from one of the functions also use constants more consistently * remove reference to docker image name by string and use variable instead.
292 lines
8.3 KiB
PowerShell
292 lines
8.3 KiB
PowerShell
param ( [switch]$Force, [switch]$UseExistingMsi )
|
|
|
|
$script:Constants = @{
|
|
AccountName = 'PowerShell'
|
|
UrlBase = 'https://ci.appveyor.com'
|
|
ApiUrl = 'https://ci.appveyor.com/api'
|
|
ProjectName = 'powershell-f975h'
|
|
TestImageName = "remotetestimage"
|
|
MsiName = "PSCore.msi"
|
|
Token = "" # in this particular use we don't need a token
|
|
}
|
|
|
|
function Get-AppVeyorBuildArtifact {
|
|
[CmdletBinding()]
|
|
param(
|
|
[Parameter(Mandatory)]
|
|
[string]$build,
|
|
[string]$downloadFolder = '.',
|
|
[string]$artifactFilter = '*.msi',
|
|
[string]$artifactLocalFileName = $Constants.MsiName
|
|
)
|
|
|
|
$headers = @{
|
|
'Authorization' = "Bearer {0}" -f $Constants.Token
|
|
'Content-type' = 'application/json'
|
|
}
|
|
|
|
# get project with last build details
|
|
$URL = "{0}/projects/{1}/{2}/build/$build" -f $Constants.ApiUrl,$Constants.AccountName,$Constants.ProjectName,$build
|
|
$project = Invoke-RestMethod -Method Get -Uri $URL -Headers $headers
|
|
|
|
# we assume here that build has a single job
|
|
# get this job id
|
|
$jobId = $project.build.jobs[0].jobId
|
|
|
|
# get job artifacts (just to see what we've got)
|
|
$URL = "{0}/buildjobs/{1}/artifacts" -f $Constants.ApiUrl,$jobid
|
|
$artifacts = Invoke-RestMethod -Method Get -Uri $URL -Headers $headers
|
|
|
|
# here we just take the first artifact, but you could specify its file name
|
|
# $artifactFileName = 'MyWebApp.zip'
|
|
$artifact = $artifacts | Where-Object {$_.fileName -like $artifactFilter} | Select-Object -First 1
|
|
$artifactFileName = $artifact.fileName
|
|
|
|
# artifact will be downloaded as
|
|
$localArtifactPath = "$downloadFolder\$artifactLocalFileName"
|
|
|
|
# download artifact
|
|
# -OutFile - is local file name where artifact will be downloaded into
|
|
$URI = "{0}/buildjobs/{1}/artifacts/{2}" -f $Constants.ApiUrl,$jobId,$artifactFileName
|
|
Invoke-RestMethod -Method Get -Uri $URI -OutFile $localArtifactPath -Headers $headers
|
|
|
|
return $localArtifactPath
|
|
}
|
|
|
|
# Get a collection of appveyor objects representing the builds for the last day
|
|
function Get-AppVeyorBuilds
|
|
{
|
|
[CmdletBinding()]
|
|
param(
|
|
[ValidateNotNullOrEmpty()]
|
|
[string]$ExtensionBranch = 'master',
|
|
[ValidateRange(1,7)][int]$Days = 7,
|
|
[int]$Last = 1
|
|
)
|
|
|
|
[datetime]$start = ((get-date).AddDays(-${Days}))
|
|
$results = Get-AppVeyorBuildRange -Start $start -LastBuildId $null -ExtensionBranch $ExtensionBranch
|
|
$results
|
|
}
|
|
|
|
function Get-AppVeyorBuildRange
|
|
{
|
|
[CmdletBinding()]
|
|
param
|
|
(
|
|
[Parameter(Mandatory=$true, Position=0)]
|
|
[string]
|
|
$ExtensionBranch = 'dev',
|
|
|
|
[Parameter(Mandatory=$true, Position=1)]
|
|
[datetime]
|
|
$Start,
|
|
|
|
[Parameter(Mandatory=$true, Position=2)]
|
|
[AllowNull()]
|
|
[Object]
|
|
$LastBuildId,
|
|
|
|
[Parameter(Mandatory=$false, Position=3)]
|
|
[int]
|
|
$Records = 20,
|
|
|
|
[switch]
|
|
$IncludeRunning
|
|
)
|
|
|
|
$result = @{
|
|
builds = @()
|
|
LastBuildId = ''
|
|
FoundLast = $false
|
|
}
|
|
|
|
if($LastBuildId)
|
|
{
|
|
$startBuildIdString = "&startBuildId=$LastBuildId"
|
|
}
|
|
|
|
$URI = "{0}/projects/{1}/{2}/history?recordsNumber={3}{4}&branch{5}" -f $Constants.ApiUrl,$Constants.AccountName,
|
|
$Constants.ProjectName,$Records,$startBuildIdString,$ExtensionBranch
|
|
$project = Invoke-RestMethod -Method Get -Uri $URI
|
|
|
|
foreach($build in $project.builds)
|
|
{
|
|
if($build.Status -ne 'running' -or $IncludeRunning)
|
|
{
|
|
$createdString = $build.created
|
|
$created = [datetime]::Parse($createdString)
|
|
|
|
if($created -gt $Start)
|
|
{
|
|
$version = $build.version
|
|
$result.lastBuildId = $build.buildId
|
|
$URI = "{0}/projects/{1}/{2}/build/{3}" -f $Constants.ApiUrl, $Constants.AccountName,
|
|
$Constants.ProjectName,$version
|
|
$buildProject = Invoke-RestMethod -Method Get -Uri $URI -Headers $headers -verbose:$false
|
|
|
|
$result.builds += Convert-AppVeyorBuildJson -build $buildProject.Build
|
|
}
|
|
else
|
|
{
|
|
$result.foundLast = $true
|
|
}
|
|
}
|
|
}
|
|
|
|
return $result
|
|
}
|
|
|
|
# Convert AppVeyor Build Json into a more usable PSObject
|
|
function Convert-AppVeyorBuildJson
|
|
{
|
|
[CmdletBinding()]
|
|
param
|
|
(
|
|
[Parameter(Mandatory=$true, Position=0)]
|
|
[Object]
|
|
$build
|
|
)
|
|
|
|
$Job = $build.jobs[0]
|
|
$status = $build.status
|
|
[datetime] $started = [datetime]::MinValue
|
|
[datetime] $finished = [datetime]::MaxValue
|
|
|
|
if($build.started)
|
|
{
|
|
[datetime] $started = [datetime]::Parse($build.started)
|
|
}
|
|
if($build.finished)
|
|
{
|
|
[datetime] $finished = [datetime]::Parse($build.finished)
|
|
}
|
|
|
|
$duration = $null
|
|
|
|
if($status -ne 'running')
|
|
{
|
|
$duration = $finished.Subtract($started)
|
|
}
|
|
|
|
$version = $build.version
|
|
|
|
$link = '<a href="{0}/project/{0}/{1}/build/{2}">Results</a>' -f $Constants.BaseUrl,$Constants.AccountName, $Constants.ProjectName, $version
|
|
$tests = @()
|
|
$tag = [string]::Empty
|
|
|
|
if($build.message.StartsWith('[') -and $build.message.Contains(']'))
|
|
{
|
|
$tag = $build.message.Substring(1,$build.message.IndexOf(']')).Replace(']','')
|
|
if($tag.Contains('('))
|
|
{
|
|
$tagParts = $tag.Split('(')
|
|
$tag = $tagParts[0]
|
|
for($i=1;$i -lt $tagParts.Count; $i++)
|
|
{
|
|
$tests += $tagParts[$i].Replace(')','')
|
|
}
|
|
}
|
|
$tag = $tag
|
|
}
|
|
|
|
$testString = $tests -join ','
|
|
|
|
$result = [PsCustomObject]@{
|
|
version = $version
|
|
Id = $build.BuildId
|
|
author = $build.authorName
|
|
branch = $Build.branch
|
|
status = $status
|
|
started = $started
|
|
StartedDay = [datetime]$started.Date
|
|
finished = $finished
|
|
duration = $duration
|
|
message = $build.message
|
|
testsCount = $Job.testsCount
|
|
passedTestsCount = $Job.passedTestsCount
|
|
failedTestsCount = $Job.failedTestsCount
|
|
link = $link
|
|
JobId = $Job.JobId
|
|
Tests = $testString
|
|
Tag = $tag
|
|
}
|
|
|
|
$result.pstypenames.Clear()
|
|
$result.pstypenames.Add('AppVeyorBuildSummary')
|
|
$result
|
|
}
|
|
|
|
############
|
|
### MAIN ###
|
|
############
|
|
|
|
#### DOCKER OPS #####
|
|
# is docker installed?
|
|
$dockerExe = get-command docker -ea silentlycontinue
|
|
if ( $dockerExe.name -ne "docker.exe" ) {
|
|
throw "Cannot find docker, is it installed?"
|
|
}
|
|
# Check to see if we already have an image, and if so
|
|
# delete it if -Force was used, otherwise throw and exit
|
|
$TestImage = docker images $Constants.TestImageName --format '{{.Repository}}'
|
|
if ( $TestImage -eq $Constants.TestImageName)
|
|
{
|
|
if ( $Force )
|
|
{
|
|
docker rmi $Constants.TestImageName
|
|
}
|
|
else
|
|
{
|
|
throw ("{0} already exists, use '-Force' to remove" -f $Constants.TestImageName)
|
|
}
|
|
}
|
|
# check again - there could be some permission problems
|
|
$TestImage = docker images $Constants.TestImageName --format '{{.Repository}}'
|
|
if ( $TestImage -eq $Constants.TestImageName)
|
|
{
|
|
throw ("'{0}' still exists, giving up" -f $Constants.TestImageName)
|
|
}
|
|
|
|
#### MSI CHECKS ####
|
|
# check to see if the MSI is present
|
|
$MsiExists = test-path $Constants.MsiName
|
|
$msg = "{0} exists, use -Force to remove or -UseExistingMsi to use" -f $Constants.MsiName
|
|
if ( $MsiExists -and ! ($force -or $useExistingMsi))
|
|
{
|
|
throw $msg
|
|
}
|
|
|
|
# remove the msi
|
|
if ( $MsiExists -and $Force -and ! $UseExistingMsi )
|
|
{
|
|
Remove-Item -force $Constants.MsiName
|
|
$MsiExists = $false
|
|
}
|
|
|
|
# a couple of checks before downloading or using the existing one
|
|
# if the msi exists and -UseExistingMsi is present, we'll use the
|
|
# one we found
|
|
if ( ! $MsiExists -and $UseExistingMsi )
|
|
{
|
|
throw ("{0} does not exist" -f $Constants.MsiName)
|
|
}
|
|
elseif ( $MsiExists -and ! $UseExistingMsi )
|
|
{
|
|
throw $msg
|
|
}
|
|
elseif ( ! ($MsiExists -and $UseExistingMsi) ) # download the msi
|
|
{
|
|
$builds = Get-AppVeyorBuilds -ExtensionBranch master
|
|
$build = $builds.builds | sort-object finished | select-object -last 1
|
|
Get-AppVeyorBuildArtifact -build $build.version
|
|
}
|
|
|
|
# last check before bulding the image
|
|
if ( ! (test-path $Constants.MsiName) )
|
|
{
|
|
throw ("{0} does not exist, giving up" -f $Constants.MsiName)
|
|
}
|
|
|
|
# collect the builds and select the last one
|
|
Docker build --tag $Constants.TestImageName .
|