Skip to content

Improvement of maintainability #2975

Improvement of maintainability

Improvement of maintainability #2975

Workflow file for this run

name: CMake Build Matrix
on:
push:
branches: [ master ]
schedule:
- cron: '0 9 * * 1'
workflow_dispatch:
pull_request_target:
branches: [ master ]
types: [ labeled ]
merge_group:
types: [ checks_requested ]
env:
NINJA_VERSION: 1.10.1
BUILD_TYPE: Release
CCACHE_VERSION: 4.2.1
jobs:
build:
name: ${{ matrix.config.name }}
runs-on: ${{ matrix.config.os }}
if: ${{ (github.repository == 'savushkin-r-d/ptusa_main') && ( (github.event_name == 'push') || (github.event_name == 'schedule') || (github.event_name == 'merge_group') || ((github.event_name == 'pull_request_target') && (contains( github.event.pull_request.labels.*.name, 'safe to test' )))) }}
strategy:
fail-fast: false
matrix:
config:
- {
name: "Windows Latest MSVC",
artifact: "Windows-MSVC.7z",
os: windows-latest,
cc: "cl",
cxx: "cl",
environment_script: "C:/Program Files/Microsoft Visual Studio/2022/Enterprise/VC/Auxiliary/Build/vcvars32.bat",
targets: "ptusa_main libptusa_main main_test main_perfomance_test",
run_tests: "true"
}
- {
name: "Windows Latest MinGW",
artifact: "Windows-MinGW.7z",
os: windows-latest,
cc: "gcc",
cxx: "g++",
targets: "ptusa_main libptusa_main",
run_tests: "false"
}
- {
name: "Ubuntu Latest GCC",
artifact: "Linux.7z",
os: ubuntu-latest,
cc: "gcc",
cxx: "g++",
targets: "ptusa_main libptusa_main main_test main_perfomance_test",
run_tests: "true"
}
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha }}
# Whether to checkout submodules: `true` to checkout submodules or `recursive` to
# recursively checkout submodules.
#
# When the `ssh-key` input is not provided, SSH URLs beginning with
# `[email protected]:` are converted to HTTPS.
#
# Default: false
submodules: 'recursive'
- name: Download Ninja and CMake
shell: cmake -P {0}
run: |
set(cmake_version ${CMAKE_VERSION})
set(ninja_version $ENV{NINJA_VERSION})
message(STATUS "Using host CMake version: ${CMAKE_VERSION}")
if ("${{ runner.os }}" STREQUAL "Windows")
set(ninja_suffix "win.zip")
set(cmake_dir "cmake-${cmake_version}-win64-x64/bin")
elseif ("${{ runner.os }}" STREQUAL "Linux")
set(ninja_suffix "linux.zip")
set(cmake_dir "cmake-${cmake_version}-Linux-x86_64/bin")
elseif ("${{ runner.os }}" STREQUAL "macOS")
set(ninja_suffix "mac.zip")
set(cmake_dir "cmake-${cmake_version}-Darwin-x86_64/CMake.app/Contents/bin")
endif()
set(ninja_url "https://github.com/ninja-build/ninja/releases/download/v${ninja_version}/ninja-${ninja_suffix}")
file(DOWNLOAD "${ninja_url}" ./ninja.zip SHOW_PROGRESS)
execute_process(COMMAND ${CMAKE_COMMAND} -E tar xvf ./ninja.zip)
# Add to PATH environment variable
file(TO_CMAKE_PATH "$ENV{GITHUB_WORKSPACE}/${cmake_dir}" cmake_dir)
set(path_separator ":")
if ("${{ runner.os }}" STREQUAL "Windows")
set(path_separator ";")
endif()
file(APPEND "$ENV{GITHUB_PATH}" "$ENV{GITHUB_WORKSPACE}${path_separator}${cmake_dir}")
if (NOT "${{ runner.os }}" STREQUAL "Windows")
execute_process(
COMMAND chmod +x ninja
)
endif()
- name: Download ccache
id: ccache
shell: cmake -P {0}
run: |
set(ccache_url "https://github.com/cristianadam/ccache/releases/download/v$ENV{CCACHE_VERSION}/${{ runner.os }}.tar.xz")
file(DOWNLOAD "${ccache_url}" ./ccache.tar.xz SHOW_PROGRESS)
execute_process(COMMAND ${CMAKE_COMMAND} -E tar xvf ./ccache.tar.xz)
- name: Prepare ccache timestamp
id: ccache_cache_timestamp
shell: cmake -P {0}
run: |
string(TIMESTAMP current_date "%Y-%m-%d-%H;%M;%S" UTC)
file(APPEND "$ENV{GITHUB_OUTPUT}" "timestamp=${current_date}\n")
- name: ccache cache files
uses: actions/cache@v4
with:
path: .ccache
key: ${{ matrix.config.name }}-ccache-${{ steps.ccache_cache_timestamp.outputs.timestamp }}
restore-keys: |
${{ matrix.config.name }}-ccache-
- name: Install yasm
shell: cmake -P {0}
run: |
if ("${{ runner.os }}" STREQUAL "Windows")
set(yasm_url "https://www.tortall.net/projects/yasm/releases/yasm-1.2.0-win64.exe")
set(yasm_install_path "C:/Program Files/yasm")
file(DOWNLOAD "${yasm_url}" "${yasm_install_path}/yasm.exe" SHOW_PROGRESS)
# Add to PATH environment variable
file(APPEND "$ENV{GITHUB_PATH}" ";${yasm_install_path}")
elseif ("${{ runner.os }}" STREQUAL "Linux")
execute_process(COMMAND sudo apt-get install -y yasm)
endif()
- name: Configure
shell: cmake -P {0}
run: |
set(ENV{CC} ${{ matrix.config.cc }})
set(ENV{CXX} ${{ matrix.config.cxx }})
if ("${{ runner.os }}" STREQUAL "Windows" AND NOT "x${{ matrix.config.environment_script }}" STREQUAL "x")
execute_process(
COMMAND "${{ matrix.config.environment_script }}" && set
OUTPUT_FILE environment_script_output.txt
)
file(STRINGS environment_script_output.txt output_lines)
foreach(line IN LISTS output_lines)
if (line MATCHES "^([a-zA-Z0-9_-]+)=(.*)$")
set(ENV{${CMAKE_MATCH_1}} "${CMAKE_MATCH_2}")
endif()
endforeach()
endif()
set(path_separator ":")
if ("${{ runner.os }}" STREQUAL "Windows")
set(path_separator ";")
endif()
set(ENV{PATH} "$ENV{GITHUB_WORKSPACE}${path_separator}$ENV{PATH}")
if ("${{ runner.os }}" STREQUAL "Linux")
set(ENV{CODE_COVERAGE} "ON")
endif()
execute_process(
COMMAND cmake
-S .
-B build
-D CMAKE_BUILD_TYPE=$ENV{BUILD_TYPE}
-G Ninja
-D CMAKE_MAKE_PROGRAM=ninja
-D CMAKE_C_COMPILER_LAUNCHER=ccache
-D CMAKE_CXX_COMPILER_LAUNCHER=ccache
-D CODE_COVERAGE=$ENV{CODE_COVERAGE}
RESULT_VARIABLE result
)
if (NOT result EQUAL 0)
message(FATAL_ERROR "Bad exit status")
endif()
- name: Build
shell: cmake -P {0}
run: |
set(ENV{NINJA_STATUS} "[%f/%t %o/sec] ")
if ("${{ runner.os }}" STREQUAL "Windows" AND NOT "x${{ matrix.config.environment_script }}" STREQUAL "x")
file(STRINGS environment_script_output.txt output_lines)
foreach(line IN LISTS output_lines)
if (line MATCHES "^([a-zA-Z0-9_-]+)=(.*)$")
set(ENV{${CMAKE_MATCH_1}} "${CMAKE_MATCH_2}")
endif()
endforeach()
endif()
file(TO_CMAKE_PATH "$ENV{GITHUB_WORKSPACE}" ccache_basedir)
set(ENV{CCACHE_BASEDIR} "${ccache_basedir}")
set(ENV{CCACHE_DIR} "${ccache_basedir}/.ccache")
set(ENV{CCACHE_COMPRESS} "true")
set(ENV{CCACHE_COMPRESSLEVEL} "6")
set(ENV{CCACHE_MAXSIZE} "400M")
if ("${{ matrix.config.cxx }}" STREQUAL "cl")
set(ENV{CCACHE_MAXSIZE} "600M")
endif()
execute_process(COMMAND ccache -p)
execute_process(COMMAND ccache -z)
execute_process(
COMMAND cmake --build build --target ${{ matrix.config.targets }}
RESULT_VARIABLE result
OUTPUT_VARIABLE output
ERROR_VARIABLE output
ECHO_OUTPUT_VARIABLE ECHO_ERROR_VARIABLE
)
if (NOT result EQUAL 0)
string(REGEX MATCH "FAILED:.*$" error_message "${output}")
string(REPLACE "\n" "%0A" error_message "${error_message}")
message("::error::${error_message}")
message(FATAL_ERROR "Build failed")
endif()
execute_process(COMMAND ccache -s)
# Install Lua
- name: Install Lua (Linux only)
if: runner.os == 'Linux'
shell: bash
run: |
sudo apt-get install -y lua5.1
# Install LuaRocks
- name: Install LuaRocks on Linux
if: runner.os == 'Linux'
shell: bash
run: sudo apt-get install -y luarocks
- name: Install LuaRocks on Windows
if: runner.os == 'Windows'
shell: cmd
run: |
choco install luarocks
# Install busted
- name: Install busted on Linux
if: runner.os == 'Linux'
shell: bash
run: sudo luarocks install busted
- name: Install busted on Windows
if: runner.os == 'Windows'
shell: cmd
run: |
call "C:/Program Files/Microsoft Visual Studio/2022/Enterprise/VC/Auxiliary/Build/vcvars32.bat"
luarocks install penlight 1.13.1-1
luarocks install busted
- name: Run tests
if: matrix.config.run_tests == 'true'
shell: cmake -P {0}
run: |
include(ProcessorCount)
ProcessorCount(N)
set(ENV{CTEST_OUTPUT_ON_FAILURE} "ON")
if ("${{ runner.os }}" STREQUAL "Windows")
execute_process(COMMAND luarocks path --lr-path
RESULT_VARIABLE result_path
OUTPUT_VARIABLE output_path
OUTPUT_STRIP_TRAILING_WHITESPACE
)
execute_process(COMMAND luarocks path --lr-cpath
RESULT_VARIABLE result_cpath
OUTPUT_VARIABLE output_cpath
OUTPUT_STRIP_TRAILING_WHITESPACE
)
if (result_path EQUAL 0 AND result_cpath EQUAL 0)
set(ENV{LUA_PATH} "${output_path}")
set(ENV{LUA_CPATH} "${output_cpath}")
endif()
message("LUA_PATH=\"$ENV{LUA_PATH}\"")
message("LUA_CPATH=\"$ENV{LUA_CPATH}\"")
endif()
execute_process(
COMMAND ctest -j ${N}
WORKING_DIRECTORY build
RESULT_VARIABLE result
OUTPUT_VARIABLE output
ERROR_VARIABLE output
ECHO_OUTPUT_VARIABLE ECHO_ERROR_VARIABLE
)
if (NOT result EQUAL 0)
string(REGEX MATCH "[0-9]+% tests.*[0-9.]+ sec.*$" test_results "${output}")
string(REPLACE "\n" "%0A" test_results "${test_results}")
message("::error::${test_results}")
message(FATAL_ERROR "Running tests failed!")
endif()
- name: Install lcov (Linux only)
if: runner.os == 'Linux'
shell: bash
run: sudo apt-get install -y lcov
- name: Create lcov report (Linux only)
if: runner.os == 'Linux'
shell: bash
run: |
lcov --capture --directory . --output-file coverage.info
lcov --remove coverage.info '/usr/*' --remove coverage.info '*/test/*' --remove coverage.info '*/googletest/*' --output-file coverage.info # filter system-files
lcov --list coverage.info # debug info
- name: Upload coverage to Codecov (Linux only)
if: runner.os == 'Linux'
uses: codecov/codecov-action@v4
with:
fail_ci_if_error: true
verbose: true
token: ${{ secrets.CODECOV_TOKEN }}
- name: Store benchmark result (Linux only)
if: runner.os == 'Linux'
uses: benchmark-action/github-action-benchmark@v1
with:
name: C++ Benchmark
tool: 'googlecpp'
output-file-path: ./build/benchmark_result.json
gh-repository: github.com/savushkin-r-d/benchmark-ptusa-main
gh-pages-branch: main
benchmark-data-dir-path: docs/dev/bench
github-token: ${{ secrets.BENCHMARK_PTUSA_MAIN_TOKEN }}
auto-push: true
# Show alert with commit comment on detecting possible performance regression
alert-threshold: '155%'
comment-on-alert: true
fail-on-alert: false
alert-comment-cc-users: '@idzm'
- name: Install Strip
run: cmake --install build --prefix instdir --strip
- name: Pack
working-directory: instdir
run: cmake -E tar cfv ../${{ matrix.config.artifact }} --format=7zip .
- name: Upload
uses: actions/upload-artifact@v4
with:
path: ./${{ matrix.config.artifact }}
name: ${{ matrix.config.artifact }}
release:
if: contains(github.ref, 'tags/v')
runs-on: ubuntu-latest
needs: build
steps:
- name: Create Release
id: create_release
uses: actions/[email protected]
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ github.ref }}
release_name: Release ${{ github.ref }}
draft: false
prerelease: false
- name: Store Release url
run: |
echo "${{ steps.create_release.outputs.upload_url }}" > ./upload_url
- uses: actions/upload-artifact@v4
with:
path: ./upload_url
name: upload_url
publish:
if: contains(github.ref, 'tags/v')
name: ${{ matrix.config.name }}
runs-on: ${{ matrix.config.os }}
strategy:
fail-fast: false
matrix:
config:
- {
name: "Windows Latest MSVC",
artifact: "Windows-MSVC.7z",
os: ubuntu-latest
}
- {
name: "Windows Latest MinGW",
artifact: "Windows-MinGW.7z",
os: ubuntu-latest
}
- {
name: "Ubuntu Latest GCC",
artifact: "Linux.7z",
os: ubuntu-latest
}
needs: release
steps:
- name: Download artifact
uses: actions/download-artifact@v4
with:
name: ${{ matrix.config.artifact }}
path: ./
- name: Download URL
uses: actions/download-artifact@v4
with:
name: upload_url
path: ./
- id: set_upload_url
run: |
upload_url=`cat ./upload_url`
echo "upload_url=$upload_url" >> $GITHUB_OUTPUT
- name: Upload to Release
id: upload_to_release
uses: actions/[email protected]
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.set_upload_url.outputs.upload_url }}
asset_path: ./${{ matrix.config.artifact }}
asset_name: ${{ matrix.config.artifact }}
asset_content_type: application/x-gtar