Skip to content

[HYPER-305] fix(pds-core): set PDS_VERSION fallback so /xrpc/_health reports version#76

Merged
aspiers merged 1 commit intomainfrom
fix/xrpc-health-pds-version
Apr 12, 2026
Merged

[HYPER-305] fix(pds-core): set PDS_VERSION fallback so /xrpc/_health reports version#76
aspiers merged 1 commit intomainfrom
fix/xrpc-health-pds-version

Conversation

@aspiers
Copy link
Copy Markdown
Contributor

@aspiers aspiers commented Apr 12, 2026

Summary

  • The vanilla @atproto/pds entrypoint does env.version ??= pkg.version to fall back to the package.json version when PDS_VERSION is unset
  • ePDS omitted this, so /xrpc/_health returned {} instead of { "version": "0.4.211" }
  • One-line fix: read @atproto/pds/package.json version and apply the same ??= fallback before envToCfg()

Note: this is the upstream PDS version on /xrpc/_health, separate from the ePDS version on /health (HYPER-304, PR #74).

Test plan

  • curl https://<pds>/xrpc/_health returns { "version": "0.4.211" } (or current @atproto/pds version)
  • /health still returns the ePDS version separately

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Chores

    • Startup now populates the app version from installed package metadata when not explicitly set.
  • New Features

    • Health endpoints now include a version field in their JSON responses (both service and upstream PDS).
  • Tests

    • Added end-to-end health checks validating presence and format of reported version strings.
  • Documentation

    • Changeset notes updated to document version reporting and audience guidance.

@vercel
Copy link
Copy Markdown

vercel bot commented Apr 12, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
epds-demo Ready Ready Preview, Comment Apr 12, 2026 8:02pm

Request Review

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 12, 2026

Warning

Rate limit exceeded

@aspiers has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 10 minutes and 11 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 10 minutes and 11 seconds.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 9c8acab3-8b5a-4730-aa30-44414decdf6d

📥 Commits

Reviewing files that changed from the base of the PR and between fd44f43 and f709066.

📒 Files selected for processing (6)
  • .changeset/version-health-endpoint.md
  • .changeset/xrpc-health-pds-version.md
  • e2e/cucumber.mjs
  • e2e/step-definitions/health.steps.ts
  • features/health.feature
  • packages/pds-core/src/index.ts
📝 Walkthrough

Walkthrough

Load the installed @atproto/pds package.json at startup to populate the PDS upstream version and use it to set env.version when unset. Add changesets documenting the /health and /xrpc/_health version behavior and introduce end-to-end Cucumber tests validating both ePDS and upstream PDS version fields.

Changes

Cohort / File(s) Summary
Core startup change
packages/pds-core/src/index.ts
Read @atproto/pds/package.json at startup and set env.version with atprotoPdsPkg.version when env.version is not already defined.
Health feature tests
e2e/cucumber.mjs, e2e/step-definitions/health.steps.ts, features/health.feature
Add Cucumber config entry and step definitions plus a BDD feature to query /health (ePDS, auth) and /xrpc/_health (upstream PDS) and assert presence and semver-like format of version fields.
Release notes / changesets
.changeset/xrpc-health-pds-version.md, .changeset/version-health-endpoint.md
Add changeset entries documenting that /xrpc/_health now reports upstream PDS version, and update audience/ops guidance for /health version exposure and override behavior.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

Poem

🐰 A little rabbit found a version to share,
It hopped from package.json with delicate care.
Tests sniffed the health, versions all aligned,
Change logged in changelogs, tidy and kind.
Hooray for tiny hops that keep systems aware! 🎉

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: adding a PDS_VERSION fallback so /xrpc/_health reports the upstream PDS version, which directly aligns with the core fix in packages/pds-core/src/index.ts.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/xrpc-health-pds-version

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coveralls-official
Copy link
Copy Markdown

coveralls-official bot commented Apr 12, 2026

Coverage Report for CI Build 24315208937

Coverage decreased (-0.02%) to 31.681%

Details

  • Coverage decreased (-0.02%) from the base build.
  • Patch coverage: 2 uncovered changes across 1 file (0 of 2 lines covered, 0.0%).
  • No coverage regressions found.

Uncovered Changes

File Changed Covered %
packages/pds-core/src/index.ts 2 0 0.0%

Coverage Regressions

No coverage regressions found.


Coverage Stats

Coverage Status
Relevant Lines: 1673
Covered Lines: 554
Line Coverage: 33.11%
Relevant Branches: 950
Covered Branches: 277
Branch Coverage: 29.16%
Branches in Coverage %: Yes
Coverage Strength: 2.79 hits per line

💛 - Coveralls

@aspiers aspiers force-pushed the fix/xrpc-health-pds-version branch from bdb7adf to 631af4f Compare April 12, 2026 18:49
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/pds-core/src/index.ts`:
- Around line 28-29: Add "type": "module" to the pds-core package.json and
update the runtime JSON import used for atprotoPdsVersion: replace the bare
require() usage of the '@atproto/pds/package.json' (the atprotoPdsVersion const)
with a Node ESM-safe import approach — either use Node's createRequire to load
the JSON or use an import with assertion (JSON import) so that atprotoPdsVersion
continues to be populated without triggering "require is not defined" under ESM.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: d240989d-17fe-43ae-89c5-81bb2f71c866

📥 Commits

Reviewing files that changed from the base of the PR and between 34c181d and bdb7adf.

📒 Files selected for processing (1)
  • packages/pds-core/src/index.ts

Comment thread packages/pds-core/src/index.ts Outdated
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
e2e/step-definitions/health.steps.ts (1)

7-11: Consider extracting a shared request helper for these When steps.

The fetch/status/json assignment pattern is repeated three times; a small helper would reduce drift and keep failures consistent.

♻️ Suggested refactor
+async function fetchJsonIntoWorld(this: EpdsWorld, url: string): Promise<void> {
+  const res = await fetch(url)
+  this.lastHttpStatus = res.status
+  this.lastHttpJson = (await res.json()) as Record<string, unknown>
+}
+
 When('the PDS /health endpoint is queried', async function (this: EpdsWorld) {
-  const res = await fetch(`${testEnv.pdsUrl}/health`)
-  this.lastHttpStatus = res.status
-  this.lastHttpJson = (await res.json()) as Record<string, unknown>
+  await fetchJsonIntoWorld.call(this, `${testEnv.pdsUrl}/health`)
 })
@@
   async function (this: EpdsWorld) {
-    const res = await fetch(`${testEnv.authUrl}/health`)
-    this.lastHttpStatus = res.status
-    this.lastHttpJson = (await res.json()) as Record<string, unknown>
+    await fetchJsonIntoWorld.call(this, `${testEnv.authUrl}/health`)
   },
 )
@@
   async function (this: EpdsWorld) {
-    const res = await fetch(`${testEnv.pdsUrl}/xrpc/_health`)
-    this.lastHttpStatus = res.status
-    this.lastHttpJson = (await res.json()) as Record<string, unknown>
+    await fetchJsonIntoWorld.call(this, `${testEnv.pdsUrl}/xrpc/_health`)
   },
 )

Also applies to: 33-40, 44-51

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@e2e/step-definitions/health.steps.ts` around lines 7 - 11, Extract the
repeated fetch+status+json logic into a shared async helper (e.g., in the same
file or a test utils module) and call it from each When step; the helper should
accept a URL (or base + path) and the EpdsWorld instance and set
world.lastHttpStatus and world.lastHttpJson consistently. Replace the body of
the When handler in health.steps.ts (the When('the PDS /health endpoint is
queried', async function (this: EpdsWorld) { ... })) and the other When handlers
referenced (lines 33-40 and 44-51) to call this helper with testEnv.pdsUrl +
'/health' (or the appropriate path) so all fetch/status/json assignments are
centralized and identical. Ensure the helper returns or throws errors
consistently so test failure behavior remains uniform.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@e2e/step-definitions/health.steps.ts`:
- Around line 13-29: Before checking the version field, assert the HTTP response
status is a success (e.g., 200 or any 2xx) so non-200 responses cannot
accidentally pass validation; in the Then step that runs inside the EpdsWorld
using this.lastHttpJson and this.lastHttpResponse (or similar response object),
add a guard validating this.lastHttpResponse.status is 200 (or within 200-299)
and throw a clear error if not, then proceed with the existing version existence
and semver checks on this.lastHttpJson.version. Ensure you apply the same change
to the other Then step referenced (lines 53-68) so both health assertions
validate response status first.

---

Nitpick comments:
In `@e2e/step-definitions/health.steps.ts`:
- Around line 7-11: Extract the repeated fetch+status+json logic into a shared
async helper (e.g., in the same file or a test utils module) and call it from
each When step; the helper should accept a URL (or base + path) and the
EpdsWorld instance and set world.lastHttpStatus and world.lastHttpJson
consistently. Replace the body of the When handler in health.steps.ts (the
When('the PDS /health endpoint is queried', async function (this: EpdsWorld) {
... })) and the other When handlers referenced (lines 33-40 and 44-51) to call
this helper with testEnv.pdsUrl + '/health' (or the appropriate path) so all
fetch/status/json assignments are centralized and identical. Ensure the helper
returns or throws errors consistently so test failure behavior remains uniform.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 4cfb8436-3d82-48dc-a074-067767bf4958

📥 Commits

Reviewing files that changed from the base of the PR and between bdb7adf and fd44f43.

📒 Files selected for processing (6)
  • .changeset/version-health-endpoint.md
  • .changeset/xrpc-health-pds-version.md
  • e2e/cucumber.mjs
  • e2e/step-definitions/health.steps.ts
  • features/health.feature
  • packages/pds-core/src/index.ts
✅ Files skipped from review due to trivial changes (5)
  • e2e/cucumber.mjs
  • packages/pds-core/src/index.ts
  • features/health.feature
  • .changeset/xrpc-health-pds-version.md
  • .changeset/version-health-endpoint.md

Comment thread e2e/step-definitions/health.steps.ts
The vanilla @atproto/pds entrypoint does `env.version ??= pkg.version`
to fall back to the package.json version when PDS_VERSION is unset.
ePDS omitted this, so /xrpc/_health returned {} instead of reporting
the upstream PDS version.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@aspiers aspiers force-pushed the fix/xrpc-health-pds-version branch from 0208730 to f709066 Compare April 12, 2026 20:02
@railway-app railway-app bot temporarily deployed to ePDS / ePDS-pr-76 April 12, 2026 20:02 Inactive
@sonarqubecloud
Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
52.4% Duplication on New Code (required ≤ 3%)

See analysis details on SonarQube Cloud

@aspiers
Copy link
Copy Markdown
Contributor Author

aspiers commented Apr 12, 2026

For some weird reason, Railway was absolutely refusing to deploy a preview environment for this PR, so I had to deploy one manually.

@aspiers
Copy link
Copy Markdown
Contributor Author

aspiers commented Apr 12, 2026

Manually triggered E2E tests ran fine: https://github.com/hypercerts-org/ePDS/actions/runs/24315210319/job/70991623246

and the other failures are trivial so I'm merging this.

@aspiers aspiers merged commit 2c1290a into main Apr 12, 2026
12 of 15 checks passed
@aspiers aspiers deleted the fix/xrpc-health-pds-version branch April 12, 2026 20:08
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