Fix Github windows CI (#3887) #2
Workflow file for this run
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: Fast-DDS Windows CI reusable workflow | ||
on: | ||
workflow_call: | ||
inputs: | ||
label: | ||
description: 'ID associated to the workflow. Must univocally identify artifacts.' | ||
required: true | ||
type: string | ||
colcon-args: | ||
description: 'Extra arguments for colcon cli' | ||
required: false | ||
type: string | ||
cmake-args: | ||
description: 'Extra arguments for cmake cli' | ||
required: false | ||
type: string | ||
ctest-args: | ||
description: 'Extra arguments for ctest cli' | ||
required: false | ||
type: string | ||
fastdds_branch: | ||
description: 'Branch or tag of Fast DDS repository (https://github.com/eProsima/Fast-DDS)' | ||
required: true | ||
type: string | ||
defaults: | ||
run: | ||
shell: pwsh | ||
jobs: | ||
reusable-windows-ci: | ||
runs-on: windows-2019 | ||
if: ${{ !contains(github.event.pull_request.labels.*.name, 'skip-ci') }} | ||
strategy: | ||
fail-fast: false | ||
matrix: | ||
cmake-config: | ||
- 'RelWithDebInfo' | ||
vs-toolset: | ||
- 'v141' | ||
- 'v142' | ||
steps: | ||
- name: Sync eProsima/Fast-DDS repository | ||
uses: actions/checkout@v3 | ||
with: | ||
path: src/fastrtps | ||
- name: Get minimum supported version of CMake | ||
uses: lukka/get-cmake@latest | ||
with: | ||
cmakeVersion: '3.16.3' | ||
- name: Patch SDK for source indexing | ||
run: | | ||
# This is a well known issue and the workarond is taken from there | ||
# https://github.com/actions/runner-images/issues/4208 | ||
$kitskey = gi "HKLM:SOFTWARE/Microsoft/Windows Kits/Installed Roots" | ||
$kitspath = $kitskey.GetValue($kitskey.GetValueNames() -match "KitsRoot") | ||
$pdbstr64 = Resolve-Path "$kitspath/*/x64/srcsrv/pdbstr.exe" | ||
$pdbstr86 = Resolve-Path "$kitspath/*/x86/srcsrv/pdbstr.exe" | ||
rm $pdbstr64 | ||
New-Item -ItemType SymbolicLink -Target $pdbstr86 -Path $pdbstr64 | ||
- name: Setup environment | ||
run: | | ||
# Check the cmake version | ||
if( (cmake --version) -join " " -notmatch | ||
"${{ matrix.configs.cmake_minimum_requirement }}".replace(".","\.") ) | ||
{ | ||
Write-Error "Using wrong cmake version" | ||
} | ||
# Introduce EchoArgs to check colcon/cmake calls | ||
$mdir = New-Item -Type Directory -Path (Join-Path ($Env:TMP ?? "/tmp") (New-GUID)) | ||
Save-Module -Name Pscx -Path $mdir -Repository PSGallery | ||
$echo = gci -Path $mdir -R -Filter EchoArgs* | ||
"PATH=$Env:PATH" + [IO.Path]::PathSeparator + ($echo | Split-Path | gi) | ||
| Out-File $Env:GITHUB_ENV -Append -Encoding OEM | ||
# Handle single target/multi target | ||
$env_variables = @() | ||
[xml]$info = & "${Env:ProgramFiles(x86)}\Microsoft Visual Studio\installer\vswhere" ` | ||
-latest -format xml | ||
$pwshmodule = Join-Path $info.instances.instance.installationPath ` | ||
"Common7\Tools\Microsoft.VisualStudio.DevShell.dll" | gi | ||
$env_variables += | ||
'CXXFLAGS=/MP', | ||
'CONFIG_TYPE=--config ${{ matrix.cmake-config }}', | ||
'BIN_ARCH=-A x64', | ||
'HOST_ARCH=-T ${{ matrix.vs-toolset }},host=x64', | ||
('VSPWSH=' + $pwshmodule) | ||
# download the pull request branches on fetch | ||
git config --global remote.origin.fetch '+refs/pull/*:refs/remotes/origin/pull/*' | ||
$env_variables | Out-File $Env:GITHUB_ENV -Append -Encoding OEM | ||
- name: Enable WER | ||
id: WERSetup | ||
run: | | ||
$wer = "HKLM:\SOFTWARE\Microsoft\Windows\Windows Error Reporting" | ||
$ld = Join-Path $wer LocalDumps | ||
$key = Get-Item $wer | ||
if("Disabled" -in $key.Property) { | ||
Set-ItemProperty -Path $wer -Name "Disabled" -Value 0 | ||
} else { | ||
New-ItemProperty -Path $wer -Name "Disabled" -Value 0 -PropertyType DWord | ||
} | ||
if(Test-Path $ld) { $key = Get-Item $ld } else { $key = New-Item -Path $wer -Name "LocalDumps" } | ||
#destination folder | ||
$crashdir = New-Item -Path "CrashDumps" -Type Directory | ||
if("DumpFolder" -in $key.Property) { | ||
Set-ItemProperty -Path $ld -Name "DumpFolder" -Value $crashdir | ||
} else { | ||
New-ItemProperty -Path $ld -Name "DumpFolder" -Value $crashdir -PropertyType ExpandString | ||
} | ||
"DumpFolder=$crashdir" | Out-File $Env:GITHUB_OUTPUT -Append | ||
# up to DumpCount files in the folder | ||
if("DumpCount" -in $key.Property) { | ||
Set-ItemProperty -Path $ld -Name "DumpCount" -Value 100 | ||
} else { | ||
New-ItemProperty -Path $ld -Name "DumpCount" -Value 100 -PropertyType DWord | ||
} | ||
# 2 -> full dump | ||
if("DumpType" -in $key.Property) { | ||
Set-ItemProperty -Path $ld -Name "DumpType" -Value 2 | ||
} else { | ||
New-ItemProperty -Path $ld -Name "DumpType" -Value 2 -PropertyType DWord | ||
} | ||
# WER service is manual by default | ||
Start-Service WerSvc | ||
- name: Install OpenSSL | ||
uses: eProsima/eprosima-CI/windows/install_openssl@v0 | ||
- name: Update OpenSSL environment variables | ||
run: | | ||
# Update the environment | ||
if (Test-Path -Path $Env:ProgramW6432\OpenSSL) | ||
{ | ||
"OPENSSL64_ROOT=$Env:ProgramW6432\OpenSSL" | Out-File $Env:GITHUB_ENV -Append -Encoding OEM | ||
} | ||
elseif (Test-Path -Path $Env:ProgramW6432\OpenSSL-Win) | ||
{ | ||
"OPENSSL64_ROOT=$Env:ProgramW6432\OpenSSL-Win" | Out-File $Env:GITHUB_ENV -Append -Encoding OEM | ||
} | ||
elseif (Test-Path -Path $Env:ProgramW6432\OpenSSL-Win64) | ||
{ | ||
"OPENSSL64_ROOT=$Env:ProgramW6432\OpenSSL-Win64" | Out-File $Env:GITHUB_ENV -Append -Encoding OEM | ||
} | ||
else | ||
{ | ||
Write-Error -Message "Cannot find OpenSSL installation." | ||
exit 1 | ||
} | ||
- name: Install colcon and other python packages | ||
run: | | ||
pip3 install -U colcon-common-extensions vcstool colcon-mixin xmlschema | ||
# patch colcon issue with visual studio 2022 | ||
$patch = gci -Include build.py -Recurse ` | ||
-Path ((gcm colcon).source | Split-Path | Join-Path -ChildPath "..\Lib\site-packages\colcon_cmake\*") | ||
if(!(sls -Path $patch -Pattern "'17.0': 'Visual Studio 17 2022'")) | ||
{ | ||
echo "Patching colcon build to admit Visual Studio 17 2022" | ||
$tmp = New-TemporaryFile | ||
Get-Content $patch | % { | ||
if($_ -match "Visual Studio 16 2019") { | ||
" '17.0': 'Visual Studio 17 2022'," } | ||
$_ | ||
} | Out-File $tmp -Encoding OEM | ||
Install-Module -Name Pscx -Force -AllowClobber | ||
ConvertTo-UnixLineEnding -Destination $patch -Path $tmp.FullName | ||
del $tmp | ||
} | ||
# refresh mixins | ||
colcon mixin add default 'https://raw.githubusercontent.com/colcon/colcon-mixin-repository/master/index.yaml' | ||
colcon mixin update default | ||
colcon mixin show | ||
- name: Install asio and tinyxml2 | ||
run: | | ||
$tmpdir = New-Item -Path "$Env:TMP\choco_aux" -Type Directory | ||
iwr -Uri https://github.com/ros2/choco-packages/releases/download/2020-02-24/asio.1.12.1.nupkg -OutFile "$tmpdir\asio.1.12.1.nupkg" | ||
iwr -Uri https://github.com/ros2/choco-packages/releases/download/2020-02-24/tinyxml2.6.0.0.nupkg -OutFile "$tmpdir\tinyxml2.6.0.0.nupkg" | ||
choco install -y -s $tmpdir asio tinyxml2 | ||
del $tmpdir -Recurse | ||
# Need to be very explicit in path location due to poor choice on ros2 choco-package composition | ||
"CMAKE_PREFIX_PATH=$Env:ProgramData\chocolatey\lib\asio\share\cmake;" + | ||
"$Env:ProgramData\chocolatey\lib\tinyxml2\share\cmake;$Env:CMAKE_PREFIX_PATH" | | ||
Out-File $Env:GITHUB_ENV -Append -Encoding OEM | ||
- name: Install googletest | ||
run: | | ||
git clone --branch release-1.11.0 https://github.com/google/googletest.git | ||
$crt = '-Dgtest_force_shared_crt=ON' | ||
# Show the args | ||
EchoArgs -DBUILD_GMOCK=ON -DCMAKE_BUILD_TYPE=${{ matrix.cmake-config }} $crt -DCMAKE_VERBOSE_MAKEFILE=ON ` | ||
-B ./build/googletest "$Env:BIN_ARCH".split(" ") "$Env:HOST_ARCH".split(" ") ./googletest | ||
# Generate | ||
cmake -DBUILD_GMOCK=ON -DCMAKE_BUILD_TYPE=${{ matrix.cmake-config }} $crt -DCMAKE_VERBOSE_MAKEFILE=ON ` | ||
-B ./build/googletest "$Env:BIN_ARCH".split(" ") "$Env:HOST_ARCH".split(" ") ./googletest | ||
# Build and install elevated if required | ||
$build = { cmake --build ./build/googletest --target install "$Env:CONFIG_TYPE".split(" ") --verbose } | ||
(& $build) | Tee-Object -FilePath gtest.log | ||
# Hint install dir | ||
$pattern = "-- Installing:\s+(?<cmake_path>.*)/GTestConfig.cmake" | ||
$matches = sls -Path gtest.log -Pattern $pattern | ||
$Env:GTest_DIR = ($matches.Matches.Groups | ? name -eq cmake_path).Value | ||
("GTest_DIR=" + $Env:GTest_DIR) | Out-File $Env:GITHUB_ENV -Append -Encoding OEM | ||
# clean up | ||
'build', 'googletest', 'gtest.log' | del -Recurse -Force | ||
<<<<<<< HEAD | ||
- name: Install OpenSSL | ||
uses: eProsima/eprosima-CI/windows/install_openssl@v0 | ||
- name: Update OpenSSL environment variables | ||
run: | | ||
# Update the environment | ||
"OPENSSL64_ROOT=$Env:ProgramW6432\OpenSSL" | Out-File $Env:GITHUB_ENV -Append -Encoding OEM | ||
======= | ||
>>>>>>> 7057142d6 (Fix Github windows CI (#3887)) | ||
- name: Update known hosts file for DNS resolver testing | ||
if: ${{ !contains(github.event.pull_request.labels.*.name, 'no-test') }} | ||
run: | | ||
$hostfile = "$Env:SystemRoot\system32\drivers" -replace "\\", "/" | ||
$hostfile += "/etc/hosts" | ||
# DNS entries to add | ||
$new_entries = @{ | ||
"localhost.test" = "127.0.0.1", "::1" | ||
"www.eprosima.com.test" = "154.56.134.194" | ||
"www.acme.com.test" = "216.58.215.164", "2a00:1450:400e:803::2004" | ||
"www.foo.com.test" = "140.82.121.4", "140.82.121.3" | ||
"acme.org.test" = "ff1e::ffff:efff:1" | ||
} | ||
# Modify the file | ||
$mod = { Param([string]$FilePath, [Hashtable]$Entries ) | ||
$entries.GetEnumerator() | | ||
% { $hostname = $_.key; $_.value | | ||
% { "{0,-25} {1}" -f $_, $hostname }} | | ||
Out-File $filepath -Append | ||
} | ||
& $mod -FilePath $hostfile -Entries $new_entries | ||
# Show the result | ||
gc $hostfile | ||
- name: Set up libp11 and SoftHSM | ||
timeout-minutes: 10 | ||
continue-on-error: true | ||
run: | | ||
if(!(Test-Path -Path Env:OPENSSL64_ROOT)) | ||
{ | ||
Write-Error -Message "OpenSSL is not set up properly. Check previous steps." | ||
} | ||
# Install the HSM emulator (required for testing PKCS #11 support) | ||
$urlHSM = "https://github.com/disig/SoftHSM2-for-Windows/releases/download/v2.5.0/SoftHSM2-2.5.0.msi" | ||
$msiHSM = "$Env:tmp\SoftHSM2-2.5.0.msi" | ||
iwr $urlHSM -OutFile $msiHSM | ||
msiexec /i $msiHSM /log "$Env:tmp\SoftHSM2.log" /quiet TARGETDIR="""${Env:ProgramFiles(x86)}""" | ||
# move to pkcs11 installation while msiexec installs softhsm2 | ||
# Build pkcs11 library | ||
$deploy_dir = "$Env:ProgramFiles/libp11" | ||
git clone https://github.com/OpenSC/libp11.git $deploy_dir | ||
$deploy_dir = gi $deploy_dir | ||
$pwshmodule = gi $Env:VSPWSH | ||
Import-Module $pwshmodule | ||
Enter-VsDevShell -SetDefaultWindowTitle -VsInstallPath $pwshmodule.Directory.Parent.Parent ` | ||
-StartInPath (pwd) -DevCmdArguments '/arch=x64 /host_arch=x64' | ||
cd $deploy_dir | ||
nmake .\Makefile.mak OPENSSL_DIR="$Env:OPENSSL64_ROOT" BUILD_FOR=WIN64 | ||
$config = ls -Path "$Env:OPENSSL64_ROOT" -Recurse -Include openssl.cnf; | ||
$libp11_path = Join-Path $deploy_dir src | ||
# Check softhsm2 installation | ||
if (!(sls -Path "$Env:tmp\SoftHSM2.log" -Pattern "Installation success or error status: 0" -SimpleMatch -Quiet)) | ||
{ | ||
Write-Error -Message "SoftHSM2 installation failed." | ||
} | ||
# lead openssl to the right config file | ||
$Env:OPENSSL_CONF=$config | ||
# Set up environment: introduce openssl and softhsm2 binaries in the path for the lower check | ||
$Env:SOFTHSM2_ROOT = Join-Path "${Env:ProgramFiles(x86)}" SoftHSM2 | ||
$Env:SOFTHSM2_CONF = (gci -Path $Env:SOFTHSM2_ROOT -R -Filter *.conf | select -First 1).fullname | ||
$Env:Path += ($env:Path[-1] -ne ';' ? ';' : $null) + (Join-Path $Env:SOFTHSM2_ROOT bin) | ||
$Env:Path += ";" + (Join-Path $Env:SOFTHSM2_ROOT lib) | ||
$Env:Path += ";" + (Join-Path $Env:OPENSSL64_ROOT bin) | ||
$Env:Path += ";" + $libp11_path | ||
# Set up OpenSSL | ||
$module_path = gci -Path $Env:SOFTHSM2_ROOT -Recurse -Include '*.dll' | ? FullName -match 64 | ||
$contents = gc $config; | ||
$header = "# HSM test ancillary configuration", | ||
"openssl_conf = openssl_init" | ||
$footer = "[openssl_init]", | ||
"engines = engine_section", | ||
"", | ||
"[engine_section]", | ||
"pkcs11 = pkcs11_section", | ||
"", | ||
"[pkcs11_section]", | ||
"engine_id = pkcs11", | ||
("dynamic_path =" + ("$libp11_path/pkcs11.dll" -replace "\\","/")), | ||
("MODULE_PATH =" + ($module_path.FullName -replace "\\","/")), | ||
"init = 0" | ||
$header_line = ($contents | sls '^HOME')[0].LineNumber; | ||
($contents[0..$header_line] + $header + $contents[$header_line..$contents.count] + $footer) | | ||
% { $_.TrimStart() } | Out-File $config -Encoding OEM; | ||
# Check config file | ||
Get-Content $config | ||
# Propagate to the other steps using github actions ad hoc files | ||
('LibP11_ROOT_64=' + $libp11_path ), | ||
('OPENSSL_CONF=' + $Env:OPENSSL_CONF), | ||
('SOFTHSM2_ROOT=' + $Env:SOFTHSM2_ROOT), | ||
('SOFTHSM2_CONF=' + $Env:SOFTHSM2_CONF ) | | ||
Out-File -Path $Env:GITHUB_ENV -Append -Encoding OEM | ||
# keep softhsm2-util working in the testing | ||
(Join-path $Env:SOFTHSM2_ROOT bin), | ||
(Join-path $Env:SOFTHSM2_ROOT lib), | ||
$libp11_path | Out-File -Path $Env:GITHUB_PATH -Encoding OEM -Append | ||
# check if is working | ||
openssl engine pkcs11 -t | ||
softhsm2-util --show-slots | ||
- name: Prepare colcon workspace | ||
run: | | ||
# Get some convenient tools | ||
Install-Module -Name ConvertBase64Strings -Force -AllowClobber | ||
Import-Module -name ConvertBase64Strings -Prefix CI | ||
Install-Module powershell-yaml -Force | ||
# Get action credentials for github REST API | ||
$secret = ConvertTo-SecureString -String "${{ secrets.GITHUB_TOKEN }}" -AsPlainText | ||
# Check available queries according with github policy | ||
"::group::Rate Limits with github action token" | ||
((Invoke-WebRequest -Authentication OAuth -Token $secret ` | ||
-Uri https://api.github.com/users/octocat).Headers.GetEnumerator() | | ||
? Key -like "X-RateLimit*") | Out-Host | ||
"::endgroup::" | ||
# Nightly job | ||
if ("${{ inputs.label }}".Contains("nightly")) | ||
{ | ||
$depends_repos_path = ".\src\fastrtps\.github\workflows\config\nightly_${{ inputs.fastdds_branch }}.repos" | ||
if (!(Test-Path -Path $depends_repos_path)) | ||
{ | ||
$depends_repos_path = ".\src\fastrtps\.github\workflows\config\nightly_master.repos" | ||
} | ||
$meta_path = ".\src\fastrtps\.github\workflows\config\nightly.meta" | ||
} | ||
# Either PR or manual | ||
else | ||
{ | ||
$depends_repos_path = ".\src\fastrtps\.github\workflows\config\default_ci_${{ inputs.fastdds_branch }}.repos" | ||
if (!(Test-Path -Path $depends_repos_path)) | ||
{ | ||
$depends_repos_path = ".\src\fastrtps\.github\workflows\config\default_ci_master.repos" | ||
} | ||
$meta_path = ".\src\fastrtps\.github\workflows\config\default_ci.meta" | ||
} | ||
Write-Output "Selected repos files: $depends_repos_path" | ||
Write-Output "Selected metas files: $meta_path" | ||
# Get the repository's repos file | ||
$repos_path = ".\src\fastrtps\fastrtps.repos" | ||
$repos = Get-Content $repos_path | ConvertFrom-Yaml | ||
# Merge with the extra dependencies .repos file | ||
$depends = Get-Content $depends_repos_path | ConvertFrom-Yaml | ||
$depends.repositories.GetEnumerator() | | ||
% { $repos.repositories[$_.Name] = $_.Value} | ||
# cmake --find-package has issues on unix base system | ||
# let's use a dummy project | ||
$find_gtest = { | ||
$tmpdir = $IsWindows ? "$Env:TMP\" : "/tmp/" | ||
pushd (New-Item -Type Directory -Path "$tmpdir$(New-Guid)") | ||
$cr = "`n" | ||
'cmake_minimum_required(VERSION 3.5)' + $cr + | ||
'project(dummy VERSION 1.0.0 LANGUAGES CXX)' + $cr + | ||
'find_package(GTest CONFIG REQUIRED)' + $cr + | ||
'message(STATUS "GTest_FOUND=>>>>${GTest_FOUND}<<<<<")' | | ||
Out-File CMakeLists.txt | ||
(cmake .) *>&1 | % { | ||
if($_ -Match "GTest_FOUND=>>>>(?<res>.*)<<<<<") { $Matches.res -eq 1 } | ||
}; popd } | ||
# If there is a framework version of googletest use it | ||
if($repos.repositories.Contains("googletest-distribution") -and (& $find_gtest)) | ||
{ | ||
$repos.repositories.Remove("googletest-distribution") | ||
Write-Output "Using framework version of googletest-distribution" | ||
} | ||
"::group::merged vcstool repos file" | ||
$repos | ConvertTo-Yaml | Tee-Object -FilePath fastrtps.repos | ||
"::endgroup::" | ||
# Generate the meta file | ||
"::group::deployed colcon.meta file" | ||
$meta = Get-Content $meta_path | ConvertFrom-Yaml | ||
$meta | ConvertTo-Json -Depth 3 | Tee-Object -FilePath ci.meta -Encoding OEM | ||
"::endgroup::" | ||
# create source dir and download the sources | ||
vcs import src --input fastrtps.repos --skip-existing | ||
- name: Build | ||
id: build | ||
run: | | ||
# build type mixin names doesn't match cmake ones | ||
$translate = @{ | ||
"Debug"="debug" | ||
"Release"="release" | ||
"RelWithDebInfo"="rel-with-deb-info" | ||
"MinSizeRel"="min-size-rel" | ||
} | ||
# For convenience use an array to pass the arguments | ||
$buildargs = "--merge-install", | ||
"--symlink-install", | ||
"--event-handlers=console_direct+", | ||
"--packages-up-to", "fastrtps", | ||
"--mixin", $translate["${{ matrix.cmake-config }}"] | ||
$cmakeargs = '--cmake-args --no-warn-unused-cli ${{ inputs.cmake-args }} ' | ||
# On Windows we must load the developer environment and chose a config | ||
$pwshmodule = gi $Env:VSPWSH | ||
Import-Module $pwshmodule | ||
Enter-VsDevShell -SetDefaultWindowTitle -VsInstallPath $pwshmodule.Directory.Parent.Parent ` | ||
-StartInPath (pwd) -DevCmdArguments '/arch=x64 /host_arch=x64' | ||
$cmakeargs += "$Env:BIN_ARCH $Env:HOST_ARCH" | ||
# Show the args | ||
EchoArgs $buildargs --metas ci.meta --executor sequential ${{ inputs.colcon-args }} $cmakeargs.split(" ") | ||
"::group::cmake summary" | ||
colcon build $buildargs --metas ci.meta --executor sequential ${{ inputs.colcon-args }} $cmakeargs.split(" ") | ||
"::endgroup::" | ||
$output_buffer = "" | ||
$warning_sb = {Write-Warning $args[0]; $global:output_buffer += $args[0]} | ||
$error_sb = {Write-Error $args[0]; $global:output_buffer += $args[0]} | ||
switch($LASTEXITCODE) | ||
{ | ||
0 { $report_kind = "generation or build warnings"; $wm = $warning_sb } | ||
1 { $report_kind = "CMake errors"; $wm = $error_sb } | ||
2 { $report_kind = "build errors"; $wm = $error_sb } | ||
} | ||
# Show only warnings or error reports but do not fail | ||
$LASTEXITCODE=0 | ||
$WarningPreference = $ErrorActionPreference = 'Continue' | ||
$reports = gci -Path ./log/build_* -R -Filter stderr.log | ? { sls -Path $_ -Pattern "error|warning" } | ||
$reports.FullName | ||
if($reports) | ||
{ | ||
$logFolder = New-Item -Type Directory -Path build_logs | ||
$msg = "There were $report_kind in some packages:" | ||
& $wm $msg | ||
(($reports.FullName | sls "log.build_[\d-_]*.(?<package>[^/]*).stderr.log").Matches.Groups | | ||
? name -eq "package").value | % { | ||
$msg += " $_" | ||
& $wm $_ | ||
$file = Resolve-Path "./log/*/$_/stderr.log" | ||
$dest_file = Join-Path -Path $logFolder -ChildPath "$_-stderr.log" | ||
Copy-Item -Path $file -Destination $dest_file | ||
Get-Content $file | ||
} | ||
"BuildWarningsErrors=" + $output_buffer | Out-File $Env:GITHUB_OUTPUT | ||
"BuildLogFolder=" + $logFolder.FullName | Out-File $Env:GITHUB_OUTPUT -Append | ||
} | ||
- name: Test | ||
if: ${{ !contains(github.event.pull_request.labels.*.name, 'no-test') && | ||
( | ||
steps.build.outcome == 'success' && | ||
( | ||
steps.build.outputs.BuildWarningsErrors == 0 || | ||
contains(steps.build.outputs.BuildWarningsErrors, 'warning') | ||
) | ||
) }} | ||
id: test | ||
run: | | ||
# Create a junit file for test results | ||
$junit = New-Item -Path ./junit.xml -ItemType File | ||
'JUNIT_LOG=' + $junit.FullName | Out-File $Env:GITHUB_ENV -Append -Encoding OEM | ||
# add ctest args | ||
$ctestargs = '${{ inputs.ctest-args }}'.split(" ") | ||
# Show the arguments | ||
EchoArgs --packages-select fastrtps --retest-until-pass 3 --event-handlers=console_direct+ ` | ||
--merge-install --executor sequential --ctest-args $ctestargs ` | ||
--timeout 300 --output-junit $junit | ||
# Run the testing | ||
"::group::ctest summary" | ||
colcon test --packages-select fastrtps --retest-until-pass 3 --event-handlers=console_direct+ ` | ||
--merge-install --executor sequential --ctest-args $ctestargs ` | ||
--timeout 300 --output-junit $junit | ||
"::endgroup::" | ||
- name: Create test Summary | ||
id: summary | ||
if: ${{ steps.test.outcome == 'success' }} | ||
run: | | ||
$ErrorActionPreference = 'Continue' | ||
$failed = 0 | ||
# If the CMake version (3.21 et seq.) supports junit use it | ||
if((Test-Path $Env:JUNIT_LOG) -and (gi $Env:JUNIT_LOG).Length ) | ||
{ | ||
# ancillary for markdown summary | ||
$modules = Get-Module -ListAvailable | Select ModuleType, Version, Name | ||
if(!($modules | ? Name -eq "MarkdownPS")) | ||
{ | ||
Install-Module -Name MarkdownPS -Force | ||
} | ||
[xml]$res = gc $Env:JUNIT_LOG | ||
[long]$failed = $res.testsuite.failures | ||
# Summary | ||
$res.testsuite | select name, tests, failures, disabled, hostname, time, timestamp | | ||
New-MDTable | Tee-Object -FilePath $Env:GITHUB_STEP_SUMMARY -Append | ||
if($failed) | ||
{ | ||
# list the failures if any | ||
"::group::Failures Summary" | ||
$failures = $res.testsuite.testcase | ? status -eq fail | ||
$failures | select name, time | format-list | ||
"::endgroup::" | ||
# list faulty tests output | ||
"::group::Failed tests output" | ||
$failures | ||
"::endgroup::" | ||
# populate a log folder with the failures | ||
$logFolder = New-Item -Type Directory -Path test_logs | ||
pushd $logFolder | ||
$failures | % { $_.'system-out' | Set-Content -Path ($_.name + ".txt") } | ||
popd | ||
colcon test-result --verbose | sls "^\- " | Tee-Object -FilePath $Env:GITHUB_STEP_SUMMARY -Append | ||
"TestLogFolder=" + $logFolder.FullName | Out-File $Env:GITHUB_OUTPUT -Append | ||
} | ||
} | ||
else | ||
{ | ||
# Fallback to parse the ordinary output file | ||
# Let's create a summary table | ||
$table = @{} | ||
$logfile = gi ./log/latest_test/fastrtps/stdout.log | ||
# Check total and passed | ||
$pattern = '(?:(?<timestamp>[\d-:T]+)\.\S+ |^)(?:.\[0;32m)?(\d+)% tests passed(?:.\[0;0m)?,' + | ||
' (?:.\[0;31m)?(?<failed>\d+) tests failed(?:.\[0;0m)? out of (?<total>\d+)$' | ||
$summary = (gc $logfile).where({ $_ -match $pattern }, 'Default') | ||
$summary[0] -match $pattern | ||
$table.tests = $matches.total | ||
$summary[-1] -match $pattern | ||
$table.failures = [long]$failed = $matches.failed | ||
# Get hostname | ||
$table.hostname = hostname | ||
# Get timestamp | ||
if($matches.timestamp) { $table.timestamp = $matches.timestamp } else { $table.timestamp = $logfile.LastWriteTime | Get-Date -Format "yyyy-MM-ddThh:mm:ss" } | ||
# Get spent time | ||
$pattern = "Total Test time \(real\) = (?<time>[\d\.]+) sec" | ||
$summary = (gc $logfile).where({ $_ -match $pattern }, 'Default') | ||
$table.time = ($summary.where({ $_ -match $pattern }) | % { $_ -match $pattern; $matches.time } | | ||
Measure-Object -Sum).Sum | ||
# Count disabled tests | ||
$pattern = "\d+ - \S+ \(Disabled\)$" | ||
$table.disabled = (gc $logfile).where({ $_ -match $pattern }, 'Default').Count | ||
# Get generator | ||
$table.generator = (gi ./build/fastrtps/CMakeCache.txt | | ||
sls "CMAKE_GENERATOR:INTERNAL=(?<gen>.*)").Matches.Groups.Where{$_.Name -eq "gen"}.Value | ||
# Print summary | ||
$summary | ||
[PSCustomObject]$table | select generator, tests, failures, disabled, hostname, time, timestamp | | ||
New-MDTable | Tee-Object -FilePath $Env:GITHUB_STEP_SUMMARY -Append | ||
if($failed) | ||
{ | ||
# populate a log folder with the failures | ||
$logFolder = New-Item -Type Directory -Path test_logs | ||
# copy the error reports and command log from colcon logs | ||
copy .\log\latest_test\fastrtps\stdout_stderr.log $logFolder | ||
copy .\log\latest_test\fastrtps\command.log $logFolder | ||
"TestLogFolder=" + $logFolder.FullName | Out-File $Env:GITHUB_OUTPUT -Append | ||
colcon test-result --verbose | sls "^\- " | Tee-Object -FilePath $Env:GITHUB_STEP_SUMMARY -Append | ||
} | ||
} | ||
$dumpfolder = gi (gi "HKLM:\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps").GetValue('DumpFolder') | ||
if(ls -Path $dumpfolder -Filter *.dmp) | ||
{ | ||
# upload: | ||
# 1. the pdb/dll files associated to the library | ||
$libs = gci -Path ./build/* -R -Include "fast*.pdb", "fast*.dll", "fast*.exe" | ||
$libs | Move-Item -Destination $dumpfolder | ||
# 2. The pdb/exe files for each failed test | ||
$test_bin = ((ls -Path $dumpfolder -Filter *.dmp).name | | ||
sls "(?<file>[^\(^\)^\.]+).*\.\d+\.dmp").Matches | | ||
% { $_.Groups['file'].Value } | Get-Unique | ||
$exes = gci -Path ./build/* -R -Include "*.pdb", "*.exe" | ||
$exes | ? basename -in $test_bin | Move-Item -Destination $dumpfolder | ||
# 3. Enable source indexing to reported pdb files | ||
& src/fastrtps/.github/workflows/utils/add_source_listing.ps1 ` | ||
-pdbs (ls $dumpfolder -Filter *.pdb | ? Name -notmatch fastrtps).FullName | ||
"::group::Crash dump files" | ||
gci $dumpfolder | Sort-Object LastWriteTime | ||
"::endgroup::" | ||
} | ||
if($failed) | ||
{ | ||
$msg = "$failed test(s) failed" | ||
"TestErrors=" + $msg | Out-File $Env:GITHUB_OUTPUT -Append | ||
Write-Error $msg; | ||
} | ||
# Avoid disturbing exit code 1 message | ||
$LASTEXITCODE=0 | ||
- name: Upload build warnings and errors | ||
if: ${{ steps.build.outputs.BuildLogFolder != 0 }} | ||
uses: actions/upload-artifact@v3 | ||
with: | ||
name: build-issues-${{ inputs.label }}-windows-2019-${{ matrix.cmake-config }} | ||
path: ${{ steps.build.outputs.BuildLogFolder }} | ||
- name: Upload test errors | ||
if: ${{ steps.summary.outputs.TestLogFolder != 0 }} | ||
uses: actions/upload-artifact@v3 | ||
with: | ||
name: test-errors-${{ inputs.label }}-windows-2019${{ matrix.vs-toolset != 0 && '-' || ''}}${{ matrix.vs-toolset }}-${{ matrix.cmake-config }} | ||
path: ${{ steps.summary.outputs.TestLogFolder }} | ||
- name: Upload crash dumps | ||
if: ${{ steps.summary.outputs.TestErrors != 0 }} | ||
uses: actions/upload-artifact@v3 | ||
with: | ||
name: crash-dumps-${{ inputs.label }}-windows-2019-${{ matrix.vs-toolset }}-${{ matrix.cmake-config }} | ||
path: ${{ steps.WERSetup.outputs.DumpFolder }} | ||
- name: Check test failures | ||
if: ${{ steps.build.outputs.BuildWarningsErrors != 0 || steps.summary.outputs.TestErrors != 0 }} | ||
uses: actions/github-script@v6 | ||
with: | ||
script: | | ||
const warnings = /warning/; | ||
const errors = /error/; | ||
const build_info = '${{ steps.build.outputs.BuildWarningsErrors }}'; | ||
const test_info = '${{ steps.summary.outputs.TestErrors }}'; | ||
if(!!build_info) | ||
{ | ||
// build errors | ||
if(errors.test(build_info)) | ||
{ | ||
core.setFailed(build_info); | ||
} | ||
// build warnings | ||
if(warnings.test(build_info)) | ||
{ | ||
core.warning(build_info); | ||
} | ||
} | ||
// test errors | ||
if (!!test_info) | ||
{ | ||
core.setFailed(test_info); | ||
} |