init:
  # Only save build cache on master branch
  - ps: IF ($env:APPVEYOR_REPO_BRANCH -ne "master") {$env:APPVEYOR_CACHE_SKIP_SAVE = "true"}

environment:
  global:
    APPVEYOR_CACHE_ENTRY_ZIP_ARGS: -t7z -m0=lzma -mx=4
  matrix:
  # 32-bit (x86) builds
  - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
    WZ_JOB_ID: release_x86
    # NOTE: Additional environment variables are set later to maintain consistent job identifiers
  ## NOTE: Unfortunately, 64-bit Windows builds are currently broken because of QScript (see: http://developer.wz2100.net/ticket/4763)
  ## Whenever that ticket is resolved, the following will build 64-bit:
  # - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
  #   WZ_JOB_ID: release_x64

# Cache
# - Maintains a separate cache for each build matrix entry
#
# To manually clear the project's cache, open the Javascript console when logged-in to AppVeyor, and execute:
# $.ajax({ url: 'https://ci.appveyor.com/api/projects/<username>/<project>/buildcache', type: 'DELETE'})
# For more, see: https://github.com/appveyor/ci/issues/985
cache:
  # 1. The vcpkg directory
  #    - Cache built dependencies to reduce frequent build time by 20+ minutes.
  #    - The vcpkg cache is invalidated if get-dependencies_win.ps1 changes (and get-dependencies_win.ps1 is what contains the pinned vcpkg commit).
  - vcpkg/ -> get-dependencies_win.ps1

platform:
  - x64

configuration:
  - Release

install:
  # Initialize Git submodules
  - git submodule update --init --recursive
  # Setup Ruby path (for Asciidoctor gem install)
  - set PATH=C:\Ruby26-x64\bin;%PATH%
  # Install Asciidoctor (for documentation generation)
  # NOTE: Specify an explicit Asciidoctor version to help ensure reproducible builds
  - gem install asciidoctor -v 2.0.9 --no-document

before_build:
  # Set expanded environment variables for release build jobs
  # NOTE: These are set here, instead of in the build matrix above, to maintain consistent job identifiers for release builds
  #       (as the job is identified based on the environment configuration in the matrix)
  - ps: |
      if ($env:WZ_JOB_ID -eq "release_x86_xp") {
        # 32-bit (x86) builds maintain Windows XP compatibility by using Qt 5.6.x and the "*_xp" VC toolchain
        # APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
        # TODO: Change VCPKG_DEFAULT_TRIPLET to one that supports XP once https://github.com/Microsoft/vcpkg/pull/1732 is finalized & merged.
        $env:VCPKG_DEFAULT_TRIPLET = "x86-windows"
        $env:WZ_VC_GENERATOR = "Visual Studio 15 2017"
        $env:QT5DIR = "C:\Qt\5.6\msvc2015"
        $env:WZ_VC_TOOLCHAIN = "v141_xp"
        $env:WZ_VC_TARGET_PLATFORMNAME = "Win32"
        $env:WZ_OUTPUT_PLATFORMNAME = "x86"
      }
      elseif ($env:WZ_JOB_ID -eq "release_x86") {
        # 32-bit (x86) builds use more recent Qt and the latest VC toolchain (and support Windows 7+)
        # APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
        $env:VCPKG_DEFAULT_TRIPLET = "x86-windows"
        $env:WZ_VC_GENERATOR = "Visual Studio 15 2017"
        $env:QT5DIR = "C:\Qt\5.9\msvc2015"
        $env:WZ_VC_TOOLCHAIN = "v141"
        $env:WZ_VC_TARGET_PLATFORMNAME = "Win32"
        $env:WZ_OUTPUT_PLATFORMNAME = "x86"
      }
      elseif ($env:WZ_JOB_ID -eq "release_x64") {
        # 64-bit (x64) builds use the latest Qt and VC toolchain (and support Windows 7+)
        # APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
        $env:VCPKG_DEFAULT_TRIPLET = "x64-windows"
        $env:WZ_VC_GENERATOR = "Visual Studio 15 2017"
        $env:QT5DIR = "C:\Qt\5.9\msvc2017_64"
        $env:WZ_VC_TOOLCHAIN = "v141"
        $env:WZ_VC_TARGET_PLATFORMNAME = "x64"
        $env:WZ_OUTPUT_PLATFORMNAME = "x64"
      }
  # Set distributor (if building from the main repo)
  - ps: |
      $env:WZ_DISTRIBUTOR = "UNKNOWN"
      if ($env:APPVEYOR_ACCOUNT_NAME -eq "Warzone2100") {
        $env:WZ_DISTRIBUTOR = "wz2100.net"
      }
  # Add the QT5 \bin dir to PATH
  - set PATH=%PATH%;%QT5DIR%\bin;
  # If a future version of vcpkg breaks the "VCPKG_BUILD_TYPE=release" setting for the dependencies we need, use the following line instead:
  # - ps: .\get-dependencies_win.ps1
  - ps: .\get-dependencies_win.ps1 -VCPKG_BUILD_TYPE "release"
  # Remove the vcpkg\buildtrees folder. (Once all dependencies are installed, it isn't needed, and it takes up a lot of space in the cache.)
  - ps: if (Test-Path .\vcpkg\buildtrees) { Remove-Item .\vcpkg\buildtrees -Force -Recurse -ErrorAction SilentlyContinue; }
  # Clean the build remnants of vcpkg itself. (Since it's rebuilt fresh - even from a cached vcpkg directory - these aren't needed.)
  - msbuild .\vcpkg\toolsrc\vcpkg.sln /t:Clean /p:Configuration=Release /p:Platform=x86
  # Use CMake to configure with the appropriate Visual Studio (MSBUILD) generator, toolchain, and target platform (portable build)
  - cmake -H. -Bbuild  -DCMAKE_TOOLCHAIN_FILE="%APPVEYOR_BUILD_FOLDER%\vcpkg\scripts\buildsystems\vcpkg.cmake" -DWZ_PORTABLE:BOOL=ON -DCPACK_PACKAGE_FILE_NAME:STRING="warzone2100_portable" -DWZ_DISTRIBUTOR:STRING="%WZ_DISTRIBUTOR%" -G "%WZ_VC_GENERATOR%" -T "%WZ_VC_TOOLCHAIN%" -A "%WZ_VC_TARGET_PLATFORMNAME%"

build:
  parallel: true
  project: build/PACKAGE.vcxproj

after_build:
  # Determine the build output description (nightly vs tag/release builds)
  # For nightly builds, base on the autorevision info: warzone2100-<BRANCH>-<DATE>-<TIME>-<COMMIT_FIRST_7>_<PLATFORM: x86, x64>_<PORTABLE/INSTALLER>.zip
  # For tags/releases, base on the tag name: warzone2100-<TAG_NAME>_<PLATFORM>_<PORTABLE/INSTALLER>.zip (so it can go right to GitHub releases)
  - ps: |
      if (Test-Path 'env:APPVEYOR_REPO_TAG_NAME') {
        # For tag builds, simply use <TAG_NAME>_<PLATFORM>
        $env:WZ_BUILD_DESC = "$($env:APPVEYOR_REPO_TAG_NAME)_$($env:WZ_OUTPUT_PLATFORMNAME)"
      }
      else {
        # For normal builds, use <BRANCH>-<DATE>-<TIME>-<COMMIT_FIRST_7>-<PLATFORM: x86, x64>
        $env:WZ_BUILD_DESC = "$($env:APPVEYOR_REPO_BRANCH)-$(get-date -f yyyyMMdd-HHmmss)-$($env:APPVEYOR_REPO_COMMIT.SubString(0,7))_$($env:WZ_OUTPUT_PLATFORMNAME)"
      }
      $env:WZ_ZIP_DESC = "$($env:APPVEYOR_REPO_BRANCH)_$($env:WZ_OUTPUT_PLATFORMNAME)"
      # Convert special characters
      $env:WZ_BUILD_DESC = $env:WZ_BUILD_DESC.replace('/','_')
      $env:WZ_ZIP_DESC = $env:WZ_ZIP_DESC.replace('/','_')
  - ps: Write-Host "env:WZ_BUILD_DESC='$env:WZ_BUILD_DESC'"

  # Package the portable installer into a zip
  - ps: cmd /c 7z a "warzone2100-$($env:WZ_ZIP_DESC)_portable.zip" "$($env:APPVEYOR_BUILD_FOLDER)\build\warzone2100_portable.exe"
  # Rename the portable installer inside the zip using the WZ_BUILD_DESC (to preserve the commit + other info)
  - ps: cmd /c 7z rn "warzone2100-$($env:WZ_ZIP_DESC)_portable.zip" "warzone2100_portable.exe" "warzone2100-$($env:WZ_BUILD_DESC)_portable.exe"
  # Package the portable .pdb and .sym files into a "DEBUGSYMBOLS" .7z archive (do not include metadata / timestamps)
  - ps: cmd /c 7z a -t7z -m0=lzma -mx=9 -mtc=off -mtm=off -mta=off "warzone2100-$($env:WZ_ZIP_DESC)_portable.DEBUGSYMBOLS.7z" "$($env:APPVEYOR_BUILD_FOLDER)\build\src\*.pdb" "$($env:APPVEYOR_BUILD_FOLDER)\build\src\*.sym"
  
  # Re-run CMake configure for non-portable (regular) installer
  - cmake -H. -Bbuild  -DCMAKE_TOOLCHAIN_FILE="%APPVEYOR_BUILD_FOLDER%\vcpkg\scripts\buildsystems\vcpkg.cmake" -DWZ_PORTABLE:BOOL=OFF -DCPACK_PACKAGE_FILE_NAME:STRING="warzone2100_installer" -DWZ_DISTRIBUTOR:STRING="%WZ_DISTRIBUTOR%" -G "%WZ_VC_GENERATOR%" -T "%WZ_VC_TOOLCHAIN%" -A "%WZ_VC_TARGET_PLATFORMNAME%"
  # Build the regular installer package (this should only rebuild the installer itself)
  - msbuild build/PACKAGE.vcxproj /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll"
  
  # Package the regular installer into a zip
  - ps: cmd /c 7z a "warzone2100-$($env:WZ_ZIP_DESC)_installer.zip" "$($env:APPVEYOR_BUILD_FOLDER)\build\warzone2100_installer.exe"
  # Rename the regular installer inside the zip using the WZ_BUILD_DESC (to preserve the commit + other info)
  - ps: cmd /c 7z rn "warzone2100-$($env:WZ_ZIP_DESC)_installer.zip" "warzone2100_installer.exe" "warzone2100-$($env:WZ_BUILD_DESC)_installer.exe"
  # Package the regular installer .pdb and .sym files into a "DEBUGSYMBOLS" .7z archive (do not include metadata / timestamps)
  - ps: cmd /c 7z a -t7z -m0=lzma -mx=9 -mtc=off -mtm=off -mta=off "warzone2100-$($env:WZ_ZIP_DESC)_installer.DEBUGSYMBOLS.7z" "$($env:APPVEYOR_BUILD_FOLDER)\build\src\*.pdb" "$($env:APPVEYOR_BUILD_FOLDER)\build\src\*.sym"
  
  # Compare the two DEBUGSYMBOLS.7z files
  # If they are equal (as they should be if only the installer was rebuilt), keep only one and remove the "PORTABLE/INSTALLER" suffix
  # If they are not equal, we have to keep both (but output a notice, as the CMake build should probably be tweaked to avoid this)
  - ps: |
      if ((Get-FileHash -LiteralPath "warzone2100-$($env:WZ_ZIP_DESC)_portable.DEBUGSYMBOLS.7z" -Algorithm SHA512).Hash -eq (Get-FileHash -LiteralPath "warzone2100-$($env:WZ_ZIP_DESC)_installer.DEBUGSYMBOLS.7z" -Algorithm SHA512).Hash) {
        # The two archives' hashes match - delete one, and rename the other
        Remove-Item -LiteralPath "warzone2100-$($env:WZ_ZIP_DESC)_installer.DEBUGSYMBOLS.7z" -Force -ErrorAction SilentlyContinue
        Rename-Item -LiteralPath "warzone2100-$($env:WZ_ZIP_DESC)_portable.DEBUGSYMBOLS.7z" -NewName "warzone2100-$($env:WZ_ZIP_DESC).DEBUGSYMBOLS.7z"
      }
      else {
        Write-Warning "The DEBUGSYMBOLS.7z files for the portable + regular builds do not match. This may mean that the executable was rebuilt when switching portable / non-portable mode. (Check the CMake scripts to fix.)"
      }
  
  # Log hashes of the setup EXEs (stored inside the ZIP files)
  - ps: |
      Write-Host "SHA512 Hashes:"
      Write-Host "`nwarzone2100-$($env:WZ_BUILD_DESC)_portable.exe`n  -> SHA512: $((Get-FileHash -LiteralPath "$($env:APPVEYOR_BUILD_FOLDER)\build\warzone2100_portable.exe" -Algorithm SHA512).Hash)`n  -> Size (bytes): $((Get-Item -LiteralPath "$($env:APPVEYOR_BUILD_FOLDER)\build\warzone2100_portable.exe").Length)"
      Write-Host "`nwarzone2100-$($env:WZ_BUILD_DESC)_installer.exe`n  -> SHA512: $((Get-FileHash -LiteralPath "$($env:APPVEYOR_BUILD_FOLDER)\build\warzone2100_installer.exe" -Algorithm SHA512).Hash)`n  -> Size (bytes): $((Get-Item -LiteralPath "$($env:APPVEYOR_BUILD_FOLDER)\build\warzone2100_installer.exe").Length)"
      Write-Host ""

artifacts:
  - path: warzone2100-*_portable.zip
    name: Warzone2100 Portable
  - path: warzone2100-*_installer.zip
    name: Warzone2100 Installer
  - path: warzone2100-*.DEBUGSYMBOLS.7z
    name: Debug Symbols (7z)
