forked from Mirrors/openclonk
200 lines
8.3 KiB
PowerShell
200 lines
8.3 KiB
PowerShell
pushd $env:BUILD_TARGET_FOLDER
|
|
trap {popd}
|
|
|
|
$ErrorActionPreference = 'Stop'
|
|
|
|
cmd /D /Q /C "`"C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\Tools\vsdevcmd.bat`" -arch=${env:PLATFORM} > NUL && SET" | %{
|
|
$k, $v = $_.Split('=', 2)
|
|
[System.Environment]::SetEnvironmentVariable($k, $v)
|
|
}
|
|
|
|
Add-Type -Path "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\Microsoft.Build.dll"
|
|
$projects = New-Object Microsoft.Build.Evaluation.ProjectCollection
|
|
$projects.SetGlobalProperty('Configuration', $env:CONFIGURATION)
|
|
|
|
function Resolve-CanonicalPath {
|
|
param([string]$Path)
|
|
Add-Type -TypeDefinition @'
|
|
using System;
|
|
using System.Runtime.InteropServices;
|
|
using Microsoft.Win32.SafeHandles;
|
|
|
|
public static class ResolveCanonicalPath {
|
|
[DllImport("kernel32.dll", EntryPoint="CreateFileW", CharSet=CharSet.Unicode, SetLastError=true)]
|
|
public static extern SafeFileHandle CreateFile(
|
|
string lpFileName,
|
|
int dwDesiredAccess,
|
|
int dwShareMode,
|
|
IntPtr securityAttributes,
|
|
int dwCreationDisposition,
|
|
int dwFlagsAndAttributes,
|
|
IntPtr hTemplateFile);
|
|
[DllImport("kernel32.dll", EntryPoint="GetFinalPathNameByHandleW", CharSet=CharSet.Unicode, SetLastError=true)]
|
|
public static extern int GetFinalPathNameByHandle(
|
|
IntPtr hFile,
|
|
[In, Out] System.Text.StringBuilder lpszFilePath,
|
|
int cchFilePath,
|
|
int dwFlags);
|
|
}
|
|
'@
|
|
# Ask the file system to provide us with the canonical path, which includes
|
|
# proper capitalization
|
|
$fh = [ResolveCanonicalPath]::CreateFile($Path, 0, 2, [System.IntPtr]::Zero, 3, 0x2000000, [System.IntPtr]::Zero)
|
|
try {
|
|
$real_path = New-Object System.Text.StringBuilder 512
|
|
$rp_len = [ResolveCanonicalPath]::GetFinalPathNameByHandle($fh.DangerousGetHandle(), $real_path, $real_path.Capacity, 0)
|
|
if ($rp_len -lt 0) {
|
|
throw [System.ComponentModel.Win32Exception]::new([System.Runtime.InteropServices.Marshal]::GetLastWin32Error())
|
|
}
|
|
$real_path = $real_path.ToString()
|
|
if ($real_path.StartsWith('\\?\')) {
|
|
return $real_path.Substring(4)
|
|
}
|
|
return $real_path
|
|
} finally {
|
|
$fh.Close()
|
|
}
|
|
}
|
|
|
|
function Add-SourceServerData {
|
|
param([string]$pdb)
|
|
|
|
$srctool = "C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\srcsrv\srctool.exe"
|
|
$pdbstr = "C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\srcsrv\pdbstr.exe"
|
|
|
|
$temp_name = New-TemporaryFile
|
|
try {
|
|
$temp = New-Object System.IO.StreamWriter $temp_name.OpenWrite()
|
|
$temp.WriteLine(@"
|
|
SRCSRV: ini ------------------------------------------------
|
|
VERSION=2
|
|
VERCTRL=http
|
|
SRCSRV: variables ------------------------------------------
|
|
DEPOT=https://raw.githubusercontent.com/$env:APPVEYOR_REPO_NAME/%COMMIT%/
|
|
COMMIT=$env:APPVEYOR_REPO_COMMIT
|
|
SRCSRVTRG=%DEPOT%%var2%
|
|
SRCSRV: source files ---------------------------------------
|
|
"@)
|
|
& $srctool -r $pdb | %{
|
|
Resolve-CanonicalPath $_
|
|
} | ?{
|
|
# Filter everything outside of the source path
|
|
$_.StartsWith($env:APPVEYOR_BUILD_FOLDER, [System.StringComparison]::OrdinalIgnoreCase)
|
|
} | ?{
|
|
# Filter everything that doesn't exist
|
|
Test-Path $_
|
|
} | %{
|
|
# Strip source folder prefix for building an URL
|
|
$path = $_.Substring($env:APPVEYOR_BUILD_FOLDER.Length)
|
|
$path = $path.TrimStart(@([System.IO.Path]::DirectorySeparatorChar, [System.IO.Path]::AltDirectorySeparatorChar))
|
|
$path = $path.Replace('\','/')
|
|
$temp.WriteLine("$_*$path")
|
|
}
|
|
$temp.WriteLine('SRCSRV: end ------------------------------------------------')
|
|
$temp.Close()
|
|
# Write source info to PDB
|
|
& $pdbstr -w -p:$pdb -i:$($temp_name.FullName) -s:srcsrv
|
|
} finally {
|
|
$temp_name.Delete()
|
|
}
|
|
}
|
|
|
|
if (-not $env:APPVEYOR) {
|
|
function appveyor {
|
|
param ([string]$action, [string[]]$rest)
|
|
}
|
|
}
|
|
|
|
# Add source server information to all debug symbols and push the
|
|
# binaries/symbols to AppVeyor
|
|
Get-Item *.vcxproj | %{
|
|
$p = $projects.LoadProject($_.FullName)
|
|
if ($p.GetPropertyValue('ConfigurationType') -eq 'Application') {
|
|
# For all executable files
|
|
$binary = $p.GetPropertyValue('TargetPath')
|
|
if (Test-Path $binary) {
|
|
# Upload the executable itself as an artifact
|
|
appveyor PushArtifact $binary
|
|
$pdb = $p.ItemDefinitions['Link'].GetMetadataValue('ProgramDataBaseFile')
|
|
if (Test-Path $pdb) {
|
|
# If we generated a .pdb file, add source server information
|
|
Add-SourceServerData $pdb
|
|
appveyor PushArtifact $pdb
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if ($env:DEPLOYMENT_URL -and $env:DEPLOYMENT_SECRET) {
|
|
# Build a zip file with the main executable and its dependencies
|
|
$deploy_dir = "${env:BUILD_TARGET_FOLDER}\deployment"
|
|
[void](mkdir $deploy_dir)
|
|
|
|
$openclonk = $projects.LoadedProjects | ?{ $_.GetPropertyValue('ProjectName') -eq 'openclonk' }
|
|
$c4group = $projects.LoadedProjects | ?{ $_.GetPropertyValue('ProjectName') -eq 'c4group' }
|
|
$groups = $projects.LoadedProjects | ?{ $_.GetPropertyValue('ProjectName') -eq 'groups' }
|
|
if ($openclonk -and $c4group -and $groups) {
|
|
$groupFiles = ($groups.GetItems('CustomBuild') |
|
|
?{ $_.GetMetadataValue('AdditionalInputs') -split ';' -contains $c4group.GetPropertyValue('TargetPath') }).
|
|
GetMetadataValue('Outputs')
|
|
}
|
|
|
|
# Copy executable, Qt
|
|
C:\Qt\5.11.1\msvc2017_64\bin\windeployqt.exe --no-translations --no-compiler-runtime --dir $deploy_dir $openclonk.GetPropertyValue('TargetPath')
|
|
Copy-Item $openclonk.GetPropertyValue('TargetPath') "${deploy_dir}\"
|
|
|
|
# Copy other DLLs openclonk depends on
|
|
function Get-Imports {
|
|
param([string]$file)
|
|
(dumpbin /imports $file | ?{ $_ -match ' {4}\w+\.dll'}).Trim()
|
|
}
|
|
$unresolved = [System.Collections.Queue]::new()
|
|
Get-Imports $openclonk.GetPropertyValue('TargetPath') | %{ $unresolved.Enqueue($_) }
|
|
while ($unresolved.Count -gt 0) {
|
|
$library = $unresolved.Dequeue()
|
|
$file = Join-Path $deploy_dir $library
|
|
$dep_file = "${env:BUILD_DEPS_FOLDER}\${env:PLATFORM}\bin\${library}"
|
|
if (-not (Test-Path $file) -and (Test-Path $dep_file)) {
|
|
Write-Host "Bundling ${library}"
|
|
Copy-Item $dep_file $file
|
|
Get-Imports $file | %{ $unresolved.Enqueue($_) }
|
|
}
|
|
}
|
|
|
|
# Copy generated group files
|
|
$groupFiles | %{ Copy-Item $_ $deploy_dir }
|
|
|
|
# Create archive
|
|
$archive_name = "OpenClonk-win-${env:PLATFORM}.zip"
|
|
7z a -mx=9 -y -r -- $archive_name "${deploy_dir}\*"
|
|
|
|
$deployment_user, $deployment_password = $env:DEPLOYMENT_SECRET.Split(':', 2)
|
|
$timestamp = Get-Date -Date (Get-Date $env:APPVEYOR_REPO_COMMIT_TIMESTAMP).ToUniversalTime() -UFormat '%Y-%m-%dT%H:%M:%SZ'
|
|
$deployment_url = [System.UriBuilder]::new("${env:DEPLOYMENT_URL}${timestamp}-${env:APPVEYOR_REPO_BRANCH}-$($env:APPVEYOR_REPO_COMMIT.Substring(0, 9))/${archive_name}")
|
|
$deployment_url.UserName = $deployment_user
|
|
$deployment_url.Password = $deployment_password
|
|
$deployment_auth = [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes("${deployment_user}:${deployment_password}"))
|
|
|
|
[System.Net.ServicePointManager]::SecurityProtocol = 'Tls12'
|
|
[System.Net.HttpWebRequest]$req = [System.Net.WebRequest]::CreateHttp($deployment_url.Uri)
|
|
$deployment_url.Password = '********'
|
|
$req.Timeout = 30 * 60 * 1000
|
|
$req.Method = 'POST'
|
|
$req.ContentType = 'application/octet-stream'
|
|
$req.AllowWriteStreamBuffering = $false
|
|
$req.SendChunked = $true
|
|
$req.Headers.Add('Authorization', "Basic ${deployment_auth}")
|
|
$fileStream = [System.IO.File]::OpenRead((Resolve-Path $archive_name))
|
|
Write-Host "Uploading to $($deployment_url.Uri)"
|
|
$reqStream = $req.GetRequestStream()
|
|
$fileStream.CopyTo($reqStream)
|
|
$fileStream.Close()
|
|
$reqStream.Close()
|
|
try {
|
|
[System.Net.HttpWebResponse]$resp = $req.GetResponse()
|
|
Write-Host "Upload successful: $([uint32]$resp.StatusCode) $($resp.StatusDescription)"
|
|
} catch [System.Net.WebException] {
|
|
Write-Host "Upload failed: $($_.Exception.Status) $($_.Exception.Response.StatusDescription)"
|
|
}
|
|
}
|