Repository navigation
Bump MongoDB.Driver from 3.11.2 to 3.12.0 #527
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: CI | |
| on: | |
| push: | |
| branches: [main] | |
| tags: ['v*'] | |
| pull_request: | |
| branches: [main] | |
| env: | |
| DOTNET_NOLOGO: true | |
| DOTNET_CLI_TELEMETRY_OPTOUT: true | |
| jobs: | |
| build-native-macos: | |
| if: startsWith(github.ref, 'refs/tags/v') | |
| runs-on: macos-latest | |
| timeout-minutes: 60 | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - name: Cache macOS native codecs | |
| id: cache-macos | |
| uses: actions/cache@v6 | |
| with: | |
| path: native/runtimes/osx-* | |
| key: native-macos-${{ hashFiles('native/build-macos.sh', 'native/src/**') }} | |
| - name: Cache vendor sources | |
| if: steps.cache-macos.outputs.cache-hit != 'true' | |
| uses: actions/cache@v6 | |
| with: | |
| path: | | |
| native/vendor/libjpeg-turbo/src | |
| native/vendor/charls/src | |
| native/vendor/openjpeg/src | |
| native/vendor/ffmpeg | |
| native/vendor/x265 | |
| native/vendor/x264 | |
| key: vendors-macos-${{ hashFiles('native/build-macos.sh') }} | |
| - name: Install build dependencies | |
| if: steps.cache-macos.outputs.cache-hit != 'true' | |
| run: | | |
| brew install nasm cmake | |
| nasm --version | |
| cmake --version | |
| - name: Build native codecs for macOS | |
| if: steps.cache-macos.outputs.cache-hit != 'true' | |
| run: | | |
| chmod +x native/build-macos.sh | |
| ./native/build-macos.sh | |
| - name: Verify outputs | |
| run: | | |
| echo "=== macOS native codec libraries ===" | |
| ls -lh native/runtimes/osx-arm64/native/ || echo "osx-arm64 not found" | |
| ls -lh native/runtimes/osx-x64/native/ || echo "osx-x64 not found" | |
| - name: Upload macOS native codecs | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: native-codecs-macos | |
| path: native/runtimes/osx-* | |
| retention-days: 7 | |
| build: | |
| needs: [build-native-macos] | |
| if: always() && (needs.build-native-macos.result == 'success' || needs.build-native-macos.result == 'skipped') | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 90 | |
| permissions: | |
| contents: write | |
| services: | |
| orthanc: | |
| image: orthancteam/orthanc:25.12.3 | |
| ports: | |
| - 4242:4242 # DICOM port | |
| - 8042:8042 # HTTP API | |
| steps: | |
| - uses: actions/checkout@v7 | |
| with: | |
| submodules: true | |
| # .NET Setup | |
| - name: Setup .NET | |
| uses: actions/setup-dotnet@v6 | |
| with: | |
| global-json-file: global.json | |
| cache: true | |
| cache-dependency-path: Directory.Packages.props | |
| # Install packages with caching | |
| - name: Cache and install apt packages | |
| uses: awalsh128/cache-apt-pkgs-action@v1 | |
| with: | |
| packages: dcmtk libcharls-dev libcharls2 cmake nasm libtiff-dev libboost-program-options-dev binutils-aarch64-linux-gnu lld | |
| version: 2.0 | |
| execute_install_scripts: true | |
| # ccache for native C/C++ builds (OpenJPH, charls-tools) | |
| - name: Setup ccache | |
| uses: hendrikmuhs/ccache-action@v1 | |
| with: | |
| max-size: 500M | |
| key: test-tools | |
| # Build OpenJPH from source (openjph-tools not available in Noble 24.04) | |
| - name: Build and install OpenJPH | |
| run: | | |
| git clone --depth 1 --branch 0.26.0 https://github.com/aous72/OpenJPH.git /tmp/openjph | |
| cmake -S /tmp/openjph -B /tmp/openjph/build \ | |
| -DCMAKE_BUILD_TYPE=Release \ | |
| -DCMAKE_INSTALL_PREFIX=/usr/local \ | |
| -DCMAKE_C_COMPILER_LAUNCHER=ccache \ | |
| -DCMAKE_CXX_COMPILER_LAUNCHER=ccache | |
| cmake --build /tmp/openjph/build --parallel $(nproc) | |
| sudo cmake --install /tmp/openjph/build | |
| sudo ldconfig | |
| # Build charls-tools from source (cjpls/djpls CLI) | |
| - name: Build and install charls-tools | |
| run: | | |
| git clone --depth 1 https://github.com/malaterre/charls-tools.git /tmp/charls-tools | |
| cmake -S /tmp/charls-tools -B /tmp/charls-tools/build \ | |
| -DCMAKE_BUILD_TYPE=Release \ | |
| -DCMAKE_INSTALL_PREFIX=/usr/local \ | |
| -DCMAKE_C_COMPILER_LAUNCHER=ccache \ | |
| -DCMAKE_CXX_COMPILER_LAUNCHER=ccache | |
| cmake --build /tmp/charls-tools/build --target cjpls djpls --parallel $(nproc) | |
| sudo install /tmp/charls-tools/build/cjpls /usr/local/bin/ | |
| sudo install /tmp/charls-tools/build/djpls /usr/local/bin/ | |
| - name: Verify package installations | |
| run: | | |
| # DCMTK - required for interop tests | |
| dcmsend --version | |
| dcmrecv --version | |
| # CharLS tools - required for JPEG-LS conformance tests | |
| which cjpls | |
| which djpls | |
| # OpenJPH - required for HTJ2K conformance tests | |
| which ojph_compress | |
| which ojph_expand | |
| echo "DCMTK_ROOT=/usr" >> $GITHUB_ENV | |
| - name: Start DCMTK services for integration tests | |
| run: | | |
| # Create output directory for received DICOM files | |
| mkdir -p /tmp/dcmtk-received | |
| # Start storescp on port 11120 (for C-STORE SCU tests) | |
| storescp -v -od /tmp/dcmtk-received 11120 > /tmp/storescp-11120.log 2>&1 & | |
| # Start storescp on port 11113 (for C-ECHO tests) | |
| storescp -v 11113 > /tmp/storescp-11113.log 2>&1 & | |
| # Give services time to start | |
| sleep 2 | |
| # Verify they're listening | |
| netstat -ln | grep -E ":(11120|11113)" || echo "Some DCMTK services may not have started" | |
| # Build Phase 1: .NET | |
| - name: Restore .NET dependencies | |
| run: dotnet restore | |
| - name: Build .NET projects | |
| run: dotnet build --no-restore --configuration Release | |
| # Build Phase 2: Native codecs for Linux and Windows (cached) | |
| - name: Cache cross-compilation toolchains | |
| uses: actions/cache@v6 | |
| with: | |
| path: ~/toolchains | |
| key: toolchains-bootlin-2025.08-1-llvm-mingw-20240619 | |
| - name: Cache Linux/Windows native codecs | |
| id: cache-linux | |
| uses: actions/cache@v6 | |
| with: | |
| path: | | |
| native/runtimes/linux-* | |
| native/runtimes/win-* | |
| key: native-linux-${{ github.ref_type }}-${{ hashFiles('native/build-linux.sh', 'native/src/**') }} | |
| - name: Set build targets | |
| run: | | |
| if [[ "${{ startsWith(github.ref, 'refs/tags/v') }}" == "true" ]]; then | |
| echo "BUILD_TARGETS=" >> $GITHUB_ENV | |
| else | |
| echo "BUILD_TARGETS=linux-x64" >> $GITHUB_ENV | |
| fi | |
| - name: Build native codecs for Linux and Windows | |
| if: steps.cache-linux.outputs.cache-hit != 'true' | |
| run: | | |
| chmod +x native/build-linux.sh | |
| ./native/build-linux.sh $BUILD_TARGETS | |
| # Download macOS native codecs from the parallel macOS job | |
| - name: Download macOS native codecs | |
| if: needs.build-native-macos.result == 'success' | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: native-codecs-macos | |
| path: native/runtimes/ | |
| - name: Verify native codec libraries | |
| run: | | |
| LIB=native/runtimes/linux-x64/native/libsharpdicom_codecs.so | |
| echo "=== All native codec libraries ===" | |
| find native/runtimes/ -type f \( -name '*.so' -o -name '*.dylib' -o -name '*.dll' \) -exec ls -lh {} \; | |
| echo "" | |
| echo "=== linux-x64 dependencies ===" | |
| ldd $LIB || true | |
| echo "" | |
| echo "=== dlopen smoke test ===" | |
| cat > /tmp/test_dlopen.c << 'CEOF' | |
| #include <dlfcn.h> | |
| #include <stdio.h> | |
| int main() { | |
| printf("Attempting dlopen...\n"); | |
| void *h = dlopen("libsharpdicom_codecs.so", RTLD_NOW); | |
| if (!h) { fprintf(stderr, "dlopen failed: %s\n", dlerror()); return 1; } | |
| printf("dlopen OK\n"); | |
| void *v = dlsym(h, "sharpdicom_codecs_version"); | |
| printf("sharpdicom_codecs_version sym: %p\n", v); | |
| if (v) { | |
| const char* (*fn)(void) = v; | |
| printf("version: %s\n", fn()); | |
| } | |
| dlclose(h); | |
| printf("dlclose OK\n"); | |
| return 0; | |
| } | |
| CEOF | |
| gcc -o /tmp/test_dlopen /tmp/test_dlopen.c -ldl | |
| LD_LIBRARY_PATH=$(dirname $(realpath $LIB)) /tmp/test_dlopen | |
| # Copy native libraries to test directories | |
| - name: Copy native codecs to test assemblies | |
| run: | | |
| NATIVE_LIB=${{ github.workspace }}/native/runtimes/linux-x64/native/libsharpdicom_codecs.so | |
| echo "Native library: $NATIVE_LIB" | |
| ls -la $NATIVE_LIB || echo "Warning: Native library not found" | |
| # Copy to all test assembly directories | |
| for testdir in tests/*/bin/Release/net*/; do | |
| if [ -d "$testdir" ]; then | |
| echo "Copying to $testdir" | |
| cp -v "$NATIVE_LIB" "$testdir" 2>/dev/null || true | |
| fi | |
| done | |
| # Test Phase: .NET tests with coverage | |
| - name: Test with coverage | |
| run: dotnet test --no-build --configuration Release --settings tests/test.runsettings --results-directory $GITHUB_WORKSPACE/TestResults -- --coverage --coverage-output-format cobertura | |
| env: | |
| LD_LIBRARY_PATH: ${{ github.workspace }}/native/runtimes/linux-x64/native | |
| SHARPDICOM_NATIVE_DEBUG: "1" | |
| # Integration Tests: Orthanc | |
| - name: Wait for Orthanc | |
| run: | | |
| for i in {1..30}; do | |
| if curl -s http://localhost:8042/system > /dev/null 2>&1; then | |
| echo "Orthanc is ready" | |
| exit 0 | |
| fi | |
| echo "Waiting for Orthanc... ($i/30)" | |
| sleep 2 | |
| done | |
| echo "Orthanc may not be ready, continuing anyway" | |
| - name: Integration tests with Orthanc | |
| continue-on-error: true # Orthanc tests are optional for now | |
| run: dotnet test --no-build --configuration Release --settings tests/test.runsettings --filter "Category=Orthanc" | |
| env: | |
| ORTHANC_HOST: localhost | |
| ORTHANC_DICOM_PORT: 4242 | |
| ORTHANC_AE_TITLE: ORTHANC | |
| # Integration Tests: DCMTK | |
| - name: Integration tests with DCMTK | |
| run: dotnet test --no-build --configuration Release --settings tests/test.runsettings --filter "Category=DCMTK" --project tests/SharpDicom.Tests/SharpDicom.Tests.csproj | |
| env: | |
| DCMTK_ROOT: /usr | |
| LD_LIBRARY_PATH: ${{ github.workspace }}/native/runtimes/linux-x64/native | |
| # Upload coverage | |
| - name: Collect coverage files | |
| id: coverage | |
| run: | | |
| FILES=$(find $GITHUB_WORKSPACE/TestResults -name '*.cobertura.xml' -printf '%p,' 2>/dev/null | sed 's/,$//') | |
| echo "files=$FILES" >> $GITHUB_OUTPUT | |
| echo "Found coverage files: $FILES" | |
| - name: Upload coverage to Codecov | |
| if: steps.coverage.outputs.files != '' | |
| uses: codecov/codecov-action@v7 | |
| with: | |
| files: ${{ steps.coverage.outputs.files }} | |
| disable_search: true | |
| flags: unittests | |
| fail_ci_if_error: false | |
| env: | |
| CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} | |
| # Upload combined native codec artifacts (all 6 platforms) | |
| - name: Upload native codec artifacts | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: native-codecs | |
| path: native/runtimes/ | |
| retention-days: 7 | |
| # NuGet Package (on tags only) | |
| - name: Pack | |
| if: startsWith(github.ref, 'refs/tags/v') | |
| run: | | |
| dotnet pack --no-build --configuration Release -p:PackageVersion=${GITHUB_REF_NAME#v} -warnaserror | |
| # Validate package was created and contains expected assemblies | |
| NUPKG="src/SharpDicom/bin/Release/SharpDicom.${GITHUB_REF_NAME#v}.nupkg" | |
| if [ ! -f "$NUPKG" ]; then | |
| echo "::error::Package not found: $NUPKG" | |
| exit 1 | |
| fi | |
| echo "Package contents:" | |
| unzip -l "$NUPKG" | |
| # Verify DLLs have embedded PDBs (file size check - embedded PDBs make DLLs larger) | |
| unzip -p "$NUPKG" "lib/net9.0/SharpDicom.dll" > /tmp/check.dll | |
| if [ $(stat -c%s /tmp/check.dll 2>/dev/null || stat -f%z /tmp/check.dll) -lt 100000 ]; then | |
| echo "::error::DLL suspiciously small - may be missing embedded symbols" | |
| exit 1 | |
| fi | |
| echo "::notice::Package validated successfully" | |
| - name: Push to NuGet | |
| if: startsWith(github.ref, 'refs/tags/v') | |
| run: dotnet nuget push "src/**/bin/Release/*.nupkg" --api-key ${{ secrets.NUGET_API_KEY }} --source https://api.nuget.org/v3/index.json --skip-duplicate | |
| # Native AOT CLI binaries (Linux + Windows cross-compilation) | |
| - name: Setup Zig (for AOT cross-compilation) | |
| uses: mlugg/setup-zig@v2 | |
| with: | |
| version: 0.13.0 | |
| - name: Install xwin (Windows SDK for cross-compilation) | |
| run: | | |
| curl -fsSL -o /tmp/xwin.tar.gz https://github.com/Jake-Shadle/xwin/releases/download/0.8.0/xwin-0.8.0-x86_64-unknown-linux-musl.tar.gz | |
| echo "8a354e12475dd154d0a2d3084eefd2c105f872ec8062965baaa7e9f2f76fe611 /tmp/xwin.tar.gz" | sha256sum -c | |
| sudo tar xzf /tmp/xwin.tar.gz -C /usr/local/bin --strip-components=1 xwin-0.8.0-x86_64-unknown-linux-musl/xwin | |
| rm /tmp/xwin.tar.gz | |
| xwin --version | |
| - name: Publish AOT for Linux and Windows | |
| run: | | |
| for rid in linux-x64 linux-arm64 win-x64 win-arm64; do | |
| echo "::group::Publishing $rid" | |
| EXTRA_PROPS="" | |
| # Cross-compiled targets need the cross-objcopy for debug symbol extraction | |
| case "$rid" in | |
| linux-arm64) EXTRA_PROPS="-p:ObjCopyName=aarch64-linux-gnu-objcopy" ;; | |
| esac | |
| dotnet publish src/SharpDicom.Cli/SharpDicom.Cli.csproj -c Release -r $rid -o publish/$rid $EXTRA_PROPS | |
| echo "::endgroup::" | |
| done | |
| - name: Archive binaries | |
| if: startsWith(github.ref, 'refs/tags/v') | |
| run: | | |
| for rid in linux-x64 linux-arm64; do | |
| tar -czf sharpdcm-$rid.tar.gz -C publish/$rid . | |
| done | |
| for rid in win-x64 win-arm64; do | |
| (cd publish/$rid && zip -q ../../sharpdcm-$rid.zip *) | |
| done | |
| - name: Create release | |
| if: startsWith(github.ref, 'refs/tags/v') | |
| uses: softprops/action-gh-release@v3 | |
| with: | |
| generate_release_notes: true | |
| files: | | |
| sharpdcm-*.tar.gz | |
| sharpdcm-*.zip | |
| release-macos: | |
| if: startsWith(github.ref, 'refs/tags/v') | |
| needs: build | |
| runs-on: macos-latest | |
| timeout-minutes: 30 | |
| permissions: | |
| contents: write | |
| steps: | |
| - uses: actions/checkout@v7 | |
| with: | |
| submodules: true | |
| - name: Setup .NET | |
| uses: actions/setup-dotnet@v6 | |
| with: | |
| global-json-file: global.json | |
| - name: Publish AOT for macOS | |
| run: | | |
| for rid in osx-x64 osx-arm64; do | |
| echo "::group::Publishing $rid" | |
| dotnet publish src/SharpDicom.Cli/SharpDicom.Cli.csproj -c Release -r $rid -o publish/$rid | |
| echo "::endgroup::" | |
| done | |
| - name: Archive macOS binaries | |
| run: | | |
| for rid in osx-x64 osx-arm64; do | |
| tar -czf sharpdcm-$rid.tar.gz -C publish/$rid . | |
| done | |
| - name: Append macOS binaries to release | |
| uses: softprops/action-gh-release@v3 | |
| with: | |
| files: sharpdcm-osx-*.tar.gz |