Skip to content

update readme.

update readme. #10

Workflow file for this run

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/