Skip to content

Deploy hosted web app from release workflow#2507

Open
juliusmarminge wants to merge 4 commits intomainfrom
t3code/1be1f71d
Open

Deploy hosted web app from release workflow#2507
juliusmarminge wants to merge 4 commits intomainfrom
t3code/1be1f71d

Conversation

@juliusmarminge
Copy link
Copy Markdown
Member

@juliusmarminge juliusmarminge commented May 4, 2026

Summary

  • Adds a release-time Vercel deploy step for the hosted web app, with channel aliasing for stable and nightly releases.
  • Introduces middleware that routes app.t3.codes traffic to the correct hosted channel based on a cookie or channel opt-in URL.
  • Disables automatic Vercel Git deployments for apps/web and documents the release/deploy process and required environment setup.
  • Adds middleware tests covering channel normalization, cookie parsing, safe redirects, and rewrite selection.

Testing

  • bun run test apps/web/middleware.test.ts
  • bun fmt
  • bun lint
  • bun typecheck

Note

Medium Risk
Adds a new release-time Vercel deployment job and Edge middleware-based request routing, which can affect production release automation and hosted web traffic routing/redirect behavior. Risk is mitigated by explicit env validation and added unit tests, but misconfiguration could break hosted channel access or announcements.

Overview
Automates hosted web deployments as part of releases. The release workflow now runs a deploy_web job after a successful GitHub Release to deploy apps/web via Vercel CLI, set build-time env (version + hosted channel), and alias the deployment to the latest (stable) or nightly domain; Discord announcements are gated on this deploy succeeding.

Introduces hosted channel routing/switching for app.t3.codes. Adds Vercel Edge middleware.ts that rewrites router-host traffic to per-channel origins based on a t3code_web_channel cookie and a /__t3code/channel opt-in endpoint (with safe internal-only next redirects), plus UI support to switch channels from the About panel and associated tests.

Disables Vercel Git auto-deploy for the web app and documents the process. apps/web/vercel.json turns off Git deployments, vite env typing/config gains VITE_HOSTED_APP_CHANNEL/APP_VERSION wiring, and docs/release.md documents required secrets/domains and the new deployment flow.

Reviewed by Cursor Bugbot for commit ad418ab. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Deploy hosted web app to Vercel from the release workflow with channel routing

  • Adds a deploy_web job to release.yml that runs after a successful release, builds apps/web, and deploys to Vercel, aliasing the result to either the latest or nightly domain based on release channel.
  • Adds a Vercel edge middleware in apps/web/middleware.ts that routes requests on the router host: /\_\_t3code/channel sets a long-lived cookie and redirects, while all other paths are rewritten to the selected channel's origin (defaulting to latest).
  • Exposes HOSTED_APP_CHANNEL and HOSTED_APP_CHANNEL_LABEL from the branding module and adds a channel selector to the About panel in the hosted web app that navigates to the channel selection URL.
  • Disables automatic Git-based Vercel deployments via apps/web/vercel.json; all deployments are now controlled by the release workflow.
  • Discord announcement now requires deploy_web to succeed before firing.

Macroscope summarized ad418ab.

- Add Vercel release deployment and channel aliasing
- Route app.t3.codes through middleware-based channel selection
- Document hosted web release setup
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 4, 2026

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 152c9f08-c9c8-44f7-b6b1-0ca25ae44761

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch t3code/1be1f71d

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

@github-actions github-actions Bot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels May 4, 2026
Comment thread apps/web/middleware.ts Outdated
Comment thread apps/web/middleware.ts
@macroscopeapp
Copy link
Copy Markdown
Contributor

macroscopeapp Bot commented May 4, 2026

Approvability

Verdict: Needs human review

This PR introduces a new feature with Vercel edge middleware for channel-based routing, new UI for channel switching, and new CI/CD deployment logic. New middleware handling request routing and cookie management represents significant new runtime behavior warranting human review. An unresolved comment also identifies a potential issue with URL path validation.

You can customize Macroscope's approvability policy. Learn more.

- Pass release version and hosted channel into the web build
- Display the hosted update track in About for latest/nightly releases
- Refresh release package versions before deployment
- Route channel changes through the hosted router so the cookie updates
- Add URL-building coverage and document the release flow
Copy link
Copy Markdown
Contributor

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Autofix Details

Bugbot Autofix prepared a fix for the issue found in the latest run.

  • ✅ Fixed: Exported constant never used in production code
    • Updated SettingsPanels.tsx to import and use HOSTED_APP_CHANNEL_LABEL instead of deriving the label inline, giving the exported constant actual production usage.

Create PR

Or push these changes by commenting:

@cursor push e243d403ad
Preview (e243d403ad)
diff --git a/apps/web/src/components/settings/SettingsPanels.tsx b/apps/web/src/components/settings/SettingsPanels.tsx
--- a/apps/web/src/components/settings/SettingsPanels.tsx
+++ b/apps/web/src/components/settings/SettingsPanels.tsx
@@ -13,7 +13,7 @@
 import { DEFAULT_UNIFIED_SETTINGS } from "@t3tools/contracts/settings";
 import { createModelSelection } from "@t3tools/shared/model";
 import { Equal } from "effect";
-import { APP_VERSION, HOSTED_APP_CHANNEL } from "../../branding";
+import { APP_VERSION, HOSTED_APP_CHANNEL, HOSTED_APP_CHANNEL_LABEL } from "../../branding";
 import {
   canCheckForUpdate,
   getDesktopUpdateButtonTooltip,
@@ -356,9 +356,7 @@
               }}
             >
               <SelectTrigger className="w-full sm:w-40" aria-label="Update track">
-                <SelectValue>
-                  {selectedHostedAppChannel === "nightly" ? "Nightly" : "Latest"}
-                </SelectValue>
+                <SelectValue>{HOSTED_APP_CHANNEL_LABEL}</SelectValue>
               </SelectTrigger>
               <SelectPopup align="end" alignItemWithTrigger={false}>
                 <SelectItem hideIndicator value="latest">

You can send follow-ups to the cloud agent here.

Comment thread apps/web/src/branding.ts
- Normalize router host comparisons with and without ports
- Reject unsafe `next` values containing backslashes, colons, or control chars
- Reuse the hosted channel label in settings
Copy link
Copy Markdown
Contributor

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

Bugbot Autofix prepared a fix for the issue found in the latest run.

  • ✅ Fixed: Client URL builder produces paths middleware rejects
    • Removed the redundant value.includes(":") check from safeNextPath since the existing startsWith("/") and startsWith("//") guards already prevent protocol-based attacks, and the colon check was incorrectly rejecting legitimate query strings and hash fragments.

Create PR

Or push these changes by commenting:

@cursor push 1d8e4354e3
Preview (1d8e4354e3)
diff --git a/apps/web/middleware.ts b/apps/web/middleware.ts
--- a/apps/web/middleware.ts
+++ b/apps/web/middleware.ts
@@ -79,7 +79,6 @@
     !value?.startsWith("/") ||
     value.startsWith("//") ||
     value.includes("\\") ||
-    value.includes(":") ||
     hasControlCharacter(value)
   ) {
     return "/";

You can send follow-ups to the cloud agent here.

Reviewed by Cursor Bugbot for commit ad418ab. Configure here.

readonly currentUrl?: URL | undefined;
}): string {
const currentUrl = input.currentUrl ?? new URL(window.location.href);
const nextPath = `${currentUrl.pathname}${currentUrl.search}${currentUrl.hash}` || "/";
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Client URL builder produces paths middleware rejects

Low Severity

buildHostedChannelSelectionUrl constructs nextPath by concatenating currentUrl.pathname, currentUrl.search, and currentUrl.hash. The middleware's safeNextPath rejects any value containing :. Since query strings and hash fragments can legitimately contain colons (e.g., a ?host=http://x:3773 param), the middleware will silently discard the return path and redirect to / instead of the user's current page. The colon check is redundant given the existing startsWith("/") and startsWith("//") guards which already prevent protocol-based attacks.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit ad418ab. Configure here.

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

Labels

size:L 100-499 changed lines (additions + deletions). vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant