-
-
Notifications
You must be signed in to change notification settings - Fork 13
Added ADR for frontend versioning strategy #1161
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
TL;DR Instead of the frontend version being determined by Ghost version, causing mismatches, the ActivityPub backend will have an endpoint that tells the frontend loader which CDN bundle URL to use. This guarantees the frontend and backend versions are always compatible - each backend version declares its matching frontend version. Simple fix, minimal code changes, solves all the deployment scenarios.
WalkthroughA new design proposal document has been added, outlining a frontend versioning strategy for the ActivityPub service. The document describes deployment scenarios, identifies compatibility challenges between frontend and backend versions, and proposes a solution involving a backend endpoint that returns the appropriate frontend bundle URL. The frontend loader will use this endpoint to dynamically import the compatible bundle. The proposal details release coordination, version pinning, and the implications for different hosting environments, without introducing any changes to code or exported entities. Estimated code review effort🎯 2 (Simple) | ⏱️ ~7 minutes Note ⚡️ Unit Test Generation is now available in beta!Learn more here, or try it out under "Finishing Touches" below. ✨ Finishing Touches🧪 Generate unit tests
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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (3)
adr/frontend-versioning.md (3)
1-6
: Add standard ADR front-matter (ID, Date, Status) for traceability
The project’s existing ADRs carry a short YAML/markdown header (id
,date
,status
,deciders
, etc.) so they can be indexed automatically. Consider adding it here to keep the file machine-discoverable and sortable.+# --- +# id: 00XX-frontend-versioning +# title: ActivityPub Service Frontend Versioning via Backend Configuration +# date: 2025-08-?? # fill in PR merge date +# status: Proposed +# deciders: @allouis +# ---
35-45
: Specify method, auth & cache semantics of/.ghost/activitypub/client-config
The ADR explains WHAT the endpoint returns but omits operational details that tend to bite later:
- HTTP method – presumably
GET
only.- Caching – Our previous learning shows a preference for broad surrogate caching (exclude v1 APIs, cache everything else). Clarify whether this endpoint should inherit that rule or set an explicit
Surrogate-Control: max-age=…
header; otherwise stale bundle URLs could linger in CDN/proxy layers.- Authentication – Should self-hosted proxies hitting our infra call an unauthenticated endpoint, or must it be session-bound? Stating this avoids later ambivalence.
A concise paragraph covering the above would complete the “Implementation” section.
68-70
: Mitigate the extra RTT by recommending aggressive caching of config response
The “Negative” list mentions the extra HTTP request but not that, with even a short-lived public cache (e.g., 5 min in CDN + private browser cache), the cost is effectively amortised. Given our earlier caching preference, add a note that the endpoint SHOULD sendSurrogate-Control
andCache-Control
headers so loaders usually hit the local cache, not origin.This aligns the ADR with established caching conventions noted in previous PR #1114.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
adr/frontend-versioning.md
(1 hunks)
🧰 Additional context used
🧠 Learnings (5)
📓 Common learnings
Learnt from: allouis
PR: TryGhost/ActivityPub#1010
File: src/app.ts:744-744
Timestamp: 2025-07-09T06:47:50.064Z
Learning: In the TryGhost/ActivityPub repository, allouis prefers to keep refactoring PRs focused on code restructuring only, without adding new functionality or changing behavior. When moving existing code that has issues, the issues should be preserved in the refactoring and addressed separately.
Learnt from: allouis
PR: TryGhost/ActivityPub#1114
File: src/app.ts:597-608
Timestamp: 2025-07-28T03:28:29.993Z
Learning: In the TryGhost/ActivityPub repository, allouis prefers simple, broad caching logic over explicit endpoint whitelisting for the Surrogate-Control header. The approach of "exclude v1 API endpoints, cache everything else ActivityPub" combined with GET/HEAD method restrictions is preferred for its simplicity and maintainability, even when it includes dynamic federation endpoints like followers/following/outbox that are still reasonable to cache for read operations.
Learnt from: allouis
PR: TryGhost/ActivityPub#1021
File: src/post/post.entity.ts:327-329
Timestamp: 2025-07-10T08:39:14.900Z
Learning: In the TryGhost/ActivityPub repository, when parsing data from Ghost CMS (such as post excerpts) using branded types with validation (like PostSummary.parse()), allouis prefers to let the parsing throw errors if Ghost sends incompatible data rather than adding defensive handling like truncation. This approach helps detect incompatibilities between the ActivityPub system and Ghost CMS early, ensuring issues are addressed at the source rather than silently ignored.
Learnt from: allouis
PR: TryGhost/ActivityPub#593
File: src/http/api/reply.ts:48-59
Timestamp: 2025-04-30T11:39:20.993Z
Learning: In the TryGhost/ActivityPub repository, when working with URL IDs in API handlers, the codebase uses a pattern where the raw ID parameter is passed to `lookupObject` even when a decoded version has been created with `decodeURIComponent`. This pattern is consistent with existing functionality in `handlers.ts`.
Learnt from: allouis
PR: TryGhost/ActivityPub#858
File: features/support/content.js:15-22
Timestamp: 2025-06-16T15:43:23.967Z
Learning: allouis prefers to keep refactoring PRs focused on code restructuring only, without adding new functionality or changing behavior. Functional improvements like error handling should be suggested for separate PRs.
📚 Learning: in the tryghost/activitypub repository, allouis prefers simple, broad caching logic over explicit en...
Learnt from: allouis
PR: TryGhost/ActivityPub#1114
File: src/app.ts:597-608
Timestamp: 2025-07-28T03:28:29.993Z
Learning: In the TryGhost/ActivityPub repository, allouis prefers simple, broad caching logic over explicit endpoint whitelisting for the Surrogate-Control header. The approach of "exclude v1 API endpoints, cache everything else ActivityPub" combined with GET/HEAD method restrictions is preferred for its simplicity and maintainability, even when it includes dynamic federation endpoints like followers/following/outbox that are still reasonable to cache for read operations.
Applied to files:
adr/frontend-versioning.md
📚 Learning: in the tryghost/activitypub repository, allouis prefers to keep refactoring prs focused on code rest...
Learnt from: allouis
PR: TryGhost/ActivityPub#1010
File: src/app.ts:744-744
Timestamp: 2025-07-09T06:47:50.064Z
Learning: In the TryGhost/ActivityPub repository, allouis prefers to keep refactoring PRs focused on code restructuring only, without adding new functionality or changing behavior. When moving existing code that has issues, the issues should be preserved in the refactoring and addressed separately.
Applied to files:
adr/frontend-versioning.md
📚 Learning: in the tryghost/activitypub repository, the exponential backoff for delivery failures in src/account...
Learnt from: mike182uk
PR: TryGhost/ActivityPub#1043
File: src/account/account.service.ts:759-794
Timestamp: 2025-07-15T13:07:04.697Z
Learning: In the TryGhost/ActivityPub repository, the exponential backoff for delivery failures in src/account/account.service.ts is intentionally designed without a maximum cap. This unbounded growth is by design - longer delivery failure periods give more confidence that an account is truly broken rather than temporarily unavailable, while still giving receivers a fair chance to recover from temporary issues.
Applied to files:
adr/frontend-versioning.md
📚 Learning: in the tryghost/activitypub repository, mike182uk designed the delivery failure backoff mechanism in...
Learnt from: mike182uk
PR: TryGhost/ActivityPub#1043
File: src/account/account.service.ts:54-55
Timestamp: 2025-07-15T13:05:42.512Z
Learning: In the TryGhost/ActivityPub repository, mike182uk designed the delivery failure backoff mechanism in src/account/account.service.ts to intentionally use unbounded exponential backoff without a maximum cap. This design serves as a confidence mechanism where the longer delivery attempts fail, the more confident the system becomes that the account is truly broken rather than experiencing temporary issues. The backoff gives receivers a "fair chance" of receiving future activities if they're having temporary issues that later get resolved.
Applied to files:
adr/frontend-versioning.md
At first read-through this sounds like a really nice approach! A couple of questions...
|
Great Q's!
|
Does that get bundled with the AP client build or does it depend on an already-loaded version provided by the host app? |
Good point, that is bundled with the AP client! |
TL;DR Instead of the frontend version being determined by Ghost version, causing mismatches, the ActivityPub backend will have an endpoint that tells the frontend loader which CDN bundle URL to use. This guarantees the frontend and backend versions are always compatible - each backend version declares its matching frontend version. Simple fix, minimal code changes, solves all the deployment scenarios.