Skip to content

Append app revision footer#29

Closed
hevehueqwnv wants to merge 1 commit into
ubiquity:mainfrom
hevehueqwnv:fix/app-revision-footer
Closed

Append app revision footer#29
hevehueqwnv wants to merge 1 commit into
ubiquity:mainfrom
hevehueqwnv:fix/app-revision-footer

Conversation

@hevehueqwnv

Copy link
Copy Markdown

Closes #6.

Adds a router-side revision footer for HTML app responses, matching the existing #bottom-right / #git-revision shape from work.ubq.fi.

  • injects a revision link for app HTML responses
  • populates existing #git-revision anchors without duplicating them
  • links derived app/plugin repos for faster debugging
  • leaves non-HTML responses untouched

Validation:

  • tsc --noEmit
  • bun test

@ubiquity-os

ubiquity-os Bot commented Jun 2, 2026

Copy link
Copy Markdown

Warning

@hevehueqwnv this pull request is linked to an issue that is already assigned to another user. Please link it to an open issue assigned to you or to an unassigned open issue.

@ubiquity-os ubiquity-os Bot closed this Jun 2, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5c525f30ba

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/worker.ts

const headers = new Headers(response.headers)
headers.delete('content-length')
return new Response(nextHtml, {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Preserve null-body statuses when injecting footers

When an HTML upstream returns a cache validation response such as 304 Not Modified with content-type: text/html, this path reads the empty body and then constructs new Response(nextHtml, { status: 304, ... }). The Fetch Response constructor rejects body content for null-body statuses like 304, so a normal conditional request for cached HTML will throw here and the route-level catch will turn the upstream 304 into a 502 instead of preserving the cache hit.

Useful? React with 👍 / 👎.

Comment thread src/worker.ts
function getRepoUrl(subKey: string, isPlugin: boolean): string {
const name = subKey.replace(/^preview-/, '')
if (isPlugin) {
return `https://github.com/ubiquity-os-marketplace/${name}`

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Strip plugin host prefixes from repo links

For plugin domains, subKey still includes the public os- prefix and any routing suffix, so os-command-config.ubq.fi produces https://github.com/ubiquity-os-marketplace/os-command-config. The documented plugin routing maps that host to the command-config-main deployment, so the derived marketplace repo link should not include the router-only os- prefix; otherwise every injected plugin footer points users at a non-existent or wrong repository.

Useful? React with 👍 / 👎.

@coderabbitai

coderabbitai Bot commented Jun 2, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The PR adds dynamic revision footer injection to HTML responses in the proxy worker. A new constant APP_REVISION_ANCHOR_ID targets the git-revision anchor element. The proxyRoute function now post-processes upstream responses via appendRevisionFooter, which extracts app revision from headers (or falls back to target hostname), builds a GitHub repository URL, and either updates an existing git-revision anchor or injects a footer before </body>. Non-HTML and HEAD requests skip processing. Helper functions handle revision extraction, URL building, footer HTML generation with inline styles, anchor attribute updates via regex, body injection, and HTML escaping. Tests validate footer injection, anchor population, and non-HTML passthrough.

🚥 Pre-merge checks | ✅ 4 | ❌ 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 (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Append app revision footer' directly and clearly describes the main change: adding a revision footer to app HTML responses.
Description check ✅ Passed The description accurately relates to the changeset, explaining the revision footer injection, anchor population, repository linking, and non-HTML pass-through behavior.
Linked Issues check ✅ Passed The PR fully implements issue #6 requirements: dynamically appends revision hash to app footer, links to repository for debugging, and reuses existing visual styles.
Out of Scope Changes check ✅ Passed All changes focus on implementing the revision footer feature; no unrelated modifications detected beyond the stated objectives.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with 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.

❤️ Share

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
tests/worker-routing.test.ts (1)

107-119: ⚡ Quick win

Add a HEAD HTML passthrough test.

Footer logic also branches on HEAD; add one test to assert no injection/mutation on HEAD + text/html responses.


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: d687e149-59be-45fc-b317-125ab0d83b5b

📥 Commits

Reviewing files that changed from the base of the PR and between 91bebfb and 5c525f3.

📒 Files selected for processing (2)
  • src/worker.ts
  • tests/worker-routing.test.ts

Comment thread src/worker.ts
Comment on lines +287 to +288
const headers = new Headers(response.headers)
headers.delete('content-length')

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Must also delete content-encoding header.

response.text() auto-decompresses gzip. The new Response has uncompressed body but retains content-encoding: gzip header → browser decode error.

🐛 Proposed fix
   const headers = new Headers(response.headers)
   headers.delete('content-length')
+  headers.delete('content-encoding')
   return new Response(nextHtml, {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const headers = new Headers(response.headers)
headers.delete('content-length')
const headers = new Headers(response.headers)
headers.delete('content-length')
headers.delete('content-encoding')

Comment thread src/worker.ts
Comment on lines +341 to +342
return html.replace(
/<a\b([^>]*\bid=["']git-revision["'][^>]*)>[\s\S]*?<\/a>/i,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Inconsistent: hardcodes 'git-revision' instead of using APP_REVISION_ANCHOR_ID.

If the constant changes, this regex won't match.

Proposed fix
   return html.replace(
-    /<a\b([^>]*\bid=["']git-revision["'][^>]*)>[\s\S]*?<\/a>/i,
+    new RegExp(`<a\\b([^>]*\\bid=["']${APP_REVISION_ANCHOR_ID}["'][^>]*)>[\\s\\S]*?</a>`, 'i'),
     (_match, attrs: string) => {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
return html.replace(
/<a\b([^>]*\bid=["']git-revision["'][^>]*)>[\s\S]*?<\/a>/i,
return html.replace(
new RegExp(`<a\\b([^>]*\\bid=["']${APP_REVISION_ANCHOR_ID}["'][^>]*)>[\\s\\S]*?</a>`, 'i'),
(_match, attrs: string) => {

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.

Dynamically append the revision hash on every app footer

1 participant