1 <#
2   Copyright (c) DataStax, Inc.
3 
4   Licensed under the Apache License, Version 2.0 (the "License");
5   you may not use this file except in compliance with the License.
6   You may obtain a copy of the License at
7 
8   http://www.apache.org/licenses/LICENSE-2.0
9 
10   Unless required by applicable law or agreed to in writing, software
11   distributed under the License is distributed on an "AS IS" BASIS,
12   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   See the License for the specific language governing permissions and
14   limitations under the License.
15 #>
16 
Get-Commit-Sha()17 Function Get-Commit-Sha {
18   return $($Env:APPVEYOR_REPO_COMMIT.SubString(0,7))
19 }
20 
Get-OpenSSL-Version()21 Function Get-OpenSSL-Version {
22   $openssl_version = "$($(Get-ChildItem Env:"OPENSSL_$($Env:OPENSSL_MAJOR_MINOR.Replace(".", "_"))_VERSION").Value)"
23   return $openssl_version
24 }
25 
Bison-Version-Informationnull26 Function Bison-Version-Information {
27   If (Get-Command "bison" -ErrorAction SilentlyContinue) {
28     $temporary_file = New-TemporaryFile
29     Start-Process -FilePath bison -ArgumentList "--version" -RedirectStandardOutput $($temporary_file) -Wait -NoNewWindow
30     $output = Get-Content "$($temporary_file)" -Raw
31     Write-Host "$($output.Trim())" -BackgroundColor DarkCyan
32     Remove-Item $temporary_file
33   } Else {
34     Write-Host "Bison is not available" -BackgroundColor DarkRed
35   }
36 }
37 
Perl-Version-Informationnull38 Function Perl-Version-Information {
39   If (Get-Command "perl" -ErrorAction SilentlyContinue) {
40     $temporary_file = New-TemporaryFile
41     Start-Process -FilePath perl -ArgumentList "--version" -RedirectStandardOutput $($temporary_file) -Wait -NoNewWindow
42     $output = Get-Content "$($temporary_file)" -Raw
43     Write-Host "$($output.Trim())" -BackgroundColor DarkGray
44     Remove-Item $temporary_file
45   } Else {
46     Write-Host "Perl is not available" -BackgroundColor DarkRed
47   }
48 }
49 
CMake-Version-Informationnull50 Function CMake-Version-Information {
51   If (Get-Command "cmake" -ErrorAction SilentlyContinue) {
52     $temporary_file = New-TemporaryFile
53     Start-Process -FilePath cmake -ArgumentList "--version" -RedirectStandardOutput $($temporary_file) -Wait -NoNewWindow
54     $output = Get-Content "$($temporary_file)" -Raw
55     Write-Host "$($output.Trim())" -BackgroundColor DarkBlue
56     Remove-Item $temporary_file
57   } Else {
58     Write-Host "CMake is not available" -BackgroundColor DarkRed
59   }
60 }
61 
Build-Configuration-Informationnull62 Function Build-Configuration-Information {
63   $output = @"
64 Visual Studio: $($Env:CMAKE_GENERATOR.Split(" ")[-2]) [$($Env:CMAKE_GENERATOR.Split(" ")[-1])]
65 Architecture:  $($Env:Platform)
66 libssh2:       v$($Env:LIBSSH2_VERSION)
67 libuv:         v$($Env:LIBUV_VERSION)
68 OpenSSL:       v$(Get-OpenSSL-Version)
69 zlib:          v$($Env:ZLIB_VERSION)
70 Build Number:  $($Env:APPVEYOR_BUILD_NUMBER)
71 Branch:        $($Env:APPVEYOR_REPO_BRANCH)
72 SHA:           $(Get-Commit-Sha)
73 "@
74   Write-Host "$($output)" -BackgroundColor DarkGreen
75 }
76 
Hardware-Informationnull77 Function Hardware-Information {
78   $computer_system = Get-CimInstance CIM_ComputerSystem
79   $operating_system = Get-CimInstance CIM_OperatingSystem
80   $processor = Get-CimInstance CIM_Processor
81   $logical_disk = Get-CimInstance Win32_LogicalDisk -Filter "DeviceID = 'C:'"
82   $capacity = "{0:N2}" -f ($logical_disk.Size / 1GB)
83   $free_space = "{0:N2}" -f ($logical_disk.FreeSpace / 1GB)
84   $free_space_percentage = "{0:P2}" -f ($logical_disk.FreeSpace / $logical_disk.Size)
85   $ram = "{0:N2}" -f ($computer_system.TotalPhysicalMemory / 1GB)
86 
87   # Determine if hyper-threading is enabled in order to display number of cores
88   $number_of_cores = "$($processor.NumberOfCores)"
89   If ($processor.NumberOfCores -lt $processor.NumberOfLogicalProcessors) {
90     $number_of_cores = "$($processor.NumberOfLogicalProcessors) (Hyper-Threading)"
91   }
92 
93   $hardware_information = @"
94 Hardware Information for $($computer_system.Name):
95   Operating System: $($operating_system.caption) (Version: $($operating_system.Version))
96   CPU: $($processor.Name)
97   Number of Cores: $($number_of_cores)
98   HDD Capacity: $($capacity) GB
99   HDD Free Capacity: $($free_space_percentage) ($($free_space) GB)
100   RAM: $($ram) GB
101 "@
102   Write-Host "$($hardware_information)" -BackgroundColor DarkMagenta
103 }
104 
Environment-Information()105 Function Environment-Information {
106   Write-Host "Visual Studio Environment Variables:" -BackgroundColor DarkMagenta
107   Get-ChildItem Env:VS* | ForEach-Object {
108     Write-Host "  $($_.Name) = $($_.Value)" -BackgroundColor DarkMagenta
109   }
110 }
111 
Initialize-Build-Environmentnull112 Function Initialize-Build-Environment {
113   # Get the versions for the third party dependencies
114   $libssh2_version = $Env:LIBSSH2_VERSION
115   $libuv_version = $Env:LIBUV_VERSION
116   $openssl_version = Get-OpenSSL-Version
117   $Env:OPENSSL_VERSION = $openssl_version
118   $zlib_version = $Env:ZLIB_VERSION
119   $kerberos_version = "4.1"
120   $bison_version = "2.4.1"
121   $perl_version = "5.26.2.1"
122 
123   # Determine the platform and create associate environment variables
124   $Env:CMAKE_PLATFORM = $Env:Platform
125   $lib_architecture = "lib64"
126   $windows_architecture = "win64"
127 
128   # Determine which header file to use for determine driver version
129   $driver_header_file = "cassandra.h"
130   $driver_archive_prefix = "cassandra"
131   If ($Env:DRIVER_TYPE -Like "dse") {
132     $driver_header_file = "dse.h"
133     $driver_archive_prefix = "dse"
134   }
135 
136   # Get the driver version number from the header file
137   $version = @()
138   Get-Content "$($Env:APPVEYOR_BUILD_FOLDER)/include/$($driver_header_file)" | ForEach-Object {
139     If ($_ -Match "#define .*_VERSION_.*") {
140         $token = $_.Split(" ")[-1].Replace("`"", "")
141         If ($token) {
142           $version += , $token
143         }
144     }
145   }
146   $Env:DRIVER_VERSION = "$($version[0]).$($version[1]).$($version[2])"
147   If ($version.Length -eq 4) {
148     $Env:DRIVER_VERSION += "-$($version[3])"
149   }
150 
151   # Generate the variables for use with third party dependencies
152   $bin_location_prefix = "C:/projects/dependencies/bin/"
153   $libs_location_prefix = "C:/projects/dependencies/libs/"
154   $dependencies_location_prefix = "$($libs_location_prefix)/$($Env:Platform)/$($Env:VISUAL_STUDIO_INTERNAL_VERSION)/"
155   $download_url_prefix = "https://raw.githubusercontent.com/mikefero/cpp-driver-msvc-libs/master"
156 
157   # Generate the environment variables for use with the CMake FindXXX scripts
158   $Env:LIBUV_ROOT_DIR = "$($dependencies_location_prefix)/libuv-$($libuv_version)"
159   $Env:OPENSSL_BASE_DIR = "$($dependencies_location_prefix)/openssl-$($openssl_version)"
160   $Env:OPENSSL_ROOT_DIR = "$($Env:OPENSSL_BASE_DIR)/shared"
161   $Env:ZLIB_ROOT_DIR = "$($dependencies_location_prefix)/zlib-$($zlib_version)"
162   $Env:DRIVER_INSTALL_DIR = "C:/projects/driver/lib"
163   $Env:DRIVER_ARTIFACTS_DIR = "C:/projects/driver/artifacts"
164   $Env:DRIVER_ARTIFACTS_LOGS_DIR = "$($Env:DRIVER_ARTIFACTS_DIR)/logs"
165 
166   # Generate the environment variables for the third party archives
167   $Env:KERBEROS_ARCHIVE = "kfw-$($kerberos_version)-$($windows_architecture)-msvc100.zip"
168   $Env:LIBUV_ARTIFACT_ARCHIVE = "libuv-$($libuv_version)-$($windows_architecture)-msvc$($Env:VISUAL_STUDIO_INTERNAL_VERSION).zip"
169   $Env:OPENSSL_ARTIFACT_ARCHIVE = "openssl-$($openssl_version)-$($windows_architecture)-msvc$($Env:VISUAL_STUDIO_INTERNAL_VERSION).zip"
170   $Env:ZLIB_ARTIFACT_ARCHIVE = "zlib-$($zlib_version)-$($windows_architecture)-msvc$($Env:VISUAL_STUDIO_INTERNAL_VERSION).zip"
171 
172   # Generate default environment variables for per commit builds
173   If ($Env:APPVEYOR_BUILD_WORKER_IMAGE -Like "Visual Studio 2019") {
174     $boost_version_directory_suffix = "1_71_0"
175   } Else {
176     $boost_version_directory_suffix = "1_69_0"
177   }
178   $visual_studio_version = "$($Env:VISUAL_STUDIO_INTERNAL_VERSION.Insert(2, "."))"
179 
180   # Generate the default Boost environment variables
181   $Env:BOOST_ROOT = "C:/Libraries/boost_$($boost_version_directory_suffix)"
182   $Env:BOOST_INCLUDEDIR = "$($Env:BOOST_ROOT)/include"
183 
184   # Generate the Kerberos environment variables
185   $Env:KERBEROS_DOWNLOAD_URL = "$($download_url_prefix)/kerberos/$($kerberos_version)/$($Env:KERBEROS_ARCHIVE)"
186   $Env:KERBEROS_EXTRACT_DIR = "$($libs_location_prefix)/$($Env:Platform)/100/kfw-$($kerberos_version)"
187   $Env:KERBEROS_ROOT_DIR = "$($Env:KERBEROS_EXTRACT_DIR)/MIT/Kerberos"
188 
189   # Generate the default libssh2 environment variables
190   $Env:LIBSSH2_ROOT_DIR = "$($dependencies_location_prefix)/libssh2-$($libssh2_version)"
191 
192   # Generate the archive name for the driver test and examples artifacts
193   $build_version = "$($Env:APPVEYOR_BUILD_NUMBER)-$($Env:APPVEYOR_REPO_BRANCH)"
194   # TODO: Re-enable OpenSSL version appending if multiple OpenSSL versions are enabled
195   #$Env:DRIVER_ARTIFACT_EXAMPLES_ARCHIVE = "$($driver_archive_prefix)-cpp-driver-$($Env:DRIVER_VERSION)-examples-openssl-$($Env:OPENSSL_MAJOR_MINOR)-$($windows_architecture)-msvc$($Env:VISUAL_STUDIO_INTERNAL_VERSION).zip"
196   #$Env:DRIVER_ARTIFACT_TESTS_ARCHIVE = "$($driver_archive_prefix)-cpp-driver-$($Env:DRIVER_VERSION)-tests-openssl-$($Env:OPENSSL_MAJOR_MINOR)-$($windows_architecture)-msvc$($Env:VISUAL_STUDIO_INTERNAL_VERSION).zip"
197   $Env:DRIVER_ARTIFACT_EXAMPLES_ARCHIVE = "$($driver_archive_prefix)-cpp-driver-$($Env:DRIVER_VERSION)-examples-$($windows_architecture)-msvc$($Env:VISUAL_STUDIO_INTERNAL_VERSION).zip"
198   $Env:DRIVER_ARTIFACT_TESTS_ARCHIVE = "$($driver_archive_prefix)-cpp-driver-$($Env:DRIVER_VERSION)-tests-$($windows_architecture)-msvc$($Env:VISUAL_STUDIO_INTERNAL_VERSION).zip"
199 
200   # Generate the archive name for the driver packaging
201   # TODO: Re-enable OpenSSL version appending if multiple OpenSSL versions are enabled
202   #$Env:DRIVER_ARTIFACT_ARCHIVE = "$($driver_archive_prefix)-cpp-driver-$($Env:DRIVER_VERSION)-openssl-$($Env:OPENSSL_MAJOR_MINOR)-$($windows_architecture)-msvc$($Env:VISUAL_STUDIO_INTERNAL_VERSION).zip"
203   $Env:DRIVER_ARTIFACT_ARCHIVE = "$($driver_archive_prefix)-cpp-driver-$($Env:DRIVER_VERSION)-$($windows_architecture)-msvc$($Env:VISUAL_STUDIO_INTERNAL_VERSION).zip"
204 
205   # Generate additional download/install environments for third party build requirements
206   $Env:BISON_BINARIES_ARCHIVE = "bison-$($bison_version)-bin.zip"
207   $Env:BISON_BINARIES_DOWNLOAD_URL = "http://downloads.sourceforge.net/gnuwin32/$($Env:BISON_BINARIES_ARCHIVE)"
208   $Env:BISON_DEPENDENCIES_ARCHIVE = "bison-$($bison_version)-dep.zip"
209   $Env:BISON_DEPENDENCIES_DOWNLOAD_URL = "http://downloads.sourceforge.net/gnuwin32/$($Env:BISON_DEPENDENCIES_ARCHIVE)"
210   $Env:BISON_ROOT_DIR = "$($bin_location_prefix)/bison-$($bison_version)"
211   $Env:PERL_STANDALONE_ARCHIVE = "strawberry-perl-$($perl_version)-64bit-portable.zip"
212   $Env:PERL_STANDALONE_DOWNLOAD_URL = "http://strawberryperl.com/download/$($perl_version)/$($Env:PERL_STANDALONE_ARCHIVE)"
213   $Env:PERL_ROOT_DIR = "$($bin_location_prefix)/perl-$($perl_version)"
214 
215   # Update the PATH to include the third party build requirement tools (prepend)
216   $Env:PATH = "$($Env:BISON_ROOT_DIR)/bin;$($Env:PERL_ROOT_DIR)/perl/site/bin;$($Env:PERL_ROOT_DIR)/perl/bin;$($Env:PERL_ROOT_DIR)/c/bin;$($Env:KERBEROS_ROOT_DIR)/bin;$($Env:LIBUV_ROOT_DIR)/bin;$($Env:OPENSSL_ROOT_DIR)/bin;$($Env:PATH)"
217 }
218 
Install-Driver-Environment()219 Function Install-Driver-Environment {
220   # Remove pre-installed OpenSSL (resolve conflicts)
221   Remove-Item -Force -Recurse -Path "C:/OpenSSL-*"
222 
223   # Determine if Bison needs to be installed (cached)
224   If (-Not (Test-Path -Path "$($Env:BISON_ROOT_DIR)")) {
225     # Download and extract the dependency
226     try {
227       Write-Host "Downloading and extracting Bison for Windows"
228       New-Item -ItemType Directory -Force -Path "$($Env:BISON_ROOT_DIR)" | Out-Null
229       $is_download_complete = $False
230       $retries = 0
231       do {
232         try {
233           Invoke-WebRequest -Uri "$($Env:BISON_BINARIES_DOWNLOAD_URL)" -OutFile $Env:BISON_BINARIES_ARCHIVE -UserAgent [Microsoft.PowerShell.Commands.PSUserAgent]::Chrome
234           $is_download_complete = $True
235         } catch {
236           Write-Host "Error downloading Bison binaries; sleeping for 10 seconds ... " -NoNewLine -BackgroundColor DarkRed
237           Start-Sleep -s 10
238           Write-Host "done." -BackgroundColor DarkRed
239           Write-Host "Retrying Bison binaries download"
240         }
241         $retries++
242       } while($is_download_complete -eq $False -and $retries -lt 10)
243       $argument_list = @"
244 -o"$($Env:BISON_ROOT_DIR)" x "$($Env:BISON_BINARIES_ARCHIVE)"
245 "@
246       $process = Start-Process -FilePath 7z -ArgumentList $argument_list -PassThru -Wait -NoNewWindow
247       If ($process.ExitCode -ne 0) {
248         Remove-Item -Force -Recurse -Path "$($Env:BISON_ROOT_DIR)"
249         Throw "Failed to extract Bison binaries"
250       }
251       $is_download_complete = $False
252       $retries = 0
253       do {
254         try {
255           Invoke-WebRequest -Uri "$($Env:BISON_DEPENDENCIES_DOWNLOAD_URL)" -OutFile $Env:BISON_DEPENDENCIES_ARCHIVE -UserAgent [Microsoft.PowerShell.Commands.PSUserAgent]::Chrome
256           $is_download_complete = $True
257         } catch {
258           Write-Host "Error downloading Bison dependencies; sleeping for 10 seconds ... " -NoNewLine -BackgroundColor DarkRed
259           Start-Sleep -s 10
260           Write-Host "done." -BackgroundColor DarkRed
261           Write-Host "Retrying Bison dependencies download"
262         }
263         $retries++
264       } while($is_download_complete -eq $False -and $retries -lt 10)
265       $argument_list = @"
266 -aoa -o"$($Env:BISON_ROOT_DIR)" x "$($Env:BISON_DEPENDENCIES_ARCHIVE)"
267 "@
268       $process = Start-Process -FilePath 7z -ArgumentList $argument_list -PassThru -Wait -NoNewWindow
269       If ($process.ExitCode -ne 0) {
270         Remove-Item -Force -Recurse -Path "$($Env:BISON_ROOT_DIR)"
271         Throw "Failed to extract Bison dependencies"
272       }
273 
274       # Delete the binary archive
275       Remove-Item $Env:BISON_BINARIES_ARCHIVE
276       Remove-Item $Env:BISON_DEPENDENCIES_ARCHIVE
277     } catch {
278       Remove-Item -Force -Recurse -Path "$($Env:BISON_ROOT_DIR)"
279       Throw $PSItem
280     }
281   }
282 
283   # Display the Bison version information
284   Bison-Version-Information
285 
286   # Determine if Strawberry Perl needs to be installed (cached)
287   If (-Not (Test-Path -Path "$($Env:PERL_ROOT_DIR)")) {
288     # Download and extract the dependency
289     try {
290       Write-Host "Downloading and extracting Strawberry Perl for Windows"
291       New-Item -ItemType Directory -Force -Path "$($Env:PERL_ROOT_DIR)" | Out-Null
292       If ($Env:APPVEYOR -Like "True") {
293         Start-FileDownload "$($Env:PERL_STANDALONE_DOWNLOAD_URL)" -FileName $Env:PERL_STANDALONE_ARCHIVE
294       } Else {
295         curl.exe -o "$($Env:PERL_STANDALONE_ARCHIVE)" "$($Env:PERL_STANDALONE_DOWNLOAD_URL)"
296       }
297       $argument_list = @"
298 -o"$($Env:PERL_ROOT_DIR)" x "$($Env:PERL_STANDALONE_ARCHIVE)"
299 "@
300       $process = Start-Process -FilePath 7z -ArgumentList $argument_list -PassThru -Wait -NoNewWindow
301       If ($process.ExitCode -ne 0) {
302         Remove-Item -Force -Recurse -Path "$($Env:PERL_ROOT_DIR)"
303         Throw "Failed to extract Strawberry Perl"
304       }
305 
306       # Delete the binary archive
307       Remove-Item $Env:PERL_STANDALONE_ARCHIVE
308     } catch {
309       Remove-Item -Force -Recurse -Path "$($Env:PERL_ROOT_DIR)"
310       Throw $PSItem
311     }
312   }
313 
314   # Display the Perl and CMake version information
315   Perl-Version-Information
316   CMake-Version-Information
317 
318   # Determine the location of the CMake modules (external projects)
319   $cmake_modules_dir = "$($Env:APPVEYOR_BUILD_FOLDER -Replace `"\\`", `"/`")/"
320   If ($Env:DRIVER_TYPE -Like "dse") {
321     $cmake_modules_dir += "cpp-driver/"
322   }
323   $cmake_modules_dir += "cmake"
324 
325   # Build and install the dependencies (if needed; cached)
326   $dependencies_build_location_prefix = "C:/projects/dependencies/build/"
327   If (-Not (Test-Path -Path "$($Env:LIBUV_ROOT_DIR)/lib")) { # lib directory checked due to external project being CMake (automatically creates root directory)
328     New-Item -ItemType Directory -Force -Path "$($dependencies_build_location_prefix)/libuv" | Out-Null
329     Push-Location -Path "$($dependencies_build_location_prefix)/libuv"
330 
331     $cmakelists_contents = @"
332 cmake_minimum_required(VERSION 2.8.12 FATAL_ERROR)
333 project(libuv)
334 set(PROJECT_DISPLAY_NAME "AppVeyor CI Build for libuv")
335 set(PROJECT_MODULE_DIR $cmake_modules_dir)
336 set(CMAKE_MODULE_PATH `${CMAKE_MODULE_PATH} `${PROJECT_MODULE_DIR})
337 include(ExternalProject-libuv)
338 set(GENERATED_SOURCE_FILE `${CMAKE_CURRENT_BINARY_DIR}/main.cpp)
339 file(REMOVE `${GENERATED_SOURCE_FILE})
340 file(WRITE `${GENERATED_SOURCE_FILE} "int main () { return 0; }")
341 add_executable(`${PROJECT_NAME} `${GENERATED_SOURCE_FILE})
342 add_dependencies(`${PROJECT_NAME} `${LIBUV_LIBRARY_NAME})
343 "@
344     $cmakelists_contents | Out-File -FilePath "CMakeLists.txt" -Encoding Utf8 -Force
345 
346     Write-Host "Configuring libuv"
347     cmake -G "$($Env:CMAKE_GENERATOR)" -A $Env:CMAKE_PLATFORM -DBUILD_SHARED_LIBS=On "-DLIBUV_VERSION=$($Env:LIBUV_VERSION)" "-DLIBUV_INSTALL_PREFIX=$($Env:LIBUV_ROOT_DIR)" .
348     If ($LastExitCode -ne 0) {
349       If (Test-Path -Path "build/CMakeFiles/CMakeOutput.log") {
350         Push-AppveyorArtifact "build/CMakeFiles/CMakeOutput.log" -DeploymentName "libuv Output Log"
351       }
352       If (Test-Path -Path "build/CMakeFiles/CMakeError.log") {
353         Push-AppveyorArtifact "build/CMakeFiles/CMakeError.log" -DeploymentName "libuv Error Log"
354       }
355       Pop-Location
356       Throw "Failed to configure libuv for MSVC $($Env:VISUAL_STUDIO_INTERNAL_VERSION)-$($Env:Platform)"
357     }
358     Write-Host "Building and Installing libuv"
359     cmake --build . --config RelWithDebInfo
360     If ($LastExitCode -ne 0) {
361       If (Test-Path -Path "build/CMakeFiles/CMakeOutput.log") {
362         Push-AppveyorArtifact "build/CMakeFiles/CMakeOutput.log" -DeploymentName "libuv Output Log"
363       }
364       If (Test-Path -Path "build/CMakeFiles/CMakeError.log") {
365         Push-AppveyorArtifact "build/CMakeFiles/CMakeError.log" -DeploymentName "libuv Error Log"
366       }
367       Pop-Location
368       Throw "Failed to build libuv for MSVC $($Env:VISUAL_STUDIO_INTERNAL_VERSION)-$($Env:Platform)"
369     }
370 
371     Pop-Location
372   }
373 
374   $library_types = ("shared", "static")
375   $library_types | foreach {
376     If (-Not (Test-Path -Path "$($Env:OPENSSL_BASE_DIR)/$_")) {
377       New-Item -ItemType Directory -Force -Path "$($dependencies_build_location_prefix)/openssl/$_" | Out-Null
378       Push-Location -Path "$($dependencies_build_location_prefix)/openssl/$_"
379 
380       $cmakelists_contents = @"
381 cmake_minimum_required(VERSION 2.8.12 FATAL_ERROR)
382 project(OpenSSL)
383 set(PROJECT_DISPLAY_NAME "AppVeyor CI Build for OpenSSL")
384 set(PROJECT_MODULE_DIR $cmake_modules_dir)
385 set(CMAKE_MODULE_PATH `${CMAKE_MODULE_PATH} `${PROJECT_MODULE_DIR})
386 include(ExternalProject-OpenSSL)
387 set(GENERATED_SOURCE_FILE `${CMAKE_CURRENT_BINARY_DIR}/main.cpp)
388 file(REMOVE `${GENERATED_SOURCE_FILE})
389 file(WRITE `${GENERATED_SOURCE_FILE} "int main () { return 0; }")
390 add_executable(`${PROJECT_NAME} `${GENERATED_SOURCE_FILE})
391 add_dependencies(`${PROJECT_NAME} `${OPENSSL_LIBRARY_NAME})
392 "@
393       $cmakelists_contents | Out-File -FilePath "CMakeLists.txt" -Encoding Utf8 -Force
394 
395       Write-Host "Configuring OpenSSL [$_]"
396       $shared_libs = "Off"
397       if ("$_" -Like "shared") {
398         $shared_libs = "On"
399       }
400       cmake -G "$($Env:CMAKE_GENERATOR)" -A $Env:CMAKE_PLATFORM "-DBUILD_SHARED_LIBS=$($shared_libs)" "-DOPENSSL_VERSION=$($Env:OPENSSL_VERSION)" "-DOPENSSL_INSTALL_PREFIX=$($Env:OPENSSL_BASE_DIR)/$_" .
401       If ($LastExitCode -ne 0) {
402         If (Test-Path -Path "build/CMakeFiles/CMakeOutput.log") {
403           Push-AppveyorArtifact "build/CMakeFiles/CMakeOutput.log" -DeploymentName "OpenSSL Output Log"
404         }
405         If (Test-Path -Path "build/CMakeFiles/CMakeError.log") {
406           Push-AppveyorArtifact "build/CMakeFiles/CMakeError.log" -DeploymentName "OpenSSL Error Log"
407         }
408         Pop-Location
409         Throw "Failed to configure OpenSSL for MSVC $($Env:VISUAL_STUDIO_INTERNAL_VERSION)-$($Env:Platform)"
410       }
411       Write-Host "Building and Installing OpenSSL [$_]"
412       cmake --build . --config RelWithDebInfo
413       If ($LastExitCode -ne 0) {
414         If (Test-Path -Path "build/CMakeFiles/CMakeOutput.log") {
415           Push-AppveyorArtifact "build/CMakeFiles/CMakeOutput.log" -DeploymentName "OpenSSL Output Log"
416         }
417         If (Test-Path -Path "build/CMakeFiles/CMakeError.log") {
418           Push-AppveyorArtifact "build/CMakeFiles/CMakeError.log" -DeploymentName "OpenSSL Error Log"
419         }
420         Pop-Location
421         Throw "Failed to build OpenSSL for MSVC $($Env:VISUAL_STUDIO_INTERNAL_VERSION)-$($Env:Platform)"
422       }
423 
424       Pop-Location
425     }
426   }
427 
428   If (-Not (Test-Path -Path "$($Env:ZLIB_ROOT_DIR)/lib")) {
429     New-Item -ItemType Directory -Force -Path "$($dependencies_build_location_prefix)/zlib" | Out-Null
430     Push-Location -Path "$($dependencies_build_location_prefix)/zlib"
431 
432     $cmakelists_contents = @"
433 cmake_minimum_required(VERSION 2.8.12 FATAL_ERROR)
434 project(zlib)
435 set(PROJECT_DISPLAY_NAME "AppVeyor CI Build for zlib")
436 set(PROJECT_MODULE_DIR $cmake_modules_dir)
437 set(CMAKE_MODULE_PATH `${CMAKE_MODULE_PATH} `${PROJECT_MODULE_DIR})
438 include(ExternalProject-zlib)
439 set(GENERATED_SOURCE_FILE `${CMAKE_CURRENT_BINARY_DIR}/main.cpp)
440 file(REMOVE `${GENERATED_SOURCE_FILE})
441 file(WRITE `${GENERATED_SOURCE_FILE} "int main () { return 0; }")
442 add_executable(`${PROJECT_NAME} `${GENERATED_SOURCE_FILE})
443 add_dependencies(`${PROJECT_NAME} `${ZLIB_LIBRARY_NAME})
444 "@
445     $cmakelists_contents | Out-File -FilePath "CMakeLists.txt" -Encoding Utf8 -Force
446 
447     Write-Host "Configuring zlib"
448     cmake -G "$($Env:CMAKE_GENERATOR)" -A $Env:CMAKE_PLATFORM -DBUILD_SHARED_LIBS=On "-DZLIB_VERSION=$($Env:ZLIB_VERSION)" "-DZLIB_INSTALL_PREFIX=$($Env:ZLIB_ROOT_DIR)" .
449     If ($LastExitCode -ne 0) {
450       If (Test-Path -Path "build/CMakeFiles/CMakeOutput.log") {
451         Push-AppveyorArtifact "build/CMakeFiles/CMakeOutput.log" -DeploymentName "zlib Output Log"
452       }
453       If (Test-Path -Path "build/CMakeFiles/CMakeError.log") {
454         Push-AppveyorArtifact "build/CMakeFiles/CMakeError.log" -DeploymentName "zlib Error Log"
455       }
456       Pop-Location
457       Throw "Failed to configure zlib for MSVC $($Env:VISUAL_STUDIO_INTERNAL_VERSION)-$($Env:Platform)"
458     }
459     Write-Host "Building and Installing zlib"
460     cmake --build . --config RelWithDebInfo
461     If ($LastExitCode -ne 0) {
462       If (Test-Path -Path "build/CMakeFiles/CMakeOutput.log") {
463         Push-AppveyorArtifact "build/CMakeFiles/CMakeOutput.log" -DeploymentName "zlib Output Log"
464       }
465       If (Test-Path -Path "build/CMakeFiles/CMakeError.log") {
466         Push-AppveyorArtifact "build/CMakeFiles/CMakeError.log" -DeploymentName "zlib Error Log"
467       }
468       Pop-Location
469       Throw "Failed to build zlib for MSVC $($Env:VISUAL_STUDIO_INTERNAL_VERSION)-$($Env:Platform)"
470     }
471 
472     Pop-Location
473   }
474 
475   # Determine if Kerberos for Windows should be installed (cached)
476   If (-Not (Test-Path -Path "$($Env:KERBEROS_ROOT_DIR)")) {
477     # Download and extract the dependency
478     try {
479       Write-Host "Downloading and extracting Kerberos for Windows"
480       New-Item -ItemType Directory -Force -Path "$($Env:KERBEROS_ROOT_DIR)" | Out-Null
481       If ($Env:APPVEYOR -Like "True") {
482         Start-FileDownload "$($Env:KERBEROS_DOWNLOAD_URL)" -FileName $Env:KERBEROS_ARCHIVE
483       } Else {
484         curl.exe -o "$($Env:KERBEROS_ARCHIVE)" "$($Env:KERBEROS_DOWNLOAD_URL)"
485       }
486       $argument_list = @"
487 -o"$($Env:KERBEROS_EXTRACT_DIR)" x "$($Env:KERBEROS_ARCHIVE)"
488 "@
489       $process = Start-Process -FilePath 7z -ArgumentList $argument_list -PassThru -Wait -NoNewWindow
490       If ($process.ExitCode -ne 0) {
491         Remove-Item -Force -Recurse -Path "$($Env:KERBEROS_EXTRACT_DIR)"
492         Throw "Failed to extract Kerberos"
493       }
494 
495       # Delete the binary archive
496       Remove-Item $Env:KERBEROS_ARCHIVE
497     } catch {
498       Remove-Item -Force -Recurse -Path "$($Env:KERBEROS_EXTRACT_DIR)"
499       Throw $PSItem
500     }
501   }
502 
503   # Determine if libssh2 should be installed (cached)
504   If (-Not (Test-Path -Path "$($Env:LIBSSH2_ROOT_DIR)/lib")) { # lib directory checked due to external project being CMake (automatically creates root directory)
505     New-Item -ItemType Directory -Force -Path "$($dependencies_build_location_prefix)/libssh2" | Out-Null
506     Push-Location -Path "$($dependencies_build_location_prefix)/libssh2"
507 
508     $cmakelists_contents = @"
509 cmake_minimum_required(VERSION 2.8.12 FATAL_ERROR)
510 project(libssh2)
511 set(PROJECT_DISPLAY_NAME "AppVeyor CI Build for libssh2")
512 set(PROJECT_MODULE_DIR $cmake_modules_dir)
513 set(CMAKE_MODULE_PATH `${CMAKE_MODULE_PATH} `${PROJECT_MODULE_DIR})
514 include(ExternalProject-libssh2)
515 set(GENERATED_SOURCE_FILE `${CMAKE_CURRENT_BINARY_DIR}/main.cpp)
516 file(REMOVE `${GENERATED_SOURCE_FILE})
517 file(WRITE `${GENERATED_SOURCE_FILE} "int main () { return 0; }")
518 add_executable(`${PROJECT_NAME} `${GENERATED_SOURCE_FILE})
519 add_dependencies(`${PROJECT_NAME} `${LIBSSH2_LIBRARY_NAME})
520 "@
521     $cmakelists_contents | Out-File -FilePath "CMakeLists.txt" -Encoding Utf8 -Force
522 
523     Write-Host "Configuring libssh2"
524     cmake -G "$($Env:CMAKE_GENERATOR)" -A $Env:CMAKE_PLATFORM "-DLIBSSH2_VERSION=$($Env:LIBSSH2_VERSION)" "-DLIBSSH2_INSTALL_PREFIX=$($Env:LIBSSH2_ROOT_DIR)" .
525     If ($LastExitCode -ne 0) {
526       If (Test-Path -Path "build/CMakeFiles/CMakeOutput.log") {
527         Push-AppveyorArtifact "build/CMakeFiles/CMakeOutput.log" -DeploymentName "libssh2 Output Log"
528       }
529       If (Test-Path -Path "build/CMakeFiles/CMakeError.log") {
530         Push-AppveyorArtifact "build/CMakeFiles/CMakeError.log" -DeploymentName "libssh2 Error Log"
531       }
532       Pop-Location
533       Throw "Failed to configure libssh2 for MSVC $($Env:VISUAL_STUDIO_INTERNAL_VERSION)-$($Env:Platform)"
534     }
535     Write-Host "Building and Installing libssh2"
536     cmake --build . --config RelWithDebInfo
537     If ($LastExitCode -ne 0) {
538       If (Test-Path -Path "build/CMakeFiles/CMakeOutput.log") {
539         Push-AppveyorArtifact "build/CMakeFiles/CMakeOutput.log" -DeploymentName "libssh2 Output Log"
540       }
541       If (Test-Path -Path "build/CMakeFiles/CMakeError.log") {
542         Push-AppveyorArtifact "build/CMakeFiles/CMakeError.log" -DeploymentName "libssh2 Error Log"
543       }
544       Pop-Location
545       Throw "Failed to build libssh2 for MSVC $($Env:VISUAL_STUDIO_INTERNAL_VERSION)-$($Env:Platform)"
546     }
547 
548     Pop-Location
549   }
550 
551   # Archive any dependency builds logs and perform cleanup
552   Get-ChildItem -File -Filter "*.log" -Recurse -Path "C:/projects/dependencies/build" | ForEach-Object {
553     If ($_.FullName.ToLower() -Match "-stamp" -And
554         $_.Length -gt 0kb) {
555       New-Item -ItemType Directory -Force -Path "$($Env:DRIVER_ARTIFACTS_LOGS_DIR)" | Out-Null
556       Copy-Item -Force -Path "$($_.FullName)" "$($Env:DRIVER_ARTIFACTS_LOGS_DIR)"
557     }
558   }
559 }
560 
Build-Driver()561 Function Build-Driver {
562   # Ensure Boost atomic is used for Visual Studio 2010 (increased performance)
563   $use_boost_atomic = "Off"
564   If ($Env:VISUAL_STUDIO_INTERNAL_VERSION -Like "100") {
565     $use_boost_atomic = "On" # Enable Boost atomic usage
566   }
567 
568   # Build the driver
569   $driver_type = "Apache Cassandra and DataStax Products"
570   If ($Env:DRIVER_TYPE -Like "dse") {
571     $driver_type = "DSE"
572   }
573   New-Item -ItemType Directory -Force -Path "$($Env:APPVEYOR_BUILD_FOLDER)/build"
574   Push-Location "$($Env:APPVEYOR_BUILD_FOLDER)/build"
575   Write-Host "Configuring DataStax C/C++ $($driver_type) Driver"
576   cmake -G "$($Env:CMAKE_GENERATOR)" -A $Env:CMAKE_PLATFORM "-D$($Env:DRIVER_TYPE)_MULTICORE_COMPILATION=On" "-D$($Env:DRIVER_TYPE)_USE_KERBEROS=On" "-D$($Env:DRIVER_TYPE)_USE_OPENSSL=On" "-D$($Env:DRIVER_TYPE)_USE_ZLIB=On" "-D$($Env:DRIVER_TYPE)_USE_BOOST_ATOMIC=$($use_boost_atomic)" "-D$($Env:DRIVER_TYPE)_BUILD_EXAMPLES=On" "-D$($Env:DRIVER_TYPE)_BUILD_TESTS=On" "-D$($Env:DRIVER_TYPE)_USE_LIBSSH2=On" "-DCMAKE_INSTALL_PREFIX=`"$($Env:DRIVER_INSTALL_DIR)`"" ..
577   If ($LastExitCode -ne 0) {
578     Pop-Location
579     Throw "Failed to configure DataStax C/C++ $($driver_type) Driver for MSVC $($Env:VISUAL_STUDIO_INTERNAL_VERSION)-$($Env:Platform)"
580   }
581   Write-Host "Building and Installing DataStax C/C++ $($driver_type) Driver"
582   cmake --build . --config RelWithDebInfo --target install
583   If ($LastExitCode -ne 0) {
584     Pop-Location
585     Throw "Failed to build DataStax C/C++ $($driver_type) Driver for MSVC $($Env:VISUAL_STUDIO_INTERNAL_VERSION)-$($Env:Platform)"
586   }
587   Pop-Location
588 
589   # Copy the binary artifacts
590   New-Item -ItemType Directory -Force -Path "$($Env:DRIVER_ARTIFACTS_DIR)/bin/examples" | Out-Null
591   New-Item -ItemType Directory -Force -Path "$($Env:DRIVER_ARTIFACTS_DIR)/bin/tests" | Out-Null
592   Get-ChildItem -File -Filter "*.exe" -Recurse -Path "$($Env:APPVEYOR_BUILD_FOLDER)/build" | ForEach-Object {
593     If ($_.FullName.ToLower() -Match "relwithdebinfo") {
594       $suffix="bin"
595      If ($_.FullName.ToLower() -Match "examples") {
596         $suffix+="/examples"
597       } ElseIf ($_.FullName.ToLower() -Match "test.*exe") {
598         $suffix+="/tests"
599       }
600       Copy-Item -Force -Path "$($_.FullName)" "$($Env:DRIVER_ARTIFACTS_DIR)/$($suffix)"
601     }
602   }
603 }
604 
Execute-Driver-Unit-Tests()605 Function Execute-Driver-Unit-Tests {
606   # Update the PATH for the test executables to run with output
607   $Env:PATH = "$($Env:DRIVER_ARTIFACTS_DIR)/bin/tests;$($Env:PATH)"
608 
609   # Execute the unit tests
610   $is_failure = $False
611   cassandra-unit-tests.exe --gtest_output=xml:"$($Env:DRIVER_ARTIFACTS_DIR)\bin\tests\unit-tests-gtest-results.xml"
612   If ($LastExitCode -ne 0) {
613     Throw "Error Executing Unit tests: Check tests tab or download from the artifacts"
614   }
615 }
616 
Push-Driver-Unit-Tests-Results()617 Function Push-Driver-Unit-Tests-Results {
618   # Push the unit test(s) results
619   If ($Env:APPVEYOR -Like "True") {
620     $web_client = New-Object "System.Net.WebClient"
621     Get-ChildItem -File -Filter "*.xml" -Path "$($Env:DRIVER_ARTIFACTS_DIR)/bin/tests" -Recurse | ForEach-Object {
622       $web_client.UploadFile("https://ci.appveyor.com/api/testresults/junit/$($Env:APPVEYOR_JOB_ID)", (Resolve-Path "$($_.FullName)"))
623     }
624   }
625 }
626 
Package-Artifacts()627 Function Package-Artifacts {
628   # Package the driver artifacts
629   New-Item -ItemType Directory -Force -Path "$($Env:DRIVER_ARTIFACTS_DIR)" | Out-Null
630   $argument_list = @"
631 a -tzip "$($Env:DRIVER_ARTIFACTS_DIR)/$($Env:DRIVER_ARTIFACT_ARCHIVE)" -r "$($Env:DRIVER_INSTALL_DIR)/*"
632 "@
633   $process = Start-Process -FilePath 7z -ArgumentList $argument_list -PassThru -Wait -NoNewWindow
634   If ($process.ExitCode -ne 0) {
635     Throw "Failed to archive driver for MSVC $($Env:VISUAL_STUDIO_INTERNAL_VERSION)-$($Env:Platform)"
636   }
637 
638   # Package the driver example and test artifacts
639   $argument_list = @"
640 a -tzip "$($Env:DRIVER_ARTIFACTS_DIR)/$($Env:DRIVER_ARTIFACT_EXAMPLES_ARCHIVE)" -r "$($Env:DRIVER_ARTIFACTS_DIR)/bin/examples/*"
641 "@
642   $process = Start-Process -FilePath 7z -ArgumentList $argument_list -PassThru -Wait -NoNewWindow
643   If ($process.ExitCode -ne 0) {
644     Throw "Failed to archive driver examples for MSVC $($Env:VISUAL_STUDIO_INTERNAL_VERSION)-$($Env:Platform)"
645   }
646   $argument_list = @"
647 a -tzip "$($Env:DRIVER_ARTIFACTS_DIR)/$($Env:DRIVER_ARTIFACT_TESTS_ARCHIVE)" -r "$($Env:DRIVER_ARTIFACTS_DIR)/bin/tests/*.exe"
648 "@
649   $process = Start-Process -FilePath 7z -ArgumentList $argument_list -PassThru -Wait -NoNewWindow
650   If ($process.ExitCode -ne 0) {
651     Throw "Failed to archive driver tests for MSVC $($Env:VISUAL_STUDIO_INTERNAL_VERSION)-$($Env:Platform)"
652   }
653 
654   # Clean up the library dependency directories for libuv packaging
655   New-Item -ItemType Directory -Force -Path "$($Env:DRIVER_ARTIFACTS_DIR)/libuv" | Out-Null
656   Copy-Item -Force -Recurse -Path "$($Env:LIBUV_ROOT_DIR)/*" "$($Env:DRIVER_ARTIFACTS_DIR)/libuv" | Out-Null
657   $argument_list = @"
658 a -tzip "$($Env:DRIVER_ARTIFACTS_DIR)/$($Env:LIBUV_ARTIFACT_ARCHIVE)" -r "$($Env:DRIVER_ARTIFACTS_DIR)/libuv/*"
659 "@
660   $process = Start-Process -FilePath 7z -ArgumentList $argument_list -PassThru -Wait -NoNewWindow
661   If ($process.ExitCode -ne 0) {
662     Throw "Failed to archive libuv for MSVC $($Env:VISUAL_STUDIO_INTERNAL_VERSION)-$($Env:Platform)"
663   }
664 
665   # Clean up the library dependency directories for OpenSSL packaging
666   New-Item -ItemType Directory -Force -Path "$($Env:DRIVER_ARTIFACTS_DIR)/openssl" | Out-Null
667   Copy-Item -Force -Recurse -Path "$($Env:OPENSSL_BASE_DIR)/*" "$($Env:DRIVER_ARTIFACTS_DIR)/openssl" | Out-Null
668   Move-Item -Force -Path "$($Env:DRIVER_ARTIFACTS_DIR)/openssl/static/LICENSE" "$($Env:DRIVER_ARTIFACTS_DIR)/openssl" | Out-Null
669   Move-Item -Force -Path "$($Env:DRIVER_ARTIFACTS_DIR)/openssl/static/include" "$($Env:DRIVER_ARTIFACTS_DIR)/openssl" | Out-Null
670   Move-Item -Force -Path "$($Env:DRIVER_ARTIFACTS_DIR)/openssl/static/openssl.cnf" "$($Env:DRIVER_ARTIFACTS_DIR)/openssl" | Out-Null
671   If (Test-Path -Path "$($Env:DRIVER_ARTIFACTS_DIR)/openssl/static/openssl.cnf.dist") {
672     Move-Item -Force -Path "$($Env:DRIVER_ARTIFACTS_DIR)/openssl/static/openssl.cnf.dist" "$($Env:DRIVER_ARTIFACTS_DIR)/openssl" | Out-Null
673   }
674   Remove-Item -Force -Recurse -Path "$($Env:DRIVER_ARTIFACTS_DIR)/openssl/shared/include" | Out-Null
675   Remove-Item -Force -Path "$($Env:DRIVER_ARTIFACTS_DIR)/openssl/shared/LICENSE" | Out-Null
676   Remove-Item -Force -Path "$($Env:DRIVER_ARTIFACTS_DIR)/openssl/shared/openssl.cnf" | Out-Null
677   If (Test-Path -Path "$($Env:DRIVER_ARTIFACTS_DIR)/openssl/shared/openssl.cnf.dist") {
678     Remove-Item -Force -Path "$($Env:DRIVER_ARTIFACTS_DIR)/openssl/shared/openssl.cnf.dist" | Out-Null
679   }
680   $argument_list = @"
681 a -tzip "$($Env:DRIVER_ARTIFACTS_DIR)/$($Env:OPENSSL_ARTIFACT_ARCHIVE)" -r "$($Env:DRIVER_ARTIFACTS_DIR)/openssl/*"
682 "@
683   $process = Start-Process -FilePath 7z -ArgumentList $argument_list -PassThru -Wait -NoNewWindow
684   If ($process.ExitCode -ne 0) {
685     Throw "Failed to archive OpenSSL for MSVC $($Env:VISUAL_STUDIO_INTERNAL_VERSION)-$($Env:Platform)"
686   }
687 
688   # Clean up the library dependency directories for zlib packaging
689   New-Item -ItemType Directory -Force -Path "$($Env:DRIVER_ARTIFACTS_DIR)/zlib" | Out-Null
690   Copy-Item -Force -Recurse -Path "$($Env:ZLIB_ROOT_DIR)/*" "$($Env:DRIVER_ARTIFACTS_DIR)/zlib" | Out-Null
691   $argument_list = @"
692 a -tzip "$($Env:DRIVER_ARTIFACTS_DIR)/$($Env:ZLIB_ARTIFACT_ARCHIVE)" -r "$($Env:DRIVER_ARTIFACTS_DIR)/zlib/*"
693 "@
694   $process = Start-Process -FilePath 7z -ArgumentList $argument_list -PassThru -Wait -NoNewWindow
695   If ($process.ExitCode -ne 0) {
696     Throw "Failed to archive zlib for MSVC $($Env:VISUAL_STUDIO_INTERNAL_VERSION)-$($Env:Platform)"
697   }
698 }
699 
Push-Artifacts()700 Function Push-Artifacts {
701   If ($Env:APPVEYOR -Like "True") {
702     $driver_type = "Apache Cassandra and DataStax Products"
703     If ($Env:DRIVER_TYPE -Like "dse") {
704       $driver_type = "DSE"
705     }
706 
707     Push-AppveyorArtifact "$($Env:DRIVER_ARTIFACTS_DIR)/$($Env:DRIVER_ARTIFACT_ARCHIVE)" -DeploymentName "DataStax C/C++ $($driver_type) Driver"
708     Push-AppveyorArtifact "$($Env:DRIVER_ARTIFACTS_DIR)/$($Env:DRIVER_ARTIFACT_EXAMPLES_ARCHIVE)" -DeploymentName "DataStax C/C++ $($driver_type) Driver Examples"
709     Push-AppveyorArtifact "$($Env:DRIVER_ARTIFACTS_DIR)/$($Env:DRIVER_ARTIFACT_TESTS_ARCHIVE)" -DeploymentName "DataStax C/C++ $($driver_type) Driver Tests"
710     Push-AppveyorArtifact "$($Env:DRIVER_ARTIFACTS_DIR)/$($Env:LIBUV_ARTIFACT_ARCHIVE)" -DeploymentName "libuv v$($Env:LIBUV_VERSION)"
711     Push-AppveyorArtifact "$($Env:DRIVER_ARTIFACTS_DIR)/$($Env:OPENSSL_ARTIFACT_ARCHIVE)" -DeploymentName "OpenSSL v$($Env:OPENSSL_VERSION)"
712     Push-AppveyorArtifact "$($Env:DRIVER_ARTIFACTS_DIR)/$($Env:ZLIB_ARTIFACT_ARCHIVE)" -DeploymentName "zlib v$($Env:ZLIB_VERSION)"
713   }
714 }
715 
Publish-Artifact-To-Artifactory()716 Function Publish-Artifact-To-Artifactory {
717   Param (
718     [Parameter(Mandatory=$True)] [String] $Uri,
719     [Parameter(Mandatory=$True)] [String] $FilePath,
720     [Parameter(Mandatory=$False)] [Int] $TimeoutSec = 480
721   )
722 
723   # Create the credentials and checksum headers
724   $username = "$($Env:ARTIFACTORY_USERNAME)"
725   $password = ConvertTo-SecureString -String "$($Env:ARTIFACTORY_PASSWORD)" -AsPlainText -Force
726   $credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $username, $password
727   $md5_hash = $(Get-FileHash "$($FilePath)" -Algorithm MD5).Hash
728   $sha1_hash = $(Get-FileHash "$($FilePath)" -Algorithm SHA1).Hash
729   $sha256_hash = $(Get-FileHash "$($FilePath)" -Algorithm SHA256).Hash
730   $headers = @{
731 #    "X-Checksum-Deploy" = $True
732     "X-Checksum-Md5" = $md5_hash
733     "X-Checksum-Sha1" = $sha1_hash
734     "X-Checksum-Sha256" = $sha256_hash
735   }
736 
737   # Publish the artifacts to artifactory
738   Try {
739     [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 # Ensure TLS v1.2 is enabled
740     $result = Invoke-RestMethod -Headers $headers -Uri "$($Uri)" -Method Put -InFile "$($FilePath)" -Credential $credential -ContentType "multipart/form-data" -TimeoutSec $TimeoutSec
741   } Catch {
742     $error_code = $_.Exception.Response.StatusCode.value__
743     $message = $_.Exception.Message
744     $filename = Split-Path $FilePath -leaf
745     If ($Env:APPVEYOR -Like "True") {
746       Add-AppveyorMessage -Category Error -Message "Unable to Upload $($filename) [$($error_code)]" -Details "$($message)"
747     } Else {
748       Write-Error -Message "Unable to Upload $($filename) [$($error_code)]: $($message)"
749     }
750     return $error_code
751   }
752   return 0
753 }
754 
Publish-Artifacts()755 Function Publish-Artifacts {
756   # Determine if the artifacts should to published to Artifactory
757   If ($Env:APPVEYOR_REPO_TAG -Like "True") {
758     # Create the upload environment
759     $driver_type = "cassandra"
760     If ($Env:DRIVER_TYPE -Like "dse") {
761       $driver_type = "dse"
762     }
763 
764     # Create the Uri and FilePath components for the upload
765     $base_uri = "$($Env:ARTIFACTORY_BASE_URI)/$($Env:DRIVER_VERSION)/$(Get-Commit-Sha)/windows"
766     $driver_uri = "$($base_uri)/$($driver_type)/v$($Env:DRIVER_VERSION)/$($Env:DRIVER_ARTIFACT_ARCHIVE)"
767     $driver_archive = "$($Env:DRIVER_ARTIFACTS_DIR)/$($Env:DRIVER_ARTIFACT_ARCHIVE)"
768     $libuv_uri = "$($base_uri)/dependencies/libuv/v$($Env:LIBUV_VERSION)/$($Env:LIBUV_ARTIFACT_ARCHIVE)"
769     $libuv_archive = "$($Env:DRIVER_ARTIFACTS_DIR)/$($Env:LIBUV_ARTIFACT_ARCHIVE)"
770     #TODO: Need to handle OpenSSL v1.1.x if enabled
771     $openssl_uri = "$($base_uri)/dependencies/openssl/v$($Env:OPENSSL_VERSION)/$($Env:OPENSSL_ARTIFACT_ARCHIVE)"
772     $openssl_archive = "$($Env:DRIVER_ARTIFACTS_DIR)/$($Env:OPENSSL_ARTIFACT_ARCHIVE)"
773     $zlib_uri = "$($base_uri)/dependencies/zlib/v$($Env:ZLIB_VERSION)/$($Env:ZLIB_ARTIFACT_ARCHIVE)"
774     $zlib_archive = "$($Env:DRIVER_ARTIFACTS_DIR)/$($Env:ZLIB_ARTIFACT_ARCHIVE)"
775 
776     # Publish/Upload the driver and it dependencies to Artifactory
777     $is_failure = $False
778     $failed_upload = @()
779     If ((Publish-Artifact-To-Artifactory -Uri "$($driver_uri)" -FilePath "$($driver_archive)") -ne 0) {
780       $is_failure = $True
781       $failed_upload += "Driver"
782     }
783     If ((Publish-Artifact-To-Artifactory -Uri "$($libuv_uri)" -FilePath "$($libuv_archive)") -ne 0) {
784       $is_failure = $True
785       $failed_upload += "libuv"
786     }
787     #TODO: Need to handle OpenSSL v1.1.x if enabled
788     If ((Publish-Artifact-To-Artifactory -Uri "$($openssl_uri)" -FilePath "$($openssl_archive)") -ne 0) {
789       $is_failure = $True
790       $failed_upload += "OpenSSL"
791     }
792     If ((Publish-Artifact-To-Artifactory -Uri "$($zlib_uri)" -FilePath "$($zlib_archive)") -ne 0) {
793       $is_failure = $True
794       $failed_upload += "zlib"
795     }
796 
797     # Check to see if there was a failure uploading the artifacts
798     If ($is_failure) {
799       Throw "Error Uploading Artifacts to Artifactory: $($failed_upload -Join ", ")"
800     }
801   }
802 }
803 
Push-Build-Logs()804 Function Push-Build-Logs {
805   If ($Env:APPVEYOR -Like "True") {
806     # Determine the prefix directory based on driver type
807     $prefix_dir = "./"
808     If ($Env:DRIVER_TYPE -Like "dse") {
809       $prefix_dir += "cpp-driver"
810     }
811 
812     # Push the logs for the builds that occurred
813     If (Test-Path -Path "$($Env:DRIVER_ARTIFACTS_LOGS_DIR)") {
814       $argument_list = @"
815 a -tzip "cmake_external_project_logs.zip" -r "$($Env:DRIVER_ARTIFACTS_LOGS_DIR)/*.log"
816 "@
817       $process = Start-Process -FilePath 7z -ArgumentList $argument_list -PassThru -Wait -NoNewWindow
818       If ($process.ExitCode -eq 0) {
819         Push-AppveyorArtifact "cmake_external_project_logs.zip" -DeploymentName "CMake External Project Logs"
820       }
821     }
822     If (Test-Path -Path "$($Env:APPVEYOR_BUILD_FOLDER)/build/CMakeFiles/CMakeOutput.log") {
823       Push-AppveyorArtifact "$($Env:APPVEYOR_BUILD_FOLDER)/build/CMakeFiles/CMakeOutput.log" -DeploymentName "Driver Output Log"
824     }
825     If (Test-Path -Path "$($Env:APPVEYOR_BUILD_FOLDER)/build/CMakeFiles/CMakeError.log") {
826       Push-AppveyorArtifact "$($Env:APPVEYOR_BUILD_FOLDER)/build/CMakeFiles/CMakeError.log" -DeploymentName "Driver Error Log"
827     }
828   }
829 }
830