diff --git a/appveyor.yml b/appveyor.yml index a5b9185..88e21c4 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -147,26 +147,13 @@ before_deploy: } deploy_script: - - cd %APPVEYOR_BUILD_FOLDER% - - ps: '& "asm\scripts\deploy-asm.ps1"' + - ps: | + Push-Location $env:APPVEYOR_BUILD_FOLDER + . .\asm\scripts\Asm-Functions.ps1 + Publish-Asm on_finish: - ps: | Push-Location $env:APPVEYOR_BUILD_FOLDER - . .\asm\scripts\API-Functions.ps1 - if(-not (Test-Path env:APPVEYOR_PULL_REQUEST_NUMBER)) { - # Delete all branches for asm if this is the last build - $build = (Get-AppVeyorBuild).build - $jobs = $build.jobs - $lastJob = ($jobs | Select-Object -Last 1) - - if (($lastJob.jobId -eq $env:APPVEYOR_JOB_ID)) { - $jobs | Foreach-Object { - $branchName = "asm/$($env:APPVEYOR_REPO_COMMIT)/appveyor-$($_.jobId)" - git ls-remote --heads --exit-code https://github.com/dadonenf/GSL.git $branchName - if($?){ - cmd.exe /c "git push origin --delete asm/$($env:APPVEYOR_REPO_COMMIT)/appveyor-$($_.jobId) 2>&1" - } - } - } - } + . .\asm\scripts\Asm-Functions.ps1 + Remove-Asm-Branches \ No newline at end of file diff --git a/asm/scripts/API-Functions.ps1 b/asm/scripts/API-Functions.ps1 deleted file mode 100644 index 9fef98b..0000000 --- a/asm/scripts/API-Functions.ps1 +++ /dev/null @@ -1,93 +0,0 @@ -function Get-AppVeyorBuild { - param() - - if (-not ($env:APPVEYOR_API_TOKEN)) { - throw "missing api token for AppVeyor." - } - - Invoke-RestMethod -Uri "https://ci.appveyor.com/api/projects/$env:APPVEYOR_ACCOUNT_NAME/$env:APPVEYOR_PROJECT_SLUG" -Method GET -Headers @{ - "Authorization" = "Bearer $env:APPVEYOR_API_TOKEN" - "Content-type" = "application/json" - } -} - -function appveyorFinished { - param() - $buildData = Get-AppVeyorBuild - $lastJob = ($buildData.build.jobs | Select-Object -Last 1).jobId - - if ($lastJob -ne $env:APPVEYOR_JOB_ID) { - return $false - } - - [datetime]$stop = ([datetime]::Now).AddMinutes($env:TIMEOUT_MINS) - - do { - - $allSuccess = $true - (Get-AppVeyorBuild).build.jobs | Where-Object {$_.jobId -ne $env:APPVEYOR_JOB_ID} | Foreach-Object ` - { - $job = $_ - switch ($job.status) { - "failed" { throw "AppVeyor's Job ($($job.jobId)) failed." } - "success" { continue } - Default { $allSuccess = $false } - } - } - if ($allSuccess) { return $true } - Start-sleep 5 - } while (([datetime]::Now) -lt $stop) - - throw "Test jobs were not finished in $env:TIMEOUT_MINS minutes" -} - - -function Get-TravisBuild { - param( - [int]$limit = 10, - [int]$maxLimit = 100 - ) - if (-not ($env:TRAVIS_API_TOKEN)) { - throw "missing api token for Travis-CI." - } - - $builds = Invoke-RestMethod -Uri "https://api.travis-ci.org/builds?limit=$($limit)" -Method Get -Headers @{ - "Authorization" = "token $env:TRAVIS_API_TOKEN" - "Travis-API-Version" = "3" - } - $currentBuild = $builds.builds | Where-Object {$_.commit.sha -eq $env:APPVEYOR_REPO_COMMIT} - if (!$currentBuild) { - if($limit+10 -le $maxLimit) { - return Get-TravisBuild -limit $limit+10 -maxLimit $maxLimit - } else { - throw "Could not get information about Travis build with sha $REPO_COMMIT" - } - } - return $currentBuild -} - -function travisFinished { - param() - - [datetime]$stop = ([datetime]::Now).AddMinutes($env:TIMEOUT_MINS) - - do { - $builds = Get-TravisBuild - $currentBuild = $builds.builds | Where-Object {$_.commit.sha -eq $env:APPVEYOR_REPO_COMMIT} - if (!$currentBuild) { - throw "Could not get information about Travis build with sha $REPO_COMMIT" - } - switch -regex ($currentBuild.state) { - "^passed$" { - return $true - } - "^(errored|failed|canceled)" { - throw "Travis Job ($($builds.builds.id)) failed" - } - } - - Start-sleep 5 - } while (([datetime]::Now) -lt $stop) - - throw "Travis build did not finished in $env:TIMEOUT_MINS minutes" -} \ No newline at end of file diff --git a/asm/scripts/Asm-Functions.ps1 b/asm/scripts/Asm-Functions.ps1 new file mode 100644 index 0000000..53bb229 --- /dev/null +++ b/asm/scripts/Asm-Functions.ps1 @@ -0,0 +1,202 @@ +function Get-AppVeyorBuild { + param() + + if (-not ($env:APPVEYOR_API_TOKEN)) { + throw "missing api token for AppVeyor." + } + + Invoke-RestMethod -Uri "https://ci.appveyor.com/api/projects/$env:APPVEYOR_ACCOUNT_NAME/$env:APPVEYOR_PROJECT_SLUG" -Method GET -Headers @{ + "Authorization" = "Bearer $env:APPVEYOR_API_TOKEN" + "Content-type" = "application/json" + } +} + +function appveyorFinished { + param() + $buildData = Get-AppVeyorBuild + $lastJob = ($buildData.build.jobs | Select-Object -Last 1).jobId + + if ($lastJob -ne $env:APPVEYOR_JOB_ID) { + return $false + } + + [datetime]$stop = ([datetime]::Now).AddMinutes($env:TIMEOUT_MINS) + + do { + + $allSuccess = $true + (Get-AppVeyorBuild).build.jobs | Where-Object {$_.jobId -ne $env:APPVEYOR_JOB_ID} | Foreach-Object ` + { + $job = $_ + switch ($job.status) { + "failed" { throw "AppVeyor's Job ($($job.jobId)) failed." } + "success" { continue } + Default { $allSuccess = $false } + } + } + if ($allSuccess) { return $true } + Start-sleep 5 + } while (([datetime]::Now) -lt $stop) + + throw "Test jobs were not finished in $env:TIMEOUT_MINS minutes" +} + + +function Get-TravisBuild { + param( + [int]$limit = 10, + [int]$maxLimit = 100 + ) + if (-not ($env:TRAVIS_API_TOKEN)) { + throw "missing api token for Travis-CI." + } + + $builds = Invoke-RestMethod -Uri "https://api.travis-ci.org/builds?limit=$($limit)" -Method Get -Headers @{ + "Authorization" = "token $env:TRAVIS_API_TOKEN" + "Travis-API-Version" = "3" + } + $currentBuild = $builds.builds | Where-Object {$_.commit.sha -eq $env:APPVEYOR_REPO_COMMIT} + if (!$currentBuild) { + if($limit+10 -le $maxLimit) { + return Get-TravisBuild -limit $limit+10 -maxLimit $maxLimit + } else { + throw "Could not get information about Travis build with sha $REPO_COMMIT" + } + } + return $currentBuild +} + +function travisFinished { + param() + + [datetime]$stop = ([datetime]::Now).AddMinutes($env:TIMEOUT_MINS) + + do { + $builds = Get-TravisBuild + $currentBuild = $builds.builds | Where-Object {$_.commit.sha -eq $env:APPVEYOR_REPO_COMMIT} + if (!$currentBuild) { + throw "Could not get information about Travis build with sha $REPO_COMMIT" + } + switch -regex ($currentBuild.state) { + "^passed$" { + return $true + } + "^(errored|failed|canceled)" { + throw "Travis Job ($($builds.builds.id)) failed" + } + } + + Start-sleep 5 + } while (([datetime]::Now) -lt $stop) + + throw "Travis build did not finished in $env:TIMEOUT_MINS minutes" +} + +function Get-Any-Appveyor-Failures { + (Get-AppVeyorBuild).build.jobs | Foreach-Object ` + { + $job = $_ + switch ($job.status) { + "failed" { return $true } + Default { } + } + } + return $false +} + +function Remove-Asm-Branches { + if(-not (Test-Path env:APPVEYOR_PULL_REQUEST_NUMBER)) { + # Delete all branches for asm if this is the last build + $build = (Get-AppVeyorBuild).build + $jobs = $build.jobs + $lastJob = ($jobs | Select-Object -Last 1) + + if (($lastJob.jobId -eq $env:APPVEYOR_JOB_ID) -or (Get-Any-Appveyor-Failures)) { + $jobs | Foreach-Object { + $branchName = "asm/$($env:APPVEYOR_REPO_COMMIT)/appveyor-$($_.jobId)" + git ls-remote --heads --exit-code https://github.com/dadonenf/GSL.git $branchName + if($?){ + cmd.exe /c "git push origin --delete asm/$($env:APPVEYOR_REPO_COMMIT)/appveyor-$($_.jobId) 2>&1" + } + } + } + } + +} + + +# Returns true if all builds are finished. Throws if any failure or timeout. If the current build is not last, then returns false +function Get-All-Builds-Finished { + return appveyorFinished +} + +function Run-Command-With-Retry { + param( + [string]$cmd, + [string]$cleanup_cmd = "", + [int]$maxTries = 3 + ) + + while ($maxTries -gt 0) { + cmd.exe /c $cmd + if($?){ + return + } else { + cmd.exe /c $cleanup_cmd + $maxTries = $maxTries - 1 + } + } + + throw "Command $($command) failed with exit code $($LastExitCode)" +} + +function collectAsm { + cmd.exe /c "git checkout $($env:APPVEYOR_REPO_BRANCH) 2>&1" + cmd.exe /c "git fetch --all 2>&1" + + # Create branch to merge asm into + $asmFinalBranch = "asm/$($env:APPVEYOR_REPO_COMMIT)/final" + cmd.exe /c "git checkout -b $($asmFinalBranch) $($env:APPVEYOR_REPO_COMMIT) 2>&1" + + #merge all branches into final branch + (Get-AppVeyorBuild).build.jobs | Foreach-Object { + $branchName = "asm/$($env:APPVEYOR_REPO_COMMIT)/appveyor-$($_.jobId)" + + #Check that all branches exist + cmd.exe /c "git ls-remote --heads --exit-code https://github.com/dadonenf/GSL.git $($branchName)" + if(-not $?){ + throw "Missing branch for job $($_.jobId)" + } + + #Only merge in asm if there is any change between the current branch and the repo branch + cmd.exe /c "git diff-tree --quiet origin/$($branchName)..$($env:APPVEYOR_REPO_COMMIT)" + if(-not $?){ + # Use cherry-pick as the asm branches only have a single commit + cmd.exe /c "git cherry-pick origin/$($branchName) 2>&1" + if(-not $?){ + throw "Failed merge of $($branchName)" + } + } + } + + #Merge all branches into $($env:APPVEYOR_REPO_BRANCH) + cmd.exe /c "git checkout $($env:APPVEYOR_REPO_BRANCH) 2>&1" + cmd.exe /c "git merge --squash $($asmFinalBranch) 2>&1" + if(-not $?){ + throw "Failed merge" + } + cmd.exe /c "git diff-index --cached --quiet --exit-code HEAD" + if(-not $?) { + git commit -m "[skip ci] Update ASM for $($env:APPVEYOR_REPO_COMMIT)" + Run-Command-With-Retry -cmd "git push 2>&1" -cleanup_cmd "git pull --rebase 2>&1" + } +} + + +function Publish-Asm { + # Wait for all jobs + if(Get-All-Builds-Finished) { + # Collect ASM (currently from Appveyor only) + collectAsm + } +} \ No newline at end of file diff --git a/asm/scripts/deploy-asm.ps1 b/asm/scripts/deploy-asm.ps1 deleted file mode 100644 index e702fec..0000000 --- a/asm/scripts/deploy-asm.ps1 +++ /dev/null @@ -1,75 +0,0 @@ -# Include the API access functions -. $PSScriptRoot\API-Functions.ps1 - -function Run-Command-With-Retry { - param( - [string]$cmd, - [string]$cleanup_cmd = "", - [int]$maxTries = 3 - ) - - while ($maxTries -gt 0) { - cmd.exe /c $cmd - if($?){ - return - } else { - cmd.exe /c $cleanup_cmd - $maxTries = $maxTries - 1 - } - } - - throw "Command $($command) failed with exit code $($LastExitCode)" -} - -function collectAsm { - cmd.exe /c "git checkout $($env:APPVEYOR_REPO_BRANCH) 2>&1" - cmd.exe /c "git fetch --all 2>&1" - - # Create branch to merge asm into - $asmFinalBranch = "asm/$($env:APPVEYOR_REPO_COMMIT)/final" - cmd.exe /c "git checkout -b $($asmFinalBranch) $($env:APPVEYOR_REPO_COMMIT) 2>&1" - - #merge all branches into final branch - (Get-AppVeyorBuild).build.jobs | Foreach-Object { - $branchName = "asm/$($env:APPVEYOR_REPO_COMMIT)/appveyor-$($_.jobId)" - - #Check that all branches exist - cmd.exe /c "git ls-remote --heads --exit-code https://github.com/dadonenf/GSL.git $($branchName)" - if(-not $?){ - throw "Missing branch for job $($_.jobId)" - } - - #Only merge in asm if there is any change between the current branch and the repo branch - cmd.exe /c "git diff-tree --quiet origin/$($branchName)..$($env:APPVEYOR_REPO_COMMIT)" - if(-not $?){ - # Use cherry-pick as the asm branches only have a single commit - cmd.exe /c "git cherry-pick origin/$($branchName) 2>&1" - if(-not $?){ - throw "Failed merge of $($branchName)" - } - } - } - - #Merge all branches into $($env:APPVEYOR_REPO_BRANCH) - cmd.exe /c "git checkout $($env:APPVEYOR_REPO_BRANCH) 2>&1" - cmd.exe /c "git merge --squash $($asmFinalBranch) 2>&1" - if(-not $?){ - throw "Failed merge" - } - cmd.exe /c "git diff-index --cached --quiet --exit-code HEAD" - if(-not $?) { - git commit -m "[skip ci] Update ASM for $($env:APPVEYOR_REPO_COMMIT)" - Run-Command-With-Retry -cmd "git push 2>&1" -cleanup_cmd "git pull --rebase 2>&1" - } -} - -Write-Host "Starting asm deployment" - -# Wait for all jobs -if(appveyorFinished) { - - Write-Host "Appveyor Finished, collecting ASM" - - # Collect ASM (currently from Appveyor only) - collectAsm -} \ No newline at end of file