Skip to content

feat: send $release_id from POSTHOG_RELEASE_ID on every event - #277

Open
ablaszkiewicz wants to merge 1 commit into
mainfrom
feat/release-id-env
Open

ablaszkiewicz wants to merge 1 commit into
mainfrom
feat/release-id-env

Conversation

@ablaszkiewicz

@ablaszkiewicz ablaszkiewicz commented Sep 23, 2026

Copy link
Copy Markdown
Contributor

💡 Motivation and Context

A Ruby app cannot link its error tracking issues to a release. posthog-cli injects the release id into JavaScript bundles, and a Ruby app has no build step to inject into. This is the Ruby counterpart of posthog-python#975.

  • The client reads POSTHOG_RELEASE_ID (the id that posthog-cli release resolve prints) and sends it as $release_id on every event.
  • On $exception events the server resolves the release by a direct id lookup.
  • The value is read once, when the client is created. It is trimmed, and a blank value counts as unset.
  • The id is added in Client#enqueue, the one path that capture, capture_exception, identify, group_identify and alias share. before_send runs after it, so it can still change or remove the id.
  • An explicit $release_id in the event properties or the request context wins over the env var.
  • It stays out of $set and $group_set, so it never becomes a person or group property.

💚 How did you test it?

  • 14 new specs: one per event type, person and group properties, explicit string and symbol keys, before_send, trimming, blank and unset values, and minimal $feature_flag_called events.
  • Without the lib/ change, 7 of them fail: the five event types, trimming and the minimal event. The others guard against overriding or leaking the id.
  • bundle exec rspec (1215 passed) and bundle exec rake public_api:check pass. bundle exec rubocop reports no offense in the changed files.
  • End to end against a local PostHog stack: a gem built from this branch, a release from a locally built posthog-cli release resolve, one handled exception, and one plain event. Both events carried $release_id, and the server resolved ruby-release-env@1.0.0 from it. Not tested against production.

The issue page resolves the release that the CLI created:

ruby-release-issue

The event JSON, filtered to release, shows the $release_id that the SDK sent and the $exception_release that the server resolved from it (same id):

ruby-release-json

📝 Checklist

  • I reviewed the submitted code.
  • I added tests to verify the changes.
  • I updated the docs if needed.
  • No breaking change or entry added to the changelog.

If releasing new changes

  • Ran pnpm changeset to generate a changeset file

🤖 Agent context

Autonomy: Human-driven (agent-assisted)

Written with Claude Code (Claude Opus 5.5), directed by the PR assignee.

  • The behavior follows posthog-python#975, which the assignee reviewed. The deployment side for PostHog's own app is PostHog/posthog#104420.
  • The assignee asked for the id on all events, so minimal $feature_flag_called events carry it too. That is the one difference from Python.
  • One hook in enqueue was chosen over one per public method, so a new event type cannot miss it.
  • The changeset file was written by hand, not with the pnpm changeset command.

🤖 Generated with Claude Code

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@ablaszkiewicz ablaszkiewicz self-assigned this Sep 23, 2026
@github-actions

Copy link
Copy Markdown

posthog-ruby-sync Compliance Report

Date: 2026-09-23T08:34:40.240734+00:00
Duration: 93923ms

⚠️ Some Tests Failed

45/47 tests passed, 2 failed


Capture Tests

⚠️ 29/30 tests passed, 1 failed

View Details
Test Status Duration
Format Validation.Event Has Required Fields 9ms
Format Validation.Event Has Uuid 7ms
Format Validation.Event Has Lib Properties 6ms
Format Validation.Distinct Id Is String 8ms
Format Validation.Token Is Present 5ms
Format Validation.Custom Properties Preserved 6ms
Format Validation.Event Has Timestamp 5ms
Format Validation.Non Utc Event Timestamp Is Converted To Utc 6ms
Retry Behavior.Retries On 503 5267ms
Retry Behavior.Does Not Retry On 400 2011ms
Retry Behavior.Does Not Retry On 401 2010ms
Retry Behavior.Respects Retry After Header 8017ms
Retry Behavior.Implements Backoff 15254ms
Retry Behavior.Retries On 500 5114ms
Retry Behavior.Retries On 502 5151ms
Retry Behavior.Retries On 504 5113ms
Retry Behavior.Max Retries Respected 15477ms
Deduplication.Generates Unique Uuids 18ms
Deduplication.Preserves Uuid On Retry 5155ms
Deduplication.Preserves Uuid And Timestamp On Retry 10318ms
Deduplication.Preserves Uuid And Timestamp On Batch Retry 5121ms
Deduplication.No Duplicate Events In Batch 17ms
Deduplication.Different Events Have Different Uuids 9ms
Compression.Sends Gzip When Enabled 5ms
Batch Format.Uses Proper Batch Structure 5ms
Batch Format.Flush With No Events Sends Nothing 3ms
Batch Format.Multiple Events Batched Together 19ms
Error Handling.Does Not Retry On 403 2009ms
Error Handling.Does Not Retry On 413 2010ms
Error Handling.Retries On 408 5165ms

Failures

batch_format.multiple_events_batched_together

Expected 1 requests, got 5

Feature_Flags Tests

⚠️ 16/17 tests passed, 1 failed

View Details
Test Status Duration
Request Payload.Request With Person Properties Device Id 9ms
Request Payload.Flags Request Uses V2 Query Param 6ms
Request Payload.Flags Request Hits Flags Path Not Decide 6ms
Request Payload.Flags Request Omits Authorization Header 6ms
Request Payload.Token In Flags Body Matches Init 6ms
Request Payload.Groups Round Trip 6ms
Request Payload.Groups Default To Empty Object 6ms
Request Payload.Disable Geoip False Propagates As Geoip Disable False 6ms
Request Payload.Disable Geoip Omitted Defaults To False 7ms
Request Payload.Flag Keys To Evaluate Contains Only Requested Key 6ms
Request Lifecycle.No Flags Request On Init Alone 2ms
Request Lifecycle.No Flags Request On Normal Capture 5ms
Request Lifecycle.Two Flag Calls Produce Two Remote Requests 9ms
Request Lifecycle.Mock Response Value Is Returned To Caller 6ms
Retry Behavior.Retries Flags On 502 148ms
Retry Behavior.Retries Flags On 504 137ms
Side Effect Events.Get Feature Flag Captures Feature Flag Called Event 9ms

Failures

request_payload.disable_geoip_omitted_defaults_to_false

Field 'geoip_disable' not found in /flags request body at path 'geoip_disable'. Available keys: ['distinct_id', 'groups', 'person_properties', 'group_properties', 'flag_keys_to_evaluate', 'token']

@github-actions

Copy link
Copy Markdown

posthog-ruby-async Compliance Report

Date: 2026-09-23T08:34:54.941347+00:00
Duration: 98390ms

⚠️ Some Tests Failed

46/47 tests passed, 1 failed


Capture Tests

30/30 tests passed

View Details
Test Status Duration
Format Validation.Event Has Required Fields 107ms
Format Validation.Event Has Uuid 106ms
Format Validation.Event Has Lib Properties 108ms
Format Validation.Distinct Id Is String 107ms
Format Validation.Token Is Present 106ms
Format Validation.Custom Properties Preserved 107ms
Format Validation.Event Has Timestamp 106ms
Format Validation.Non Utc Event Timestamp Is Converted To Utc 7ms
Retry Behavior.Retries On 503 5311ms
Retry Behavior.Does Not Retry On 400 2110ms
Retry Behavior.Does Not Retry On 401 2110ms
Retry Behavior.Respects Retry After Header 8117ms
Retry Behavior.Implements Backoff 15523ms
Retry Behavior.Retries On 500 5212ms
Retry Behavior.Retries On 502 5211ms
Retry Behavior.Retries On 504 5212ms
Retry Behavior.Max Retries Respected 15623ms
Deduplication.Generates Unique Uuids 114ms
Deduplication.Preserves Uuid On Retry 5211ms
Deduplication.Preserves Uuid And Timestamp On Retry 10417ms
Deduplication.Preserves Uuid And Timestamp On Batch Retry 5215ms
Deduplication.No Duplicate Events In Batch 111ms
Deduplication.Different Events Have Different Uuids 108ms
Compression.Sends Gzip When Enabled 107ms
Batch Format.Uses Proper Batch Structure 107ms
Batch Format.Flush With No Events Sends Nothing 4ms
Batch Format.Multiple Events Batched Together 114ms
Error Handling.Does Not Retry On 403 2108ms
Error Handling.Does Not Retry On 413 2109ms
Error Handling.Retries On 408 5211ms

Feature_Flags Tests

⚠️ 16/17 tests passed, 1 failed

View Details
Test Status Duration
Request Payload.Request With Person Properties Device Id 108ms
Request Payload.Flags Request Uses V2 Query Param 106ms
Request Payload.Flags Request Hits Flags Path Not Decide 106ms
Request Payload.Flags Request Omits Authorization Header 107ms
Request Payload.Token In Flags Body Matches Init 108ms
Request Payload.Groups Round Trip 106ms
Request Payload.Groups Default To Empty Object 106ms
Request Payload.Disable Geoip False Propagates As Geoip Disable False 107ms
Request Payload.Disable Geoip Omitted Defaults To False 107ms
Request Payload.Flag Keys To Evaluate Contains Only Requested Key 106ms
Request Lifecycle.No Flags Request On Init Alone 3ms
Request Lifecycle.No Flags Request On Normal Capture 106ms
Request Lifecycle.Two Flag Calls Produce Two Remote Requests 112ms
Request Lifecycle.Mock Response Value Is Returned To Caller 108ms
Retry Behavior.Retries Flags On 502 209ms
Retry Behavior.Retries Flags On 504 244ms
Side Effect Events.Get Feature Flag Captures Feature Flag Called Event 108ms

Failures

request_payload.disable_geoip_omitted_defaults_to_false

Field 'geoip_disable' not found in /flags request body at path 'geoip_disable'. Available keys: ['distinct_id', 'groups', 'person_properties', 'group_properties', 'flag_keys_to_evaluate', 'token']

@greptile-apps

greptile-apps Bot commented Sep 23, 2026

Copy link
Copy Markdown
Contributor

Retrigger

The PR appears safe to merge with no actionable correctness, security, or repository-rule violations identified.

Reviews (1) · Last reviewed commit: "feat: send $release_id from POSTHOG_RELE..."

@posthog

posthog Bot commented Sep 23, 2026

Copy link
Copy Markdown

🦔 PostHog Review reviewed this pull request

Nothing worth raising this time, so here's a calming picture instead:

A panda relaxing and waving

This branch has not been deployed

No deployments
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.

1 participant