Skip to content

[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
masterfrom
upstream-changes-2026-05-04
Open

[UPSTREAM CHANGES] latest changes as of Mon May 04 2026 01:03:21 GMT+0000 (Coordinated Universal Time)#227
github-actions[bot] wants to merge 5474 commits into
masterfrom
upstream-changes-2026-05-04

Conversation

@github-actions

@github-actions github-actions Bot commented May 4, 2026

Copy link
Copy Markdown

This PR is auto-generated by
actions/github-script.

bufke and others added 30 commits March 24, 2026 20:26
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
bufke and others added 30 commits April 23, 2026 14:52
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
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.

7 participants