name: C/C++ CI on: push: branches: [master] paths-ignore: - '**.md' pull_request: types: [opened, reopened, synchronize] release: types: [published] workflow_dispatch: jobs: windows: name: 'Windows' runs-on: windows-2019 env: solution: 'msvc/ReHLDS.sln' buildPlatform: 'Win32' buildRelease: 'Release' buildReleasePlay: 'Release Play' buildTest: 'Test Fixes' steps: - name: Checkout uses: actions/checkout@v4 with: fetch-depth: 0 - name: Setup MSBuild uses: microsoft/setup-msbuild@v2 - name: Build and Run unittests run: | msbuild ${{ env.solution }} -p:Configuration="${{ env.buildTest }}" /t:Clean,Build /p:Platform=${{ env.buildPlatform }} /p:PlatformToolset=v140_xp /p:XPDeprecationWarning=false .\"msvc\Test Fixes\swds.exe" If ($LASTEXITCODE -ne 0 -And $LASTEXITCODE -ne 3) {[Environment]::Exit(1)} shell: "pwsh" - name: Build run: | msbuild ${{ env.solution }} -p:Configuration="${{ env.buildRelease }}" /t:Clean,Build /p:Platform=${{ env.buildPlatform }} /p:PlatformToolset=v140_xp /p:XPDeprecationWarning=false msbuild ${{ env.solution }} -p:Configuration="${{ env.buildReleasePlay }}" /t:Clean,Build /p:Platform=${{ env.buildPlatform }} /p:PlatformToolset=v140_xp /p:XPDeprecationWarning=false - name: Get rcedit from chocolatey run: | choco install rcedit -y shell: "pwsh" - name: Move files run: | mkdir publish\debug mkdir publish\tests mkdir publish\bin\win32\valve\dlls move "msvc\${{ env.buildReleasePlay }}\swds.dll" publish\tests\swds.dll move msvc\${{ env.buildRelease }}\hlds.exe publish\bin\win32\hlds.exe move msvc\${{ env.buildRelease }}\hltv.exe publish\bin\win32\hltv.exe move msvc\${{ env.buildRelease }}\swds.dll publish\bin\win32\swds.dll move msvc\${{ env.buildRelease }}\core.dll publish\bin\win32\core.dll move msvc\${{ env.buildRelease }}\proxy.dll publish\bin\win32\proxy.dll move msvc\${{ env.buildRelease }}\demoplayer.dll publish\bin\win32\demoplayer.dll move msvc\${{ env.buildRelease }}\filesystem_stdio.dll publish\bin\win32\filesystem_stdio.dll move msvc\${{ env.buildRelease }}\director.dll publish\bin\win32\valve\dlls\director.dll move msvc\${{ env.buildRelease }}\hlds.pdb publish\debug\hlds.pdb move msvc\${{ env.buildRelease }}\hltv.pdb publish\debug\hltv.pdb move msvc\${{ env.buildRelease }}\swds.pdb publish\debug\swds.pdb move msvc\${{ env.buildRelease }}\core.pdb publish\debug\core.pdb move msvc\${{ env.buildRelease }}\proxy.pdb publish\debug\proxy.pdb move msvc\${{ env.buildRelease }}\demoplayer.pdb publish\debug\demoplayer.pdb move msvc\${{ env.buildRelease }}\filesystem_stdio.pdb publish\debug\filesystem_stdio.pdb move msvc\${{ env.buildRelease }}\director.pdb publish\debug\director.pdb # TODO: Set version to exe dynamicly: 0.0.0.0 to normal version such as at linux - name: Edit resources at windows binaries run: | rcedit ${{ github.workspace }}\publish\bin\win32\hlds.exe --set-version-string ProductName "ReHLDS" --set-file-version "0.0.0.0" --set-product-version "0.0.0.0" --set-version-string FileDescription "The Half-Life Dedicated Server, Commit: $env:GITHUB_SHA" --set-version-string "Comments" "Commit: $env:GITHUB_SHA" --set-version-string CompanyName "ReHLDS Dev Team" --set-version-string LegalCopyright "Copyright 2025 Valve, ReHLDS DevTeam" rcedit ${{ github.workspace }}\publish\bin\win32\hltv.exe --set-version-string ProductName "ReHLTV" --set-file-version "0.0.0.0" --set-product-version "0.0.0.0" --set-version-string FileDescription "The Half-Life TV, Commit: $env:GITHUB_SHA" --set-version-string "Comments" "Commit: $env:GITHUB_SHA" --set-version-string CompanyName "ReHLDS Dev Team" --set-version-string LegalCopyright "Copyright 2025 Valve, ReHLDS DevTeam" rcedit ${{ github.workspace }}\publish\tests\swds.dll --set-version-string ProductName "swds.dll" --set-file-version "0.0.0.0" --set-product-version "0.0.0.0" --set-version-string FileDescription "A dll used by Steamworks Dedicated Servers, Commit: $env:GITHUB_SHA" --set-version-string "Comments" "Commit: $env:GITHUB_SHA" --set-version-string CompanyName "ReHLDS Dev Team" --set-version-string LegalCopyright "Copyright 2025 Valve, ReHLDS DevTeam" --set-icon rehlds/dedicated/msvc/icon.ico rcedit ${{ github.workspace }}\publish\bin\win32\swds.dll --set-version-string ProductName "swds.dll" --set-file-version "0.0.0.0" --set-product-version "0.0.0.0" --set-version-string FileDescription "A ddll used by Steamworks Dedicated Servers, Commit: $env:GITHUB_SHA" --set-version-string "Comments" "Commit: $env:GITHUB_SHA" --set-version-string CompanyName "ReHLDS Dev Team" --set-version-string LegalCopyright "Copyright 2025 Valve, ReHLDS DevTeam" --set-icon rehlds/dedicated/msvc/icon.ico rcedit ${{ github.workspace }}\publish\bin\win32\core.dll --set-version-string ProductName "core.dll" --set-file-version "0.0.0.0" --set-product-version "0.0.0.0" --set-version-string FileDescription " A dll, it is a core of game engine, Commit: $env:GITHUB_SHA" --set-version-string "Comments" "Commit: $env:GITHUB_SHA" --set-version-string CompanyName "ReHLDS Dev Team" --set-version-string LegalCopyright "Copyright 2025 Valve, ReHLDS DevTeam" --set-icon rehlds/dedicated/msvc/icon.ico rcedit ${{ github.workspace }}\publish\bin\win32\proxy.dll --set-version-string ProductName "proxy.dll" --set-file-version "0.0.0.0" --set-product-version "0.0.0.0" --set-version-string FileDescription "A dll for proxying network connections, Commit: $env:GITHUB_SHA" --set-version-string "Comments" "Commit: $env:GITHUB_SHA" --set-version-string CompanyName "ReHLDS Dev Team" --set-version-string LegalCopyright "Copyright 2025 Valve, ReHLDS DevTeam" --set-icon rehlds/dedicated/msvc/icon.ico rcedit ${{ github.workspace }}\publish\bin\win32\demoplayer.dll --set-version-string ProductName "demoplayer.dll" --set-file-version "0.0.0.0" --set-product-version "0.0.0.0" --set-version-string FileDescription "A dll for demoplayer functionality, Commit: $env:GITHUB_SHA" --set-version-string "Comments" "Commit: $env:GITHUB_SHA" --set-version-string CompanyName "ReHLDS Dev Team" --set-version-string LegalCopyright "Copyright 2025 Valve, ReHLDS DevTeam" --set-icon rehlds/dedicated/msvc/icon.ico rcedit ${{ github.workspace }}\publish\bin\win32\filesystem_stdio.dll --set-version-string ProductName "filesystem_stdio.dll" --set-file-version "0.0.0.0" --set-product-version "0.0.0.0" --set-version-string FileDescription "A dll that manages file input/output operations, Commit: $env:GITHUB_SHA" --set-version-string "Comments" "Commit: $env:GITHUB_SHA" --set-version-string CompanyName "ReHLDS Dev Team" --set-version-string LegalCopyright "Copyright 2025 Valve, ReHLDS DevTeam" --set-icon rehlds/dedicated/msvc/icon.ico rcedit ${{ github.workspace }}\publish\bin\win32\valve\dlls\director.dll --set-version-string ProductName "director.dll" --set-file-version "0.0.0.0" --set-product-version "0.0.0.0" --set-version-string FileDescription "A dll used for Director functionality in Half-Life 1, Commit: $env:GITHUB_SHA" --set-version-string "Comments" "Commit: $env:GITHUB_SHA" --set-version-string CompanyName "ReHLDS Dev Team" --set-version-string LegalCopyright "Copyright 2025 Valve, ReHLDS DevTeam" --set-icon rehlds/dedicated/msvc/icon.ico shell: "pwsh" - name: Import PFX and sign env: KEY_PFX_PASS: ${{ secrets.KEY_PFX_PASS}} run: | $pfxBase64 = "${{ secrets.KEY_PFX_B64 }}" [IO.File]::WriteAllBytes("${{ github.workspace }}\signing-cert.pfx", [Convert]::FromBase64String($pfxBase64)) certutil -f -p "${{ secrets.KEY_PFX_PASS }}" -importPFX "${{ github.workspace }}\signing-cert.pfx" & 'C:\Program Files (x86)\Windows Kits\10\bin\10.0.22621.0\x86\signtool.exe' sign /a /f "${{ github.workspace }}\signing-cert.pfx" /p $env:KEY_PFX_PASS /d "ReHLDS" /du "https://rehlds.dev/" /tr "http://timestamp.digicert.com" /td sha512 /fd sha512 /v ${{ github.workspace }}\publish\bin\win32\hlds.exe & 'C:\Program Files (x86)\Windows Kits\10\bin\10.0.22621.0\x86\signtool.exe' sign /a /f "${{ github.workspace }}\signing-cert.pfx" /p $env:KEY_PFX_PASS /d "reHLTV" /du "https://rehlds.dev/" /tr "http://timestamp.digicert.com" /td sha512 /fd sha512 /v ${{ github.workspace }}\publish\bin\win32\hltv.exe & 'C:\Program Files (x86)\Windows Kits\10\bin\10.0.22621.0\x86\signtool.exe' sign /a /f "${{ github.workspace }}\signing-cert.pfx" /p $env:KEY_PFX_PASS /d "ReHLDS - swds.dll" /du "https://rehlds.dev/" /tr "http://timestamp.digicert.com" /td sha512 /fd sha512 /v ${{ github.workspace }}\publish\tests\swds.dll & 'C:\Program Files (x86)\Windows Kits\10\bin\10.0.22621.0\x86\signtool.exe' sign /a /f "${{ github.workspace }}\signing-cert.pfx" /p $env:KEY_PFX_PASS /d "ReHLDS - swds.dll" /du "https://rehlds.dev/" /tr "http://timestamp.digicert.com" /td sha512 /fd sha512 /v ${{ github.workspace }}\publish\bin\win32\swds.dll & 'C:\Program Files (x86)\Windows Kits\10\bin\10.0.22621.0\x86\signtool.exe' sign /a /f "${{ github.workspace }}\signing-cert.pfx" /p $env:KEY_PFX_PASS /d "ReHLDS - core.dll" /du "https://rehlds.dev/" /tr "http://timestamp.digicert.com" /td sha512 /fd sha512 /v ${{ github.workspace }}\publish\bin\win32\core.dll & 'C:\Program Files (x86)\Windows Kits\10\bin\10.0.22621.0\x86\signtool.exe' sign /a /f "${{ github.workspace }}\signing-cert.pfx" /p $env:KEY_PFX_PASS /d "ReHLDS - proxy.dll" /du "https://rehlds.dev/" /tr "http://timestamp.digicert.com" /td sha512 /fd sha512 /v ${{ github.workspace }}\publish\bin\win32\proxy.dll & 'C:\Program Files (x86)\Windows Kits\10\bin\10.0.22621.0\x86\signtool.exe' sign /a /f "${{ github.workspace }}\signing-cert.pfx" /p $env:KEY_PFX_PASS /d "ReHLDS - demoplayer.dll" /du "https://rehlds.dev/" /tr "http://timestamp.digicert.com" /td sha512 /fd sha512 /v ${{ github.workspace }}\publish\bin\win32\demoplayer.dll & 'C:\Program Files (x86)\Windows Kits\10\bin\10.0.22621.0\x86\signtool.exe' sign /a /f "${{ github.workspace }}\signing-cert.pfx" /p $env:KEY_PFX_PASS /d "ReHLDS - filesystem_stdio.dll" /du "https://rehlds.dev/" /tr "http://timestamp.digicert.com" /td sha512 /fd sha512 /v ${{ github.workspace }}\publish\bin\win32\filesystem_stdio.dll & 'C:\Program Files (x86)\Windows Kits\10\bin\10.0.22621.0\x86\signtool.exe' sign /a /f "${{ github.workspace }}\signing-cert.pfx" /p $env:KEY_PFX_PASS /d "ReHLDS - director.dll" /du "https://rehlds.dev/" /tr "http://timestamp.digicert.com" /td sha512 /fd sha512 /v ${{ github.workspace }}\publish\bin\win32\valve\dlls\director.dll Remove-Item -Recurse -Force "${{ github.workspace }}\signing-cert.pfx" shell: "pwsh" - name: Deploy artifacts uses: actions/upload-artifact@v4 with: name: win32 path: publish/* testdemos: name: 'Test demos' runs-on: ubuntu-24.04 container: rehldsorg/testdemos:latest needs: [windows] defaults: run: shell: bash working-directory: /opt/HLDS strategy: fail-fast: false matrix: test: [ { file: 'cstrike-muliplayer-1', desc: 'CS: Multiplayer' }, { file: 'rehlds-phys-single1', desc: 'Half-Life: Physics singleplayer' }, { file: 'crossfire-1-multiplayer-1', desc: 'Half-Life: Multiplayer on crossfire map' }, { file: 'shooting-hl-1', desc: 'Half-Life: Shooting with several weapons' }, ] steps: - name: Deploying windows artifacts uses: actions/download-artifact@v4 with: name: win32 - name: Setup dependencies run: | chown root ~ rsync -a deps/rehlds/* . mv $GITHUB_WORKSPACE/tests/swds.dll . - name: Play test env: demo: ${{ matrix.test.file }} desc: ${{ matrix.test.desc }} run: ./runTest.sh linux: name: 'Linux' runs-on: ubuntu-24.04 container: debian:11-slim steps: - name: Checkout uses: actions/checkout@v4 with: fetch-depth: 0 - name: Install dependencies run: | dpkg --add-architecture i386 apt-get update apt-get install -y \ gcc-multilib g++-multilib \ build-essential \ libc6-dev libc6-dev-i386 \ git cmake rsync \ g++ gcc - name: GPG Import run: | echo "${{ secrets.PUB_ASC }}" > "${{ secrets.PUB_ASC_FILE }}" echo "${{ secrets.KEY_ASC }}" > "${{ secrets.KEY_ASC_FILE }}" # Import the public key gpg --batch --yes --import "${{ secrets.PUB_ASC_FILE }}" if [[ $? -ne 0 ]]; then echo "Error: Failed to import the public key" exit 1 fi # Import the private key gpg --batch --yes --import "${{ secrets.KEY_ASC_FILE }}" if [[ $? -ne 0 ]]; then echo "Error: Failed to import the private key" exit 2 fi # Extract the fingerprint of the imported public key GPG_LINUX_FINGERPRINT=$(gpg --list-keys --with-colons | grep '^fpr' | head -n 1 | cut -d: -f10) # Check if the fingerprint was extracted if [[ -z "$GPG_LINUX_FINGERPRINT" ]]; then echo "Error: Failed to extract the fingerprint of the key" exit 3 fi # Set the trust level for the key echo "$GPG_LINUX_FINGERPRINT:6:" | gpg --batch --import-ownertrust if [ $? -ne 0 ]; then echo "Error: Failed to set trust for the key $GPG_LINUX_FINGERPRINT" exit 4 fi echo "Key $GPG_LINUX_FINGERPRINT successfully imported and trusted" gpg --list-keys #export for global use echo "GPG_LINUX_FINGERPRINT=$GPG_LINUX_FINGERPRINT" >> $GITHUB_ENV shell: bash - name: Build and Run unittests run: | rm -rf build && cmake -DCMAKE_BUILD_TYPE=Unittests -B build && cmake --build build -j8 retVal=0 export LD_LIBRARY_PATH="rehlds/lib/linux32:$LD_LIBRARY_PATH" ./build/rehlds/engine_i486 2> /dev/null > result.log || retVal=$? while read line; do if [[ ${line} == *"Warning in test"* ]] ; then echo -e "\e[2;38m$line" elif [[ ${line} == *"Failure in test"* ]] ; then echo -e "\e[1;31m$line" else echo -e "\e[0;33m$line" fi done <<< $(cat result.log) if [ $retVal -ne 0 ] && [ $retVal -ne 3 ]; then echo -e "\e[30;41mExit code: $retVal\e[0m" exit 1 # Unittest failed else echo -e "\e[30;43mExit code: $retVal\e[0m" fi shell: bash - name: Build using GCC Compiler run: | rm -rf build && cmake -B build && cmake --build build -j8 - name: Prepare HLSDK run: | mkdir -p publish/hlsdk rsync -a rehlds/common/ publish/hlsdk/common/ rsync -a rehlds/dlls/ publish/hlsdk/dlls/ rsync -a rehlds/pm_shared/ publish/hlsdk/pm_shared/ rsync -a rehlds/public/ publish/hlsdk/public/ --exclude rehlds/ rsync -a rehlds/public/rehlds/ publish/hlsdk/engine - name: Move files run: | mkdir -p publish/bin/linux32/valve/dlls mv build/rehlds/engine_i486.so publish/bin/linux32/engine_i486.so mv rehlds/version/appversion.h publish/appversion.h mv build/rehlds/dedicated/hlds_linux publish/bin/linux32/hlds_linux mv build/rehlds/HLTV/Console/hltv publish/bin/linux32/hltv mv build/rehlds/HLTV/Core/core.so publish/bin/linux32/core.so mv build/rehlds/HLTV/Proxy/proxy.so publish/bin/linux32/proxy.so mv build/rehlds/HLTV/DemoPlayer/demoplayer.so publish/bin/linux32/demoplayer.so mv build/rehlds/HLTV/Director/director.so publish/bin/linux32/valve/dlls/director.so mv build/rehlds/filesystem/FileSystem_Stdio/filesystem_stdio.so publish/bin/linux32/filesystem_stdio.so - name: Run GLIBC/ABI version compat test run: | binaries=( "publish/bin/linux32/engine_i486.so" "publish/bin/linux32/hlds_linux" "publish/bin/linux32/hltv" "publish/bin/linux32/core.so" "publish/bin/linux32/proxy.so" "publish/bin/linux32/demoplayer.so" "publish/bin/linux32/valve/dlls/director.so" "publish/bin/linux32/filesystem_stdio.so" ) bash ./rehlds/version/glibc_test.sh ${binaries[@]} if [[ $? -ne 0 ]]; then exit 1 # Assertion failed fi shell: bash - name: Deploy artifacts uses: actions/upload-artifact@v4 id: upload-job with: name: linux32 path: publish/* publish: name: 'Publish' runs-on: ubuntu-24.04 needs: [windows, testdemos, linux] steps: - name: Deploying linux artifacts uses: actions/download-artifact@v4 with: name: linux32 - name: Deploying windows artifacts uses: actions/download-artifact@v4 with: name: win32 - name: Reading appversion.h run: | if [ -e appversion.h ]; then APP_VERSION=$(cat appversion.h | grep -wi '#define APP_VERSION_STRD' | sed -e 's/#define APP_VERSION_STRD[ \t\r\n\v\f]\+\(.*\)/\1/i' -e 's/\r//g') if [ $? -ne 0 ]; then APP_VERSION="" else # Remove quotes APP_VERSION=$(echo $APP_VERSION | xargs) echo "APP_VERSION=${APP_VERSION}" >> $GITHUB_ENV fi fi rm -f appversion.h - name: Final signing and Packaging bin/dbg id: packaging-job if: | github.event_name == 'release' && github.event.action == 'published' && startsWith(github.ref, 'refs/tags/') run: | # new runner, niw signs echo "${{ secrets.PUB_ASC }}" > "${{ secrets.PUB_ASC_FILE }}" echo "${{ secrets.KEY_ASC }}" > "${{ secrets.KEY_ASC_FILE }}" gpg --batch --yes --import "${{ secrets.PUB_ASC_FILE }}" gpg --batch --yes --import "${{ secrets.KEY_ASC_FILE }}" GPG_LINUX_FINGERPRINT=$(gpg --list-keys --with-colons | grep '^fpr' | head -n 1 | cut -d: -f10) echo "$GPG_LINUX_FINGERPRINT:6:" | gpg --batch --import-ownertrust echo "GPG_LINUX_FINGERPRINT=$GPG_LINUX_FINGERPRINT" >> $GITHUB_ENV sign_file() { local file=$1 gpg --batch --yes --detach-sign --armor -u "$GPG_LINUX_FINGERPRINT" "$file" if [ $? -ne 0 ]; then echo "Error: Failed to sign $file" exit 2 fi echo "$file signed successfully." } # Pack and sign final archive 7z a -tzip rehlds-bin-${{ env.APP_VERSION }}.zip bin/ hlsdk/ sign_file "rehlds-bin-${{ env.APP_VERSION }}.zip" # Pack and sign final archive 7z a -t7z -m0=lzma2 -mx=9 -mfb=64 -aoa rehlds-dbg-${{ env.APP_VERSION }}.7z debug/ sign_file "rehlds-dbg-${{ env.APP_VERSION }}.7z" shell: bash - name: Publish artifacts uses: softprops/action-gh-release@v2 id: publish-job if: | startsWith(github.ref, 'refs/tags/') && steps.packaging-job.outcome == 'success' with: files: | *.zip *.7z *.asc env: GITHUB_TOKEN: ${{ secrets.API_TOKEN }}