[UPSTREAM CHANGES] latest changes as of Mon May 04 2026 01:03:21 GMT+0000 (Coordinated Universal Time) - #227
Open
github-actions[bot] wants to merge 5474 commits into
Open
[UPSTREAM CHANGES] latest changes as of
Mon May 04 2026 01:03:21 GMT+0000 (Coordinated Universal Time)#227github-actions[bot] wants to merge 5474 commits into
github-actions[bot] wants to merge 5474 commits into
Conversation
fix: drop issue_id FK constraints on partitioned tables See merge request glitchtip/glitchtip-backend!2230
Previously, assemble_artifacts() raised AssembleArtifactsError on validation failures (bad zip, missing manifest, org/release mismatch, path traversal). This left the assemble status stuck at ASSEMBLING, causing client SDKs to retry indefinitely — observed as 1,200+ repeat errors from a single organization uploading a non-zip file. Now all error paths set ChunkFileState.ERROR with a descriptive detail message, clean up temp resources (including any File objects already created during artifact processing), and return gracefully. Bare except clauses log warnings with exc_info for diagnostics. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
chore(deps): update dependency boto3 to v1.42.75 See merge request glitchtip/glitchtip-backend!2233
chore(deps): update dependency sentry-sdk to v2.56.0 See merge request glitchtip/glitchtip-backend!2235
fix: set ERROR status on artifact assembly failures See merge request glitchtip/glitchtip-backend!2231
The create_release endpoint used acreate() which threw an IntegrityError when a release with the same (organization_id, version) already existed. Changed to aget_or_create to make the endpoint idempotent, matching the behavior of create_project_release. Fixes https://app.glitchtip.com/burke-software/issues/5534440 AI Disclosure: This commit was authored with the assistance of an AI agent. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Claude Code's MCP client does not yet support automatic OAuth token refresh (grant_type=refresh_token), so users had to re-authenticate every hour. Increase access token lifetime to 8 hours to last a full work session, matching GitHub's token lifetime. AI Disclosure: This commit was authored with the assistance of an AI agent. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
fix: increase MCP OAuth access token lifetime to 8 hours See merge request glitchtip/glitchtip-backend!2237
chore(deps): update dependency boto3 to v1.42.76 See merge request glitchtip/glitchtip-backend!2238
The monolithic `with_event_counts()` method built a single SQL statement with 5+ correlated subqueries across all partitioned tables (stats tables, MonitorCheck, debug files). This acquired locks on every partition simultaneously, exhausting PostgreSQL's shared lock table under concurrent load (OperationalError: out of shared memory). Changes: - Replace `with_event_counts()` with `get_event_counts()` that runs separate aggregate queries per table, releasing locks between queries - Add `UptimeCheckHourlyStatistic` model (weekly range-partitioned) so uptime counts use a small stats table instead of scanning all daily MonitorCheck partitions - Increment uptime stats on monitor check creation (bulk and heartbeat) - Add new table to partition maintenance and org deletion cleanup - Pass total_event_count through throttle email task instead of re-querying with annotation - Simplify admin (remove event count columns that required annotation) AI-assisted (Claude Opus 4.6) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ter' fix: handle duplicate release creation with get_or_create See merge request glitchtip/glitchtip-backend!2236
chore(deps): update dependency vulture to v2.16 See merge request glitchtip/glitchtip-backend!2239
The sample data commands now upsert hourly project statistics so the billing/subscription UI shows realistic counts in dev environments. - make_sample_issues → IssueEventProjectHourlyStatistic - make_sample_logs → LogProjectHourlyStatistic (with level/service/env buckets) - make_sample_transactions → TransactionEventProjectHourlyStatistic - Added upsert_hourly_project_stats helper to MakeSampleCommand base class Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
'admin' is too short for Django's password validation, causing login form submissions to fail. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Moved event count display from list view (N+1 problem) to detail view where we only need counts for one org. Uses get_event_counts with a per-object cache so all 6 readonly fields share one set of queries. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Remove the OrganizationSubscription proxy model and its separate admin. All subscription/billing info is now on the Organization detail page: - Event counts, max_events, customer/subscription links as readonly fields - Subscription inline (only when BILLING_ENABLED) - Billing-specific readonly fields and list filters conditional on setting Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
fix: split event count queries to prevent shared memory exhaustion See merge request glitchtip/glitchtip-backend!2240
Replace Django ORM queries with raw SQL for three high-traffic query patterns in the ingest pipeline to reduce Python overhead (Q-object tree building, SQL compilation, model instantiation): - IssueHash batch lookup: O(n) Q-object OR chain → VALUES-based tuple lookup with JOIN to issue table - TransactionGroup batch fetch: same OR chain → VALUES lookup, returning lightweight _TxnGroupRef instead of full model instances - Project annotations query: Coalesce/Exists/OuterRef annotations → explicit LEFT JOINs with ANY() array parameters AI-assisted development via Claude Code. Human review required. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Convert additional ORM queries on the ingest hot path to raw SQL: Writes (must stay sync_to_async regardless of async-backend): - IssueEvent bulk insert: ORM abulk_create → raw INSERT with Jsonb adapter, avoiding model field serialization overhead - Environment post-create fetch: Q-object OR chain → VALUES lookup - Release post-create fetch: same pattern Reads: - Tag key/value ID lookups: ORM filter → ANY() array parameter - TransactionGroup phase 2 histogram refetch: ORM .only() → raw SELECT Also adds early return in update_tags when no tags present. AI-assisted development via Claude Code. Human review required. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Long-running Python ASGI workers accumulate glibc malloc fragmentation that cannot be reclaimed. Granian's --workers-max-rss restarts workers that exceed the limit, spawning the replacement before terminating the old one so traffic is uninterrupted. Default: 50% of the cgroup memory limit (floor 1024 MiB, fallback 2048 MiB when no cgroup limit exists). Operators can override via the GRANIAN_WORKERS_MAX_RSS environment variable. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
fix: auto-set GRANIAN_WORKERS_MAX_RSS to bound memory fragmentation See merge request glitchtip/glitchtip-backend!2243
perf: convert hot-path ORM queries to raw SQL in event ingest See merge request glitchtip/glitchtip-backend!2242
check_all_organizations_throttle() used .aiterator() which creates a server-side cursor, incompatible with PgBouncer transaction pooling. Replace with keyset pagination (id__gt) in batches of 500 to keep memory bounded without requiring server-side cursors. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- wizard: setup_wizard and setup_wizard_delete now use async cache ops - api fallback 404: async to avoid unnecessary thread in ASGI - prometheus metrics: inline generate_latest instead of sync_to_async wrapping the django-prometheus view (no I/O, just CPU formatting) django-ninja uses sync Operation for sync views, which Django's ASGI handler wraps in sync_to_async — creating a thread for no reason. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
fix: convert remaining sync views to async See merge request glitchtip/glitchtip-backend!2244
fix(settings): derive cookie Secure flags from URL; warn on unsafe defaults See merge request glitchtip/glitchtip-backend!2327
chore(deps): update dependency boto3 to v1.42.95 See merge request glitchtip/glitchtip-backend!2334
chore(deps): update dependency granian to v2.7.4 See merge request glitchtip/glitchtip-backend!2335
The access-token cache is keyed by sha256(plaintext), and the paired refresh-token row already stores that same sha256 in access_token_digest. Reconstructing the cache key from the digest preserves the original revocation semantics without needing the plaintext: both exchange_refresh_token and revoke_token(RefreshToken) can again delete the paired cache entry immediately rather than waiting out ACCESS_TOKEN_LIFETIME. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
chore(deps): update dependency boto3 to v1.42.96 See merge request glitchtip/glitchtip-backend!2337
chore(deps): update dependency ruff to v0.15.12 See merge request glitchtip/glitchtip-backend!2338
chore(deps): update dependency ipython to v9.13.0 See merge request glitchtip/glitchtip-backend!2339
feat(oauth): hash refresh + access tokens at rest See merge request glitchtip/glitchtip-backend!2330
Use direct schema access when copying `exception.stacktrace` to `exception.raw_stacktrace` in the JavaScript sourcemap processor. The previous code used `get_path(...)` on the ingest schema object, so `raw_stacktrace` was never populated. Add a regression assertion for the sourcemap flow.
The public /api/0/settings/ endpoint constructs an OpenIDConnectOAuth2Adapter on every call, and django-allauth lazily fetches the provider's well-known/openid-configuration via a synchronous requests call the first time `authorize_url` is read. Even though get_settings is async, this was wrapped in sync_to_async, so each request blocked a worker thread on an outbound HTTP call to the IdP. Add a small helper that fetches the discovery document once with aiohttp and caches the JSON in the Django cache (Valkey in production), keyed by the provider's server URL. Subsequent requests read from cache and never touch the wire. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…seline Python 3.12 is the project's minimum (`requires-python = ">=3.12"`), so PEP 604 (`X | Y`) and PEP 585 (`list[X]`) syntax is native and the `from __future__ import annotations` import added in `glitchtip/oidc_discovery.py` was a no-op. Note this in AGENTS.md so future AI-drafted contributions don't reintroduce it. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
GlitchTip is async-first; the `a` prefix is only meaningful in libraries that expose parallel sync and async APIs in the same namespace (Django ORM, allauth, etc.). Rename `aget_openid_config` and `aget_authorize_url` to drop the prefix and document the convention in AGENTS.md. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
expose is_public on StripePrice for canonical-price selection See merge request glitchtip/glitchtip-backend!2342
feat: filter Stripe products by hosted product_type metadata See merge request glitchtip/glitchtip-backend!2307
perf(api): cache OIDC discovery doc instead of fetching per request See merge request glitchtip/glitchtip-backend!2344
Refactor JavaScript sourcemap processing to remap stacktraces per exception instead of flattening all frames first. This keeps `raw_stacktrace` unset when sourcemap resolution is a no-op for an exception, while still preserving the original stacktrace before the first successful frame remap.
fix: persist raw JS stacktrace before sourcemap remap See merge request glitchtip/glitchtip-backend!2340
The hosted product_type filter merged in !2307 was added at the same time !2306 introduced test_sync_product_round_trips_price_is_public. The filter MR updated test_sync_product to set product_type=hosted in metadata, but the round-trip test (developed in parallel) was missed. After both merged the new test's products were filtered out, no StripePrice rows were created, and aget(stripe_id="price_pub") raised DoesNotExist on master CI. Generated with assistance from Claude Code (Opus 4.7).
fix(stripe): add product_type=hosted to round-trip test products See merge request glitchtip/glitchtip-backend!2345
add test and test data for ios event context;
Fix ios event context v2 See merge request glitchtip/glitchtip-backend!2346
… into upstream-changes-2026-05-04
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR is auto-generated by
actions/github-script.