Skip to content

ref(api): promote Telemetry Experience release endpoints to spectacular public docs (sentry-api-schema#76)#118005

Open
betegon wants to merge 5 commits into
masterfrom
api/promote-org-release-commits-docs
Open

ref(api): promote Telemetry Experience release endpoints to spectacular public docs (sentry-api-schema#76)#118005
betegon wants to merge 5 commits into
masterfrom
api/promote-org-release-commits-docs

Conversation

@betegon

@betegon betegon commented Jun 18, 2026

Copy link
Copy Markdown
Member

What

Migrates all of Telemetry Experience's release endpoints off the legacy hand-maintained api-docs/ system onto drf-spectacular @extend_schema decorators — so their public docs entries get clean token operationIds + summarys (instead of the legacy sentence operationIds with no summary). Pilot + full team sweep for getsentry/sentry-api-schema#76.

14 operations across 7 source files / 7 legacy files:

Path methods tokens
…/releases/ GET, POST listOrganizationReleases, createOrganizationRelease
…/releases/{version}/files/ GET, POST listOrganizationReleaseFiles, uploadOrganizationReleaseFile
…/releases/{version}/files/{file_id}/ GET, PUT, DELETE get/update/deleteOrganizationReleaseFile
…/releases/{version}/commits/ GET listOrganizationReleaseCommits
…/projects/…/releases/{version}/commits/ GET listProjectReleaseCommits
…/projects/…/releases/{version}/files/ GET, POST listProjectReleaseFiles, uploadProjectReleaseFile
…/projects/…/releases/{version}/files/{file_id}/ GET, PUT, DELETE get/update/deleteProjectReleaseFile

For each op: flip publish_statusPUBLIC so the decorator drives the spec, and delete the legacy api-docs/paths/releases/*.json file + its $ref in api-docs/openapi.json.

Decorator-parity work surfaced by the build

Promoting to PUBLIC turns on the spec-completeness checks, which required:

  • 4 list/update file ops still had sentence operation_ids → tokens + summaries
  • createOrganizationRelease's request body fields (projects, headCommits, refs) needed help_text descriptions
  • the two file delete()s needed Response[None] (PUBLIC endpoints can't use bare Response)

Slug preservation

Each summary equals the endpoint's old legacy operationId verbatim, so slugify(summary || operationId) is unchanged — no docs-URL/SEO breakage.

Verification

make build-deprecated-docs + sentry django spectacular --validate --fail-on-warn:

  • all 14 ops emit token operationId + summary
  • 216 public ops total (unchanged) — nothing added or lost, just relocated source-of-truth
  • operationIds unique across src/sentry

Scope notes / sign-off

This promotes these endpoints to officially PUBLIC (a public-API stability commitment) — but they're already de-facto public via the legacy docs, so this aligns source with reality. Flagging @getsentry/telemetry-experience as owner.

Excluded: the commitfiles endpoint (owned by Issues, and has no decorator yet) and deploys (unowned, already de-listed). Those are tracked in the issue for their owners.


Old → new doc parity (no regression)

Verified each op's old legacy api-docs/ definition against the new decorator output in the generated spec. Nothing dropped on any of the 14 — params/responses are a strict superset (the decorators document params and error codes the legacy files omitted).

Method · path Params dropped Params added Resp codes added Body kept Verdict
GET …/releases/ environment n/a
POST …/releases/ 208, 401
GET …/releases/{version}/files/ checksum, query 401 n/a
POST …/releases/{version}/files/ 400, 401, 409
GET …/releases/{version}/files/{file_id}/ 401 n/a
PUT …/releases/{version}/files/{file_id}/ 400, 401
DELETE …/releases/{version}/files/{file_id}/ 401 n/a
GET …/releases/{version}/commits/ 401 n/a
GET …/projects/…/releases/{version}/commits/ 401 n/a
GET …/projects/…/releases/{version}/files/ checksum, query 401 n/a
POST …/projects/…/releases/{version}/files/ 400, 401, 409
GET …/projects/…/releases/{version}/files/{file_id}/ 401 n/a
PUT …/projects/…/releases/{version}/files/{file_id}/ 400, 401
DELETE …/projects/…/releases/{version}/files/{file_id}/ 401 n/a

Notes:

  • These endpoints were already public (in openapi-derefed.json / @sentry/api); this only relocates the source of truth from the legacy file to the decorator. No new exposure.
  • Each summary equals the old legacy operationId verbatim → docs slug (slugify(summary || operationId)) is byte-identical → same docs URL, no SEO/link change.
  • publish_status is documentation-only (read solely by the apidocs spec generator) — no access, permission, or runtime-behavior change.
  • One intentional shape change: release-commits responses now declare the full CommitSerializerResponse instead of the legacy trimmed MinimalCommit — an accuracy improvement (the endpoint always returned the full serializer).

Pilot for getsentry/sentry-api-schema#76. This endpoint was documented
publicly only via the legacy hand-maintained api-docs/ spec (sentence
operationId, no summary), while its source method was PRIVATE and already
carried a fully-migrated @extend_schema (token operation_id + summary +
params + typed responses + examples).

- flip GET publish_status PRIVATE -> PUBLIC so the decorator drives the spec
- delete the legacy api-docs/paths/releases/organization-release-commits.json
  and its $ref in api-docs/openapi.json

Generated spec now emits operationId=listOrganizationReleaseCommits +
summary='List an Organization Release's Commits' (was the sentence with no
summary). summary == old operationId, so the docs slug is unchanged.
@github-actions github-actions Bot added the Scope: Backend Automatically applied to PRs that change backend components label Jun 18, 2026
… spectacular public docs

Migrates the rest of the team's release endpoints off the legacy
hand-maintained api-docs/ system onto drf-spectacular decorators (13 ops
across 6 files), completing the set started by the org-release-commits pilot.

For each: flip publish_status -> PUBLIC so the decorator drives the spec,
and delete the legacy api-docs path file + its $ref. Decorator parity work
surfaced by the build:
- list/update release-file ops still had sentence operation_ids -> tokens
  + summaries
- createOrganizationRelease body fields (projects/headCommits/refs) needed
  help_text descriptions
- the two file delete()s needed Response[None] (PUBLIC endpoints can't use
  bare Response)

Summaries equal the old legacy operationIds, so docs slugs are unchanged.
Verified: spectacular --validate --fail-on-warn passes; all 14 release ops
emit token operationIds; 216 public ops total (unchanged); ids unique.
Excludes commitfiles (owned by Issues) and deploys (unowned).
@betegon betegon changed the title ref(api): promote org release commits to spectacular public docs (pilot for sentry-api-schema#76) ref(api): promote Telemetry Experience release endpoints to spectacular public docs (sentry-api-schema#76) Jun 18, 2026
betegon added 3 commits June 18, 2026 12:51
…motion

The api docs endpoint tests validate real responses against the (now stricter,
decorator-driven) schemas, exposing two inaccuracies the loose legacy schemas
had masked:

- CommitSerializer emits author={} for authorless commits, but
  CommitSerializerResponse.author only allowed a populated Author. Allow an
  EmptyAuthor ({}) alongside Author so the published schema matches reality.
- The release-file upload apidocs tests forced SERVER_NAME=us.sentry.io, which
  only matched the legacy POST's operation-level region server. The endpoint now
  uses the standard global server (still region-templated), so drop the forced
  host to match every other endpoint test.

Verified: spectacular --validate --fail-on-warn clean; the 4 previously-failing
ops pass; full releases apidocs suite (19) + commit-consumer tests (4) green.
…sponse

The release-commits endpoints serialize via the Commit registry, where
CommitWithReleaseSerializer wins — so the response includes a 'releases'
field that the declared CommitSerializerResponse omitted. The api docs tests
didn't catch it because OpenAPI response validation ignores undeclared extra
fields.

- declare list[CommitSerializerResponseWithReleases] on both release-commits
  endpoints so 'releases' is part of the published contract
- make CommitReleaseSerializerResponse.ref/url/dateReleased nullable to match
  what the serializer actually returns (None for releases without them)
- give the apidocs tests one authored + one authorless commit so both the
  populated-author and empty-author ({}) shapes are actually validated

Verified: spectacular --validate --fail-on-warn clean; releases apidocs suite
(19) + commit-consumer tests (4) green.
The release-commits response now declares CommitSerializerResponseWithReleases
(releases required), so the LIST_RELEASE_COMMITS example needs a releases entry
or openapi-examples-validator (validate-api-examples / api docs test) fails with
'must have required property releases'.

Verified: validate-api-examples reports no errors; releases apidocs suite (19) green.
@betegon betegon marked this pull request as ready for review June 18, 2026 14:11
@betegon betegon requested review from a team as code owners June 18, 2026 14:11
@vgrozdanic

Copy link
Copy Markdown
Member

Why are we making all of these public?

I have too little context on these endpoints to even tell if they are ready to be public and if we are ready to commit to maintaining them and not breaking them. Keeping them private gives us that freedom, but once they are public, it's way harder to do work on them

betegon commented Jun 18, 2026

Copy link
Copy Markdown
Member Author

@vgrozdanic Heyaaa! i know you're travelling that's why i didn't bother you (yet). from my understanding:

  1. these endpoints (and some others) are using our old way of publishing to the openapi schema
  2. there isn't a public entity in there, but all of them are being published to our openapi schema, api reference docs, etc. This technically means they are already public-facing, just via the legacy mechanism.

so basically, this PR moves them to our new convention.

betegon commented Jun 18, 2026

Copy link
Copy Markdown
Member Author

maybe we can loop someone else that has more context on this?

to be clear we don't need this PR for our work on @sentry/api, as all of these endpoints are already public and being used in places like the MCP.

I just saw an opportunity to standardize our API surface

betegon commented Jun 18, 2026

Copy link
Copy Markdown
Member Author

example of them being already published https://docs.sentry.io/api/releases/list-an-organizations-releases/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Scope: Backend Automatically applied to PRs that change backend components

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants