update readme. #10
This file contains hidden or 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: GeoSharPlus CI | |
| on: | |
| push: | |
| branches: [ main ] | |
| pull_request: | |
| branches: [ main ] | |
| workflow_dispatch: | |
| env: | |
| DOTNET_VERSION: '8.0.x' | |
| CPP_PROJECT: GeoSharPlusCPP | |
| CPP_PREBUILD_DIR: cppPrebuild | |
| jobs: | |
| # ============================================ | |
| # Build C++ Library | |
| # ============================================ | |
| # This job builds the native C++ library using CMake presets and vcpkg. | |
| # ============================================ | |
| build-cpp: | |
| name: Build C++ (${{ matrix.os }}) | |
| strategy: | |
| matrix: | |
| os: [windows-latest, macos-latest] | |
| include: | |
| - os: windows-latest | |
| output-ext: ".dll" | |
| output-path: "build/GeoSharPlusCPP.dll" | |
| triplet: "x64-windows" | |
| configure-preset: "windows-default" | |
| build-preset: "windows-release" | |
| - os: macos-latest | |
| output-ext: ".dylib" | |
| output-path: "build/libGeoSharPlusCPP.dylib" | |
| triplet: "arm64-osx" | |
| configure-preset: "macos-default" | |
| build-preset: "macos-release" | |
| fail-fast: false | |
| runs-on: ${{ matrix.os }} | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| with: | |
| submodules: recursive | |
| # Generate cache key based on C++ source files | |
| - name: Generate C++ Cache Key (macOS) | |
| if: matrix.os == 'macos-latest' | |
| id: cpp-cache-key | |
| shell: bash | |
| run: | | |
| cpp_hash=$(find ${{ env.CPP_PROJECT }}/src ${{ env.CPP_PROJECT }}/include -type f \( -name "*.cpp" -o -name "*.h" -o -name "*.hpp" \) -exec shasum -a 256 {} \; 2>/dev/null | sort | shasum -a 256 | cut -d' ' -f1) | |
| cmake_hash=$(shasum -a 256 ${{ env.CPP_PROJECT }}/CMakeLists.txt ${{ env.CPP_PROJECT }}/CMakePresets.json 2>/dev/null | shasum -a 256 | cut -d' ' -f1) | |
| echo "hash=${cpp_hash:0:16}${cmake_hash:0:16}" >> $GITHUB_OUTPUT | |
| echo "C++ source hash: ${cpp_hash:0:16}${cmake_hash:0:16}" | |
| - name: Generate C++ Cache Key (Windows) | |
| if: matrix.os == 'windows-latest' | |
| id: cpp-cache-key-windows | |
| shell: pwsh | |
| run: | | |
| $files = Get-ChildItem -Path "${{ env.CPP_PROJECT }}" -Recurse -Include *.cpp,*.h,*.hpp,CMakeLists.txt,CMakePresets.json | | |
| Where-Object { $_.FullName -notmatch '[\\/]build[\\/]' } | | |
| Sort-Object FullName | |
| $hashInput = "" | |
| foreach ($file in $files) { | |
| $relativePath = $file.FullName.Replace("${{ github.workspace }}\", "").Replace("\", "/") | |
| $contentHash = (Get-FileHash -Path $file.FullName -Algorithm SHA256).Hash | |
| $hashInput += "$relativePath`:$contentHash`n" | |
| } | |
| $stringAsStream = [System.IO.MemoryStream]::new() | |
| $writer = [System.IO.StreamWriter]::new($stringAsStream) | |
| $writer.write($hashInput) | |
| $writer.Flush() | |
| $stringAsStream.Position = 0 | |
| $cpp_hash = (Get-FileHash -InputStream $stringAsStream -Algorithm SHA256).Hash.ToLower().Substring(0, 32) | |
| echo "hash=$cpp_hash" >> $env:GITHUB_OUTPUT | |
| echo "C++ source hash: $cpp_hash" | |
| # Try to restore C++ build from cache | |
| - name: Cache C++ Build Artifacts | |
| id: cache-cpp | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| ${{ env.CPP_PROJECT }}/build | |
| ${{ env.CPP_PREBUILD_DIR }} | |
| key: cpp-build-${{ matrix.os }}-${{ matrix.os == 'windows-latest' && steps.cpp-cache-key-windows.outputs.hash || steps.cpp-cache-key.outputs.hash }} | |
| restore-keys: | | |
| cpp-build-${{ matrix.os }}- | |
| # Setup CMake (only if cache miss) | |
| - name: Setup CMake | |
| if: steps.cache-cpp.outputs.cache-hit != 'true' | |
| uses: lukka/get-cmake@latest | |
| # Setup vcpkg (only if cache miss) | |
| - name: Setup vcpkg | |
| if: steps.cache-cpp.outputs.cache-hit != 'true' | |
| uses: lukka/run-vcpkg@v11 | |
| with: | |
| vcpkgGitCommitId: ce613c41372b23b1f51333815feb3edd87ef8a8b | |
| # Configure and build using CMake presets (only if cache miss) | |
| - name: Configure and Build with CMake | |
| if: steps.cache-cpp.outputs.cache-hit != 'true' | |
| uses: lukka/run-cmake@v10 | |
| with: | |
| cmakeListsTxtPath: "${{ github.workspace }}/${{ env.CPP_PROJECT }}/CMakeLists.txt" | |
| configurePreset: ${{ matrix.configure-preset }} | |
| buildPreset: ${{ matrix.build-preset }} | |
| # Create prebuild directory | |
| - name: Create prebuild directory | |
| if: steps.cache-cpp.outputs.cache-hit != 'true' | |
| shell: bash | |
| run: | | |
| mkdir -p ${{ env.CPP_PREBUILD_DIR }} | |
| # Copy C++ artifacts (Windows) | |
| - name: Copy C++ artifacts (Windows) | |
| if: steps.cache-cpp.outputs.cache-hit != 'true' && matrix.os == 'windows-latest' | |
| shell: pwsh | |
| run: | | |
| Write-Host "Copying C++ artifacts (Windows)..." -ForegroundColor Cyan | |
| $found = $false | |
| # Check the specified output path first | |
| if (Test-Path "${{ github.workspace }}/${{ env.CPP_PROJECT }}/${{ matrix.output-path }}") { | |
| Copy-Item "${{ github.workspace }}/${{ env.CPP_PROJECT }}/${{ matrix.output-path }}" -Destination "${{ env.CPP_PREBUILD_DIR }}/GeoSharPlusCPP${{ matrix.output-ext }}" | |
| Write-Host "Copied from ${{ matrix.output-path }}" -ForegroundColor Green | |
| $found = $true | |
| } | |
| # Check build/Release subdirectory | |
| elseif (Test-Path "${{ github.workspace }}/${{ env.CPP_PROJECT }}/build/Release/GeoSharPlusCPP.dll") { | |
| Copy-Item "${{ github.workspace }}/${{ env.CPP_PROJECT }}/build/Release/GeoSharPlusCPP.dll" -Destination "${{ env.CPP_PREBUILD_DIR }}/GeoSharPlusCPP${{ matrix.output-ext }}" | |
| Write-Host "Copied from build/Release/" -ForegroundColor Green | |
| $found = $true | |
| } | |
| if (-not $found) { | |
| Write-Host "Built library not found at expected locations" -ForegroundColor Red | |
| Write-Host "Searching for DLL in build directory..." -ForegroundColor Yellow | |
| Get-ChildItem -Path "${{ github.workspace }}/${{ env.CPP_PROJECT }}/build" -Recurse -Filter "*.dll" | ForEach-Object { | |
| Write-Host " - $($_.FullName)" -ForegroundColor Gray | |
| } | |
| exit 1 | |
| } | |
| # Copy C++ artifacts (macOS) | |
| - name: Copy C++ artifacts (macOS) | |
| if: steps.cache-cpp.outputs.cache-hit != 'true' && matrix.os == 'macos-latest' | |
| shell: bash | |
| run: | | |
| echo "Copying C++ artifacts (macOS)..." | |
| found=false | |
| # Check the specified output path first | |
| if [ -f "${{ github.workspace }}/${{ env.CPP_PROJECT }}/${{ matrix.output-path }}" ]; then | |
| cp "${{ github.workspace }}/${{ env.CPP_PROJECT }}/${{ matrix.output-path }}" "${{ env.CPP_PREBUILD_DIR }}/libGeoSharPlusCPP${{ matrix.output-ext }}" | |
| echo "Copied from ${{ matrix.output-path }}" | |
| found=true | |
| # Check build/Release subdirectory | |
| elif [ -f "${{ github.workspace }}/${{ env.CPP_PROJECT }}/build/Release/libGeoSharPlusCPP.dylib" ]; then | |
| cp "${{ github.workspace }}/${{ env.CPP_PROJECT }}/build/Release/libGeoSharPlusCPP.dylib" "${{ env.CPP_PREBUILD_DIR }}/libGeoSharPlusCPP${{ matrix.output-ext }}" | |
| echo "Copied from build/Release/" | |
| found=true | |
| fi | |
| if [ "$found" = false ]; then | |
| echo "Built library not found at expected locations" | |
| echo "Searching for dylib files..." | |
| find "${{ github.workspace }}/${{ env.CPP_PROJECT }}/build" -name "*.dylib" -type f 2>/dev/null | |
| exit 1 | |
| fi | |
| # Report cache status | |
| - name: Report Cache Status | |
| shell: bash | |
| run: | | |
| if [ "${{ steps.cache-cpp.outputs.cache-hit }}" = "true" ]; then | |
| echo "Using cached C++ build" | |
| else | |
| echo "Fresh C++ build completed" | |
| fi | |
| # Upload C++ artifacts | |
| - name: Upload C++ artifacts | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: cpp-libs-${{ matrix.os }} | |
| path: ${{ env.CPP_PREBUILD_DIR }} | |
| # ============================================ | |
| # Build and Test .NET Projects | |
| # ============================================ | |
| test-dotnet-core: | |
| name: Test .NET Core (${{ matrix.os }}) | |
| runs-on: ${{ matrix.os }} | |
| strategy: | |
| matrix: | |
| os: [ubuntu-latest, windows-latest, macos-latest] | |
| fail-fast: false | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| with: | |
| submodules: recursive | |
| - name: Setup .NET | |
| uses: actions/setup-dotnet@v4 | |
| with: | |
| dotnet-version: ${{ env.DOTNET_VERSION }} | |
| - name: Cache NuGet packages | |
| uses: actions/cache@v4 | |
| with: | |
| path: ~/.nuget/packages | |
| key: ${{ runner.os }}-nuget-${{ hashFiles('**/*.csproj') }} | |
| restore-keys: | | |
| ${{ runner.os }}-nuget- | |
| - name: Verify generated FlatBuffer files exist | |
| shell: bash | |
| run: | | |
| echo "Checking for generated FlatBuffer files..." | |
| if [ -d "generated/GSP_FB/csharp" ]; then | |
| echo "Found generated/GSP_FB/csharp/" | |
| ls -la generated/GSP_FB/csharp/ | |
| file_count=$(ls -1 generated/GSP_FB/csharp/*.cs 2>/dev/null | wc -l) | |
| echo "Found $file_count generated C# files" | |
| if [ "$file_count" -lt 1 ]; then | |
| echo "No .cs files found in generated/GSP_FB/csharp/" | |
| exit 1 | |
| fi | |
| else | |
| echo "Missing generated/GSP_FB/csharp/ directory" | |
| echo "Please run the FlatBuffer compiler locally and commit the generated files." | |
| exit 1 | |
| fi | |
| - name: Restore dependencies | |
| run: dotnet restore GeoSharPlusNET.Tests/GeoSharPlusNET.Tests.csproj | |
| - name: Build test project | |
| run: dotnet build GeoSharPlusNET.Tests/GeoSharPlusNET.Tests.csproj --configuration Release --no-restore | |
| - name: Run tests | |
| run: dotnet test GeoSharPlusNET.Tests/GeoSharPlusNET.Tests.csproj --configuration Release --no-build --verbosity normal --logger "trx;LogFileName=test-results.trx" | |
| - name: Upload test results | |
| uses: actions/upload-artifact@v4 | |
| if: always() | |
| with: | |
| name: test-results-${{ matrix.os }} | |
| path: '**/TestResults/*.trx' | |
| # ============================================ | |
| # Build Full .NET Solution with C++ Libraries | |
| # ============================================ | |
| build-dotnet-full: | |
| name: Build .NET Solution | |
| runs-on: windows-latest | |
| needs: [build-cpp, test-dotnet-core] | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| with: | |
| submodules: recursive | |
| - name: Setup .NET | |
| uses: actions/setup-dotnet@v4 | |
| with: | |
| dotnet-version: ${{ env.DOTNET_VERSION }} | |
| - name: Cache NuGet packages | |
| uses: actions/cache@v4 | |
| with: | |
| path: ~/.nuget/packages | |
| key: ${{ runner.os }}-nuget-${{ hashFiles('**/*.csproj') }} | |
| restore-keys: | | |
| ${{ runner.os }}-nuget- | |
| # Download C++ artifacts | |
| - name: Download Windows C++ libs | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: cpp-libs-windows-latest | |
| path: ${{ env.CPP_PREBUILD_DIR }}/windows | |
| - name: Download macOS C++ libs | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: cpp-libs-macos-latest | |
| path: ${{ env.CPP_PREBUILD_DIR }}/macos | |
| - name: Restore GeoSharPlusNET | |
| run: dotnet restore GeoSharPlusNET/GeoSharPlusNET.csproj | |
| - name: Build GeoSharPlusNET (Release) | |
| run: dotnet build GeoSharPlusNET/GeoSharPlusNET.csproj --configuration Release --no-restore | |
| # Copy C++ libraries to output directories | |
| - name: Copy C++ libraries to output | |
| shell: pwsh | |
| run: | | |
| Write-Host "Copying C++ libraries to output directories..." -ForegroundColor Cyan | |
| # Find all target framework directories in bin/Release/ | |
| $binReleasePath = "${{ github.workspace }}/bin/Release" | |
| if (Test-Path $binReleasePath) { | |
| $targetDirs = Get-ChildItem -Path $binReleasePath -Directory | |
| foreach ($targetDir in $targetDirs) { | |
| Write-Host "Target: $($targetDir.Name)" -ForegroundColor Yellow | |
| # Copy Windows DLL | |
| $windowsDll = "${{ env.CPP_PREBUILD_DIR }}/windows/GeoSharPlusCPP.dll" | |
| if (Test-Path $windowsDll) { | |
| Copy-Item -Path $windowsDll -Destination $targetDir.FullName -Force | |
| Write-Host " Copied GeoSharPlusCPP.dll" -ForegroundColor Green | |
| } | |
| # Copy macOS dylib | |
| $macosDylib = "${{ env.CPP_PREBUILD_DIR }}/macos/libGeoSharPlusCPP.dylib" | |
| if (Test-Path $macosDylib) { | |
| Copy-Item -Path $macosDylib -Destination $targetDir.FullName -Force | |
| Write-Host " Copied libGeoSharPlusCPP.dylib" -ForegroundColor Green | |
| } | |
| } | |
| } | |
| # Also copy to GeoSharPlusNET output if it exists | |
| $netOutputPath = "GeoSharPlusNET/bin/Release" | |
| if (Test-Path $netOutputPath) { | |
| $targetDirs = Get-ChildItem -Path $netOutputPath -Directory | |
| foreach ($targetDir in $targetDirs) { | |
| $windowsDll = "${{ env.CPP_PREBUILD_DIR }}/windows/GeoSharPlusCPP.dll" | |
| if (Test-Path $windowsDll) { | |
| Copy-Item -Path $windowsDll -Destination $targetDir.FullName -Force | |
| } | |
| $macosDylib = "${{ env.CPP_PREBUILD_DIR }}/macos/libGeoSharPlusCPP.dylib" | |
| if (Test-Path $macosDylib) { | |
| Copy-Item -Path $macosDylib -Destination $targetDir.FullName -Force | |
| } | |
| } | |
| } | |
| - name: Upload build artifacts | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: GeoSharPlusNET-build | |
| path: | | |
| GeoSharPlusNET/bin/Release/ | |
| ${{ env.CPP_PREBUILD_DIR }}/ | |
| # ============================================ | |
| # Test Coverage Report | |
| # ============================================ | |
| coverage: | |
| name: Test Coverage | |
| runs-on: ubuntu-latest | |
| needs: test-dotnet-core | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Setup .NET | |
| uses: actions/setup-dotnet@v4 | |
| with: | |
| dotnet-version: ${{ env.DOTNET_VERSION }} | |
| - name: Restore dependencies | |
| run: dotnet restore GeoSharPlusNET.Tests/GeoSharPlusNET.Tests.csproj | |
| - name: Run tests with coverage | |
| run: | | |
| dotnet test GeoSharPlusNET.Tests/GeoSharPlusNET.Tests.csproj \ | |
| --configuration Release \ | |
| --collect:"XPlat Code Coverage" \ | |
| --results-directory ./coverage | |
| - name: Upload coverage reports | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: coverage-report | |
| path: coverage/**/coverage.cobertura.xml | |
| # ============================================ | |
| # Generate FlatBuffer Files (Manual trigger only) | |
| # ============================================ | |
| generate-flatbuffers: | |
| name: Generate FlatBuffers | |
| runs-on: ubuntu-latest | |
| if: github.event_name == 'workflow_dispatch' | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Install FlatBuffers compiler | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y flatbuffers-compiler | |
| flatc --version | |
| - name: Generate C# files | |
| run: | | |
| mkdir -p generated/GSP_FB/csharp | |
| for schema in GeoSharPlusCPP/schema/*.fbs; do | |
| echo "Generating C# from $schema..." | |
| flatc --csharp --gen-object-api --scoped-enums -o generated/GSP_FB/csharp "$schema" | |
| done | |
| echo "Generated files:" | |
| ls -la generated/GSP_FB/csharp/ | |
| - name: Generate C++ files | |
| run: | | |
| mkdir -p generated/GSP_FB/cpp | |
| for schema in GeoSharPlusCPP/schema/*.fbs; do | |
| echo "Generating C++ from $schema..." | |
| flatc --cpp --scoped-enums -o generated/GSP_FB/cpp "$schema" | |
| done | |
| echo "Generated files:" | |
| ls -la generated/GSP_FB/cpp/ | |
| - name: Upload generated files | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: generated-flatbuffers | |
| path: generated/GSP_FB/ |