Skip to content

feat(flags): add semver targeting to local evaluation#86

Closed
dmarticus wants to merge 1 commit intomasterfrom
feat/semver-targeting
Closed

feat(flags): add semver targeting to local evaluation#86
dmarticus wants to merge 1 commit intomasterfrom
feat/semver-targeting

Conversation

@dmarticus
Copy link
Contributor

@dmarticus dmarticus commented Mar 2, 2026

Summary

  • Add semantic versioning (semver) property matching for local feature flag evaluation with 9 new operators:
    • Comparison operators: semver_eq, semver_neq, semver_gt, semver_gte, semver_lt, semver_lte
    • Range operators: semver_tilde (~1.2.3), semver_caret (^1.2.3), semver_wildcard (1.2.*)
  • Implement robust semver parsing that handles:
    • v/V prefix stripping (e.g., "v1.2.3" → {1, 2, 3})
    • Pre-release and build metadata stripping (e.g., "1.2.3-alpha+build" → {1, 2, 3})
    • Missing components defaulting to 0 (e.g., "1.2" → {1, 2, 0})
    • Leading zeros and 4-part versions
  • Add comprehensive PropertyMatcher module (lib/posthog/feature_flags/property_matcher.ex) that also includes equality, string, numeric, and date operators for complete local flag evaluation support
  • Include 738 lines of tests covering all operators, edge cases, and error handling

This aligns the Elixir SDK with the semver targeting feature available in other PostHog SDKs:

Test plan

  • All new tests pass (mix test test/posthog/feature_flags/property_matcher_test.exs)
  • Tests cover all 9 semver operators with valid inputs
  • Tests verify semver parsing edge cases:
    • v/V prefix handling
    • Pre-release/build metadata stripping
    • Partial versions (1.2, 1)
    • 4-part versions (1.2.3.4)
    • Leading zeros (01.02.03)
    • Whitespace trimming
  • Tests verify range operator bounds:
    • Tilde: ~1.2.3 matches >=1.2.3 <1.3.0
    • Caret: ^1.2.3 matches >=1.2.3 <2.0.0, with special handling for 0.x versions
    • Wildcard: 1.2.* matches >=1.2.0 <1.3.0
  • Tests verify error handling:
    • Invalid semver formats raise InconclusiveMatchError
    • Missing property keys raise InconclusiveMatchError
    • Unknown operators raise InconclusiveMatchError
    • Null property values return false
  • Existing tests continue to pass (mix test)

@github-actions
Copy link
Contributor

github-actions bot commented Mar 2, 2026

posthog-elixir Compliance Report

Date: 2026-03-02 22:09:31 UTC
Duration: 105882ms

✅ All Tests Passed!

29/29 tests passed


Capture Tests

29/29 tests passed

View Details
Test Status Duration
Format Validation.Event Has Required Fields 609ms
Format Validation.Event Has Uuid 611ms
Format Validation.Event Has Lib Properties 610ms
Format Validation.Distinct Id Is String 611ms
Format Validation.Token Is Present 610ms
Format Validation.Custom Properties Preserved 610ms
Format Validation.Event Has Timestamp 611ms
Retry Behavior.Retries On 503 5612ms
Retry Behavior.Does Not Retry On 400 2614ms
Retry Behavior.Does Not Retry On 401 2613ms
Retry Behavior.Respects Retry After Header 5616ms
Retry Behavior.Implements Backoff 15626ms
Retry Behavior.Retries On 500 5614ms
Retry Behavior.Retries On 502 5615ms
Retry Behavior.Retries On 504 5616ms
Retry Behavior.Max Retries Respected 15624ms
Deduplication.Generates Unique Uuids 624ms
Deduplication.Preserves Uuid On Retry 5616ms
Deduplication.Preserves Uuid And Timestamp On Retry 10611ms
Deduplication.Preserves Uuid And Timestamp On Batch Retry 5618ms
Deduplication.No Duplicate Events In Batch 617ms
Deduplication.Different Events Have Different Uuids 613ms
Compression.Sends Gzip When Enabled 609ms
Batch Format.Uses Proper Batch Structure 609ms
Batch Format.Flush With No Events Sends Nothing 607ms
Batch Format.Multiple Events Batched Together 615ms
Error Handling.Does Not Retry On 403 2612ms
Error Handling.Does Not Retry On 413 2612ms
Error Handling.Retries On 408 5616ms

Copy link
Member

@rafaeelaudibert rafaeelaudibert left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dmarticus Ahn, I don't think there's local evaluation in Elixir yet? So... this is moot?

You're literally defining the module, but it's not connected in any way or form to the actual SDK. Local evaluation in Elixir is very tricky because we can make it work very well with the Erlang machine, but we haven't built that yet

@dmarticus
Copy link
Contributor Author

ope, didn't realize. Will nuke.

@dmarticus dmarticus closed this Mar 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants