Skip to content

Instantly share code, notes, and snippets.

@Zingam
Last active December 24, 2021 20:12
Show Gist options
  • Save Zingam/48fd980e5ef35335282a6c8203a45d03 to your computer and use it in GitHub Desktop.
Save Zingam/48fd980e5ef35335282a6c8203a45d03 to your computer and use it in GitHub Desktop.
# Version format
version: 1.0.0.{build}
image:
- Ubuntu1804
- Visual Studio 2019
platform: x64
configuration:
- Debug
- Release
environment:
option_EngineLibraryAs_SHARED:
"YES"
# Environment variables are always strings (in PowerShell)
RemoteSessionOnExit_Enabled:
false
CoverityScan_Enabled:
false
CoverityScanToken:
secure: R5iKcUqFlDHXEM5mD8NMvlRqKF2yIEQH+0ZvrsLBrOE=
CoverityScanEmail:
secure: MhbF2+Iukp8Z+ltTigOZbgG5564cfXoWpsHp2mLypEs=
# Preserve contents of selected directories and files across project builds
cache:
# If using out-of-repository "appveyor.yml":
'%vcpkgCachePath%'
# Set dependency on "appveyor.yml" and invalidate the cache on change
#'%vcpkgCachePath% -> appveyor.yml'
# Scripts that are called at very beginning, before repo cloning
init:
- ps: |
$env:AppveyorModulesPath="$env:APPVEYOR_BUILD_FOLDER/../PS_Modules/"
mkdir -p $env:AppveyorModulesPath
################################################
# Helper functions
################################################
# Write out a Script Module to a file
Set-Content -Path "$env:AppveyorModulesPath/$AppveyorCI_Functions.psm1" -Value `
@'
function Get-CannonicalPath
{
# Process parameters
param (
[Parameter (Mandatory=$true)]
#[ValidatePattern ("^(?!\s*$).+", ErrorMessage = "A non-empty string is required.")]
[string] $FullPathName
)
$newPath = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($FullPathName)
$root = [System.IO.Path]::GetPathRoot($newPath)
# Handle root directory
if ($newPath -eq $root)
{
return $root
}
return $newPath.Replace("\", "/")
}
function Invoke-Executable
{
param ([string] $FilePath, [string] $ArgumentList)
$psInfo = New-Object System.Diagnostics.ProcessStartInfo
$psInfo.FileName = $FilePath
$psInfo.Arguments = $ArgumentList
$psInfo.WorkingDirectory = Get-Location
$psInfo.RedirectStandardError = $true
$psInfo.RedirectStandardOutput = $true
$psInfo.UseShellExecute = $false
$ps = New-Object System.Diagnostics.Process
$ps.StartInfo = $psInfo
$ps.Start() | Out-Null
$ps.WaitForExit()
$stdout = $ps.StandardOutput.ReadToEnd()
$stderr = $ps.StandardError.ReadToEnd()
Write-Host $stdout
Write-Host $stderr
Write-Host "[$FilePath] Process exited with code: " $ps.ExitCode
}
function Stop-AppveyorBuild
{
# Process parameters
param (
[Parameter (Mandatory=$true)]
#[ValidatePattern ("^(?!\s*$).+", ErrorMessage = "A non-empty string is required.")]
[string] $ErrorMessage
)
$env:APPVEYOR_SKIP_FINALIZE_ON_EXIT = $true
Write-Host $ErrorMessage
Exit-AppveyorBuild
}
function Write-ArrayElements
{
param (
[Parameter (Mandatory=$true)]
#[ValidatePattern ("^(?!\s*$).+", ErrorMessage = "A non-empty string is required.")]
[string] $ArrayName,
[Parameter (Mandatory=$true)]
[array] $Array
)
Write-Host "Array element list $ArrayName ="
foreach ($element in $Array)
{
$element = [System.Environment]::ExpandEnvironmentVariables($element)
Write-Host " $element,"
}
}
function Write-EnvVariables
{
Write-Host "Environment variables:"
Write-Host " - CMake command line options"
Write-Host " `$env:option_Graphics_CheckGraphicsApiCalls = $env:option_Graphics_CheckGraphicsApiCalls"
Write-Host " `$env:option_EngineLibraryAs_SHARED = $env:option_EngineLibraryAs_SHARED"
Write-Host " - Platform & Target variables"
Write-Host " `$env:Generator = $env:Generator"
Write-Host " `$env:TargetPlatform = $env:TargetPlatform"
Write-Host " `$env:vcpkgTriplet = $env:vcpkgTriplet"
Write-Host " - Path variables"
Write-Host " `$env:ArchivePath = $env:ArchivePath"
Write-Host " `$env:BuildPath = $env:BuildPath"
Write-Host " `$env:InstallPath = $env:InstallPath"
Write-Host " `$env:VCPKG_ROOT = $env:VCPKG_ROOT"
Write-Host " `$env:vcpkgCachePath = $env:vcpkgCachePath"
Write-Host " - Date & Version variables"
Write-Host " `$env:BuildVersion = $env:BuildVersion"
Write-Host " - Archive names"
Write-Host " `$env:ArchiveName = $env:ArchiveName"
Write-Host " `$env:CoverityScanArchiveName = $env:CoverityScanArchiveName"
}
Export-ModuleMember -Function Get-CannonicalPath
Export-ModuleMember -Function Invoke-Executable
Export-ModuleMember -Function Stop-AppveyorBuild
Export-ModuleMember -Function Write-ArrayElements
Export-ModuleMember -Function Write-EnvVariables
'@
################################################
# Include common functions
################################################
Import-Module "$env:AppveyorModulesPath/$AppveyorCI_Functions.psm1"
################################################
# Set environment variables
################################################
# CMake command line options
if ("Debug" -eq $env:CONFIGURATION)
{
$env:option_Graphics_CheckGraphicsApiCalls = "YES"
}
else
{
$env:option_Graphics_CheckGraphicsApiCalls = "NO"
}
# Platform & Target variables
if ("x64" -eq $env:PLATFORM)
{
if ($env:APPVEYOR_BUILD_WORKER_IMAGE -match "^Visual Studio")
{
$env:Generator = "Ninja"
$env:TargetPlatform = "Windows"
}
elseif ($env:APPVEYOR_BUILD_WORKER_IMAGE -match "^Ubuntu")
{
$env:Generator = "Ninja"
$env:TargetPlatform = "Linux"
}
else
{
return Stop-AppveyorBuild "Unknown worker image: $env:APPVEYOR_BUILD_WORKER_IMAGE"
}
$env:vcpkgTriplet = "x64"
}
else
{
return Stop-AppveyorBuild "Unknown target platform: $PLATFORM"
}
$env:vcpkgTriplet = "$env:vcpkgTriplet-$env:TargetPlatform".ToLower()
# Path variables
$archivePath = "$env:APPVEYOR_BUILD_FOLDER/__archive-output/$env:vcpkgTriplet-$env:CONFIGURATION"
$buildPath = "$env:APPVEYOR_BUILD_FOLDER/__build-output/$env:vcpkgTriplet-$env:CONFIGURATION"
$installPath = "$env:APPVEYOR_BUILD_FOLDER/__install-output/$env:vcpkgTriplet-$env:CONFIGURATION"
$vcpkgRoot = "$env:APPVEYOR_BUILD_FOLDER/vcpkg"
$vcpkgRoot = [System.Environment]::ExpandEnvironmentVariables($vcpkgRoot)
$vcpkgCachePath = "$vcpkgRoot/installed"
$env:ArchivePath = Get-CannonicalPath -FullPathName $archivePath
$env:BuildPath = Get-CannonicalPath -FullPathName $buildPath
$env:InstallPath = Get-CannonicalPath -FullPathName $installPath
$env:VCPKG_ROOT = Get-CannonicalPath -FullPathName $vcpkgRoot
$env:vcpkgCachePath = Get-CannonicalPath -FullPathName $vcpkgCachePath
# Date & Version variables
if ($isWindows)
{
Set-TimeZone -Name "FLE Standard Time"
}
# Get a sortable timestamp:
# https://docs.microsoft.com/en-us/dotnet/api/system.globalization.datetimeformatinfo?view=netframework-4.7.2
$timestamp = Get-Date -format s | foreach {$_ -replace ":", "-"}
$env:BuildVersion = "$env:APPVEYOR_BUILD_VERSION-D$timestamp"
# Archive names
$env:ArchiveName = "$env:APPVEYOR_PROJECT_NAME-$env:TargetPlatform-$env:CONFIGURATION-$env:BuildVersion.zip"
$env:CoverityScanArchiveName = "CoverityScan-$env:ArchiveName"
Write-EnvVariables
# Scripts that run after cloning a repository
install:
- ps: |
################################################
# Include common functions
################################################
Import-Module "$env:AppveyorModulesPath/$AppveyorCI_Functions.psm1"
Write-EnvVariables
################################################
# Install packages
if ("Windows" -eq $env:TargetPlatform)
{
if ("Ninja" -eq $env:Generator)
{
choco install -y --no-progress ninja
}
}
elseif ("Linux" -eq $env:TargetPlatform)
{
# Add GCC 9.1 repository
sudo add-apt-repository ppa:jonathonf/gcc-9.1
# Set non-interactive frontend for "debconf" to prevent errors in the script
$env:DEBIAN_FRONTEND = "noninteractive"
# "apt" options: -y - "yes", -q - "quiet"
sudo apt-get -yq update | Out-Null
# Applications
sudo apt-get -yq install ninja-build | Out-Null
sudo apt-get -yq install g++-9
# Libraries
sudo apt-get -yq install libgl1-mesa-dev | Out-Null
# Set default compiler: GCC 9
# Register GCC 9 as an alternative
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-9 60
sudo update-alternatives --config gcc
# Set GCC9 as the default compiler
sudo update-alternatives --set gcc /usr/bin/gcc-9
gcc --version
}
else
{
return Stop-AppveyorBuild "Unknown target platform: $env:TargetPlatform"
}
if ("Ninja" -eq $env:Generator)
{
ninja --version
}
# Install vcpkg packages
if (-not (Test-Path $env:vcpkgCachePath))
{
Write-Host "`n===> Cloning vcpkg...`n"
git clone -q https://github.com/Microsoft/vcpkg.git
Write-Host "`n===> Rebuilding vcpkg...`n"
cd $env:VCPKG_ROOT
if ("Windows" -eq $env:TargetPlatform)
{
./bootstrap-vcpkg.bat
}
elseif ("Linux" -eq $env:TargetPlatform)
{
. ./bootstrap-vcpkg.sh
}
else
{
return Stop-AppveyorBuild "Unknown target platform: $env:TargetPlatform"
}
./vcpkg install --recurse --triplet $env:vcpkgTriplet freetype sdl2
}
# Custom build scripts that run instead of automatic MSBuild
build_script:
- ps: |
################################################
# Include common functions
################################################
Import-Module "$env:AppveyorModulesPath/$AppveyorCI_Functions.psm1"
Write-EnvVariables
################################################
# Setup build environment
if (("Windows" -eq $env:TargetPlatform) `
-and ("Ninja" -eq $env:Generator))
{
# Install VSSetup - This PowerShell module contains cmdlets to query instances of Visual Studio 2017 and newer.
Install-Module VSSetup -Scope CurrentUser
# Get the latest MSVC version - https://docs.microsoft.com/en-us/visualstudio/install/workload-component-id-vs-professional
$VSSetupInstance = Get-VSSetupInstance -All | Select-VSSetupInstance -Require 'Microsoft.VisualStudio.Component.VC.Tools.x86.x64' -Latest
$env:VSInstallationPath = $VSSetupInstance.InstallationPath
Write-Host "`nVisual Studio instance location: $env:VSInstallationPath`n"
# Store the environment variables from the Batch script to a temporary file
cmd.exe /c "call `"%VSInstallationPath%\VC\Auxiliary\Build\vcvars64.bat`" && set > %APPVEYOR_BUILD_FOLDER%\vcvars64.txt"
# Set the environment variables from the temporary file in PowerShell
Get-Content "$env:APPVEYOR_BUILD_FOLDER\vcvars64.txt" | ForEach-Object -Process `
{
if ($_ -match "^(.*?)=(.*)$")
{
Set-Item -Force -Path "env:\$($matches[1])" -Value $matches[2]
}
}
}
# Create output paths
mkdir -p $env:ArchivePath
mkdir -p $env:BuildPath
mkdir -p $env:InstallPath
# Configure CMake project
cd $env:BuildPath
# Setup CMake arguments
$cmakeArguments = @(
'-G"%Generator%"',
'-D"CMAKE_BUILD_TYPE:STRING=%CONFIGURATION%"',
'-D"option_EngineLibraryAs_SHARED:BOOL=%option_EngineLibraryAs_SHARED%"',
'-D"option_Graphics_CheckGraphicsApiCalls:BOOL=%option_Graphics_CheckGraphicsApiCalls%"',
'-D"CMAKE_INSTALL_PREFIX:STRING=%InstallPath%"',
'"../../GunBox"'
)
$cmakeArgumentList = [System.Environment]::ExpandEnvironmentVariables($cmakeArguments)
Write-Host "`n===> CMake configuration started...`n"
cmake --version
Invoke-Executable -FilePath "cmake" -ArgumentList $cmakeArgumentList
Write-Host "`n===> CMake configuration completed...`n"
# Run Coverity Scan on forced builds (via the "New Build" option)
if (("true" -eq $env:CoverityScan_Enabled) `
-and ("true" -eq $env:APPVEYOR_FORCED_BUILD) `
-and ($isWindows))
{
Write-Host "`n===> CoverityScan build started...`n"
cov-build --dir cov-int/ cmake --build .
# Compress scan results recursively
7z a -r "$env:ArchivePath/$env:CoverityScanArchiveName" cov-int/
# Deploy build artifact
Push-AppveyorArtifact "$env:ArchivePath/$env:CoverityScanArchiveName"
# Publish results for analysis
$curlArguments = @(
'--form token=%CoverityScanToken%',
'--form email=%CoverityScanEmail%',
'--form file=@%ArchivePath%/%CoverityScanArchiveName%',
'--form version="%BuildVersion%"',
'--form description="GunBox"',
'https://scan.coverity.com/builds?project=Zingam%2FGunBox'
)
$curlArgumentList = [System.Environment]::ExpandEnvironmentVariables($curlArguments)
Invoke-Executable -FilePath "curl" -ArgumentList $curlArgumentList
return Stop-AppveyorBuild "`n===> CoverityScan build completed...`n"
}
Write-Host "`n===> Build started...`n"
# Build artifacts
cmake --build .
cmake --build . --target install
Write-Host "`n===> Build completed...`n"
# Deploy build artifact
$archivePushLocation = "$env:ArchivePath/$env:ArchiveName"
Add-Type -AssemblyName "System.IO.Compression.FileSystem"
[IO.Compression.ZipFile]::CreateFromDirectory(
"$env:InstallPath",
"$archivePushLocation",
[IO.Compression.CompressionLevel]::Optimal,
$false
)
Write-Host "`n===> Artifact deployment started...`n"
Push-AppveyorArtifact $archivePushLocation
Write-Host "`n===> Artifact deployment completed...`n"
# Scripts that run after build success/failure
on_finish:
# Uncomment to enable a Remote Desktop session
- ps: |
if (("true" -eq $env:RemoteSessionOnExit_Enabled) `
-and ($isWindows))
{
$blockRdp = $true;
iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
}
# Uncomment to enable SSH connection
- sh: |
if [ true = "${RemoteSessionOnExit_Enabled}" ]
then
export APPVEYOR_SSH_BLOCK=true
curl -sflL 'https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-ssh.sh' | bash -e -
fi