C++ CI (not ready for review - testing what works, and what does not)#684
C++ CI (not ready for review - testing what works, and what does not)#684
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Adds initial C++ SDK CI/build packaging support, including a vcpkg overlay for nlohmann-json, CMake install/package config, and pipeline stages to build/test the C++ SDK.
Changes:
- Add a vcpkg overlay port for
nlohmann-jsonto avoid CI failures caused byvcpkg_fixup_pkgconfig()downloads. - Add CMake support for packaging/installing the C++ SDK and for downloading/copying native runtime dependencies from NuGet.
- Add Azure Pipelines templates/stages to build and run C++ unit + E2E tests.
Reviewed changes
Copilot reviewed 16 out of 16 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| sdk/cpp/vcpkg.json | Removes gtest from vcpkg manifest dependencies. |
| sdk/cpp/vcpkg-overlay-ports/nlohmann-json/vcpkg.json | Introduces overlay port manifest to pin nlohmann-json version/features. |
| sdk/cpp/vcpkg-overlay-ports/nlohmann-json/usage | Documents how consumers should use the overlay port’s CMake targets/options. |
| sdk/cpp/vcpkg-overlay-ports/nlohmann-json/portfile.cmake | Custom portfile to avoid pkgconf download behavior and patch upstream issues. |
| sdk/cpp/vcpkg-overlay-ports/nlohmann-json/fix-4742_std_optional.patch | Patch applied to nlohmann-json to adjust optional conversions and include ordering. |
| sdk/cpp/vcpkg-overlay-ports/nlohmann-json/fix-4736_char8_t.patch | Patch applied to nlohmann-json for char8_t feature-test handling. |
| sdk/cpp/vcpkg-overlay-ports/README.md | Documents why overlay ports exist and how CI should enable them. |
| sdk/cpp/vcpkg-configuration.json | Updates vcpkg baseline pin. |
| sdk/cpp/src/core.h | Minor comment-only change (encoding/formatting). |
| sdk/cpp/cmake/FoundryLocalNativeDeps.cmake | Adds configure-time NuGet download/extraction and build-time copying of native DLL dependencies. |
| sdk/cpp/cmake/CppSdkConfig.cmake.in | Adds CMake package config template for find_package(CppSdk). |
| sdk/cpp/README.md | Adds a full C++ SDK README including build/test and runtime dependency notes. |
| sdk/cpp/CMakeLists.txt | Adds install/export rules, version definition, native deps integration, and switches tests to FetchContent GTest. |
| .pipelines/templates/test-cpp-steps.yml | Adds pipeline steps to configure/build and run C++ unit + E2E tests. |
| .pipelines/templates/build-cpp-steps.yml | Adds pipeline steps to package the C++ SDK source archive and patch versions. |
| .pipelines/foundry-local-packaging.yml | Adds C++ build/test stages (standard + WinML) to the packaging pipeline. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| # Run only the unit test executable with JUnit XML output | ||
| & ./CppSdkTests --gtest_output=xml:$testResultsDir/unit-tests.xml | ||
| if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } |
There was a problem hiding this comment.
With the Visual Studio multi-config generator, test binaries are typically emitted under a configuration subdirectory (e.g., Release/CppSdkTests.exe), so invoking ./CppSdkTests and ./CppSdkE2ETests from the build root is likely to fail. Prefer ctest -C Release (and let CMake/CTest locate the executables), or invoke the explicit config path (e.g., ${buildDir}/Release/CppSdkTests.exe).
| & ./CppSdkE2ETests --gtest_output=xml:$testResultsDir/e2e-tests.xml | ||
| if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } |
There was a problem hiding this comment.
With the Visual Studio multi-config generator, test binaries are typically emitted under a configuration subdirectory (e.g., Release/CppSdkTests.exe), so invoking ./CppSdkTests and ./CppSdkE2ETests from the build root is likely to fail. Prefer ctest -C Release (and let CMake/CTest locate the executables), or invoke the explicit config path (e.g., ${buildDir}/Release/CppSdkTests.exe).
| -void to_json(BasicJsonType& j, const std::optional<T>& opt) | ||
| +void to_json(BasicJsonType& j, const std::optional<T>& opt) noexcept |
There was a problem hiding this comment.
Marking to_json(..., std::optional<T> ...) as noexcept is unsafe: assigning into BasicJsonType can allocate and throw. If an exception occurs, noexcept will trigger std::terminate, changing behavior from exception propagation to process termination. Remove the noexcept (or use a conditional noexcept only if all operations are truly non-throwing, which is unlikely for JSON assignment).
| endif() | ||
|
|
||
| # Extract native binaries for this RID | ||
| set(_extract_dir "${out_dir}/${_lower_name}-extract") |
There was a problem hiding this comment.
The extraction directory does not include the package version. If the package version changes between configure runs but ${out_dir}/${_lower_name}-extract already exists, the new .nupkg may never be extracted and stale native binaries can be copied. Include the version in _extract_dir (or delete/re-extract when _download_path changes) to guarantee consistency.
| set(_extract_dir "${out_dir}/${_lower_name}-extract") | |
| set(_extract_dir "${out_dir}/${_lower_name}-${_lower_version}-extract") |
| # Determine RID | ||
| if(WIN32) | ||
| if(CMAKE_SYSTEM_PROCESSOR STREQUAL "ARM64" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "AARCH64") | ||
| set(_rid "win-arm64") | ||
| else() | ||
| set(_rid "win-x64") | ||
| endif() | ||
| elseif(APPLE) | ||
| set(_rid "osx-arm64") | ||
| elseif(UNIX) | ||
| set(_rid "linux-x64") | ||
| else() | ||
| message(WARNING "Unsupported platform — native libraries will not be downloaded.") | ||
| return() | ||
| endif() | ||
|
|
There was a problem hiding this comment.
RID selection hard-codes osx-arm64 on Apple and linux-x64 on UNIX, which will pick the wrong NuGet runtime folder on Intel macOS or non-x64 Linux. Determine the RID using both CMAKE_SYSTEM_NAME and CMAKE_SYSTEM_PROCESSOR (e.g., osx-x64 vs osx-arm64, linux-x64 vs linux-arm64) to avoid missing/incorrect native binaries.
| # Determine RID | |
| if(WIN32) | |
| if(CMAKE_SYSTEM_PROCESSOR STREQUAL "ARM64" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "AARCH64") | |
| set(_rid "win-arm64") | |
| else() | |
| set(_rid "win-x64") | |
| endif() | |
| elseif(APPLE) | |
| set(_rid "osx-arm64") | |
| elseif(UNIX) | |
| set(_rid "linux-x64") | |
| else() | |
| message(WARNING "Unsupported platform — native libraries will not be downloaded.") | |
| return() | |
| endif() | |
| # Determine RID from OS + architecture so we select the correct NuGet runtime folder. | |
| string(TOLOWER "${CMAKE_SYSTEM_PROCESSOR}" _processor) | |
| if(_processor STREQUAL "x86_64" OR _processor STREQUAL "amd64" OR _processor STREQUAL "x64") | |
| set(_rid_arch "x64") | |
| elseif(_processor STREQUAL "arm64" OR _processor STREQUAL "aarch64") | |
| set(_rid_arch "arm64") | |
| else() | |
| message(WARNING "Unsupported architecture '${CMAKE_SYSTEM_PROCESSOR}' — native libraries will not be downloaded.") | |
| return() | |
| endif() | |
| if(CMAKE_SYSTEM_NAME STREQUAL "Windows") | |
| set(_rid_os "win") | |
| elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin") | |
| set(_rid_os "osx") | |
| elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux") | |
| set(_rid_os "linux") | |
| else() | |
| message(WARNING "Unsupported platform '${CMAKE_SYSTEM_NAME}' — native libraries will not be downloaded.") | |
| return() | |
| endif() | |
| set(_rid "${_rid_os}-${_rid_arch}") |
| file(DOWNLOAD "${_nupkg_url}" "${_download_path}" | ||
| STATUS _dl_status | ||
| TLS_VERIFY ON | ||
| ) |
There was a problem hiding this comment.
The NuGet .nupkg download is not integrity-checked (no EXPECTED_HASH). Even with TLS, this increases supply-chain risk and can allow corrupted partial downloads to be reused because you skip re-download when the file exists. Add hash verification (e.g., SHA512 from the NuGet registration metadata) or otherwise validate downloads before extraction.
| | `gtest` | Google Test (unit and E2E tests only) | | ||
|
|
There was a problem hiding this comment.
gtest is documented as a vcpkg-resolved build dependency, but sdk/cpp/vcpkg.json removes gtest and sdk/cpp/CMakeLists.txt now fetches GoogleTest via FetchContent. Update the README to reflect the new source of GoogleTest (and any resulting network requirements), or revert to vcpkg-provided gtest to match the documentation.
| | `gtest` | Google Test (unit and E2E tests only) | | |
| GoogleTest is used only for unit and E2E tests and is fetched by CMake during configuration rather than being provided by vcpkg. If you enable or build tests, CMake must be able to access the network to download GoogleTest unless it has already been cached by your build environment. |
| // Licensed under the MIT License. | ||
| // | ||
| // Core DLL interop � loads Microsoft.AI.Foundry.Local.Core.dll at runtime. | ||
| // Core DLL interop � loads Microsoft.AI.Foundry.Local.Core.dll at runtime. |
There was a problem hiding this comment.
The comment contains a mojibake/invalid character (�), which is likely an encoding artifact. Replace it with a standard hyphen/dash so the comment renders correctly in all editors (e.g., // Core DLL interop — loads ...).
| // Core DLL interop � loads Microsoft.AI.Foundry.Local.Core.dll at runtime. | |
| // Core DLL interop - loads Microsoft.AI.Foundry.Local.Core.dll at runtime. |
No description provided.