From 5fc07aa391a3854b61703269418e18784ff5ad36 Mon Sep 17 00:00:00 2001 From: Greg Huels Date: Fri, 21 Nov 2025 11:00:30 -0600 Subject: [PATCH 1/3] chore: do not run performance tests with "make test" --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 92049a1..5da3e1d 100644 --- a/Makefile +++ b/Makefile @@ -97,8 +97,8 @@ test: test-data rm -f compile_commands.json ./scripts/generate_compile_commands.sh @$(MAKE) $(TEST_EXECUTABLE) - @echo "Running all tests..." - @./$(TEST_EXECUTABLE) + @echo "Running all tests (excluding performance tests)..." + @./$(TEST_EXECUTABLE) "~[performance]" # Clean build artifacts .PHONY: clean From 7c826aa27bff3d75b549e55d5e8ae39e648b9780 Mon Sep 17 00:00:00 2001 From: Greg Huels Date: Tue, 25 Nov 2025 12:01:29 -0600 Subject: [PATCH 2/3] chore: centralize version and remove version consistency checks --- .github/workflows/test.yml | 5 +-- scripts/check-version-consistency.sh | 51 ---------------------------- src/version.hpp | 7 +++- 3 files changed, 7 insertions(+), 56 deletions(-) delete mode 100755 scripts/check-version-consistency.sh diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 3ccd34a..c82d71b 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -17,7 +17,7 @@ on: sdk_branch: type: string description: The branch of the SDK to test - required: false + required: false env: SDK_BRANCH_NAME: ${{ inputs.sdk_branch || github.head_ref || github.ref_name || 'main' }} @@ -90,9 +90,6 @@ jobs: with: repository: ${{ github.event.pull_request.head.repo.full_name || 'Eppo-exp/cpp-sdk' }} ref: ${{ env.SDK_BRANCH_NAME }} - - - name: Verify version consistency - run: ./scripts/check-version-consistency.sh - name: Set up build environment run: | diff --git a/scripts/check-version-consistency.sh b/scripts/check-version-consistency.sh deleted file mode 100755 index 942834e..0000000 --- a/scripts/check-version-consistency.sh +++ /dev/null @@ -1,51 +0,0 @@ -#!/bin/bash -# Verify that EPPOCLIENT_VERSION matches the component versions -# (EPPOCLIENT_VERSION_MAJOR.MINOR.PATCH) -# Treats EPPOCLIENT_VERSION as the source of truth. - -set -e - -VERSION_FILE="${1:-src/version.hpp}" - -if [ ! -f "$VERSION_FILE" ]; then - echo "❌ ERROR: Version file not found: $VERSION_FILE" - exit 1 -fi - -# Extract version components from version.hpp -MAJOR=$(grep '#define EPPOCLIENT_VERSION_MAJOR' "$VERSION_FILE" | awk '{print $3}') -MINOR=$(grep '#define EPPOCLIENT_VERSION_MINOR' "$VERSION_FILE" | awk '{print $3}') -PATCH=$(grep '#define EPPOCLIENT_VERSION_PATCH' "$VERSION_FILE" | awk '{print $3}') -VERSION=$(grep '#define EPPOCLIENT_VERSION ' "$VERSION_FILE" | awk '{print $3}' | tr -d '"') - -# Parse VERSION string into expected components -IFS='.' read -r EXPECTED_MAJOR EXPECTED_MINOR EXPECTED_PATCH <<< "$VERSION" - -echo "EPPOCLIENT_VERSION: $VERSION" -echo "Component versions: MAJOR=$MAJOR, MINOR=$MINOR, PATCH=$PATCH" - -# Check for mismatches -MISMATCHES=() -if [ "$MAJOR" != "$EXPECTED_MAJOR" ]; then - MISMATCHES+=("EPPOCLIENT_VERSION_MAJOR is $MAJOR but should be $EXPECTED_MAJOR") -fi -if [ "$MINOR" != "$EXPECTED_MINOR" ]; then - MISMATCHES+=("EPPOCLIENT_VERSION_MINOR is $MINOR but should be $EXPECTED_MINOR") -fi -if [ "$PATCH" != "$EXPECTED_PATCH" ]; then - MISMATCHES+=("EPPOCLIENT_VERSION_PATCH is $PATCH but should be $EXPECTED_PATCH") -fi - -# Report results -if [ ${#MISMATCHES[@]} -gt 0 ]; then - echo "" - echo "❌ ERROR: Version component mismatch!" - for mismatch in "${MISMATCHES[@]}"; do - echo " - $mismatch" - done - echo "" - echo "Please update the component version(s) in $VERSION_FILE to match EPPOCLIENT_VERSION." - exit 1 -fi - -echo "✅ Version consistency check passed!" diff --git a/src/version.hpp b/src/version.hpp index 234a2b4..5b8c56c 100644 --- a/src/version.hpp +++ b/src/version.hpp @@ -4,7 +4,12 @@ #define EPPOCLIENT_VERSION_MAJOR 1 #define EPPOCLIENT_VERSION_MINOR 0 #define EPPOCLIENT_VERSION_PATCH 0 -#define EPPOCLIENT_VERSION "1.0.0" + +#define STRINGIFY(x) #x +#define TOSTRING(x) STRINGIFY(x) +#define EPPOCLIENT_VERSION \ + TOSTRING(EPPOCLIENT_VERSION_MAJOR) \ + "." TOSTRING(EPPOCLIENT_VERSION_MINOR) "." TOSTRING(EPPOCLIENT_VERSION_PATCH) namespace eppoclient { From c4888ad9b6949f47ee260854f80968b90ec32892 Mon Sep 17 00:00:00 2001 From: Greg Huels Date: Fri, 21 Nov 2025 11:10:42 -0600 Subject: [PATCH 3/3] Release v2.0.0 --- CHANGELOG.md | 29 ++++++++++++++++++++++++++--- src/version.hpp | 2 +- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 632b3a8..a3d2301 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,16 +5,39 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [Unreleased] +## [2.0.0] ### Changed - **BREAKING**: `ConfigurationStore::getConfiguration()` now returns `std::shared_ptr` instead of `Configuration` by value - Returns an empty configuration when no configuration is set (graceful behavior, no null checks required) - - Eliminates expensive configuration copies on every flag evaluation - - Provides thread-safe reference counting via `std::shared_ptr` - Configuration is immutable (`const`) once retrieved - Update your code: use `->` instead of `.` to access configuration methods (no null checks needed) +- **BREAKING**: All error handling is now done through logging and returning default values +- **BREAKING**: Removed `setIsGracefulFailureMode()` method - SDK always operates in "graceful" mode +- **BREAKING**: Removed custom exception classes (`FlagConfigurationNotFoundException`, `FlagNotEnabledException`, `SubjectAllocationException`) +- **BREAKING**: `EppoClient` constructor now takes `ConfigurationStore&` by reference instead of `std::shared_ptr`, allowing SDK consumers to choose their own synchronization strategy +- SDK now builds with `-fno-exceptions` and does not use exceptions internally +- Configured nlohmann/json with `JSON_NOEXCEPTION` to eliminate JSON parsing exceptions +- Constructor preconditions (null checks, size validations) now use `assert()` instead of throwing exceptions +- Internal functions now return `std::optional` or error codes instead of throwing exceptions + +### Added + +- Full compatibility with `-fno-exceptions` projects +- Documentation on error handling and constructor preconditions + +### Migration Guide + +If you were using v1.0.0: + +1. Remove all `try-catch` blocks around SDK method calls - they no longer throw +2. Remove calls to `setIsGracefulFailureMode()` - this method no longer exists +3. Update `EppoClient` instantiation - pass `ConfigurationStore` by reference instead of as `shared_ptr`: + - Before: `auto client = std::make_shared(configStorePtr);` + - After: `EppoClient client(configStore);` (ensure `configStore` outlives `client`) +4. Ensure constructor preconditions are met (non-null loggers, positive cache sizes) +5. Monitor errors through the `ApplicationLogger` interface instead of catching exceptions ## [1.0.0] - 2025-11-14 diff --git a/src/version.hpp b/src/version.hpp index 5b8c56c..f76f716 100644 --- a/src/version.hpp +++ b/src/version.hpp @@ -1,7 +1,7 @@ #ifndef EPPOCLIENT_VERSION_HPP #define EPPOCLIENT_VERSION_HPP -#define EPPOCLIENT_VERSION_MAJOR 1 +#define EPPOCLIENT_VERSION_MAJOR 2 #define EPPOCLIENT_VERSION_MINOR 0 #define EPPOCLIENT_VERSION_PATCH 0