Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -625,6 +625,9 @@ jobs:
router_url="${T3CODE_WEB_ROUTER_URL:-https://app.t3.codes}"
latest_domain="${T3CODE_WEB_LATEST_DOMAIN:-latest.app.t3.codes}"
nightly_domain="${T3CODE_WEB_NIGHTLY_DOMAIN:-nightly.app.t3.codes}"
router_domain="${router_url#http://}"
router_domain="${router_domain#https://}"
router_domain="${router_domain%%/*}"

if [[ "${{ needs.preflight.outputs.release_channel }}" == "stable" ]]; then
channel_domain="$latest_domain"
Expand Down Expand Up @@ -657,6 +660,13 @@ jobs:
--token "$VERCEL_TOKEN" \
"${vercel_scope_args[@]}"

if [[ "$channel_name" == "latest" && -n "$router_domain" && "$router_domain" != "$channel_domain" ]]; then
echo "Aliasing $deployment_url to router domain $router_domain."
bunx vercel@53.1.1 alias set "$deployment_url" "$router_domain" \
--token "$VERCEL_TOKEN" \
"${vercel_scope_args[@]}"
fi

finalize:
name: Finalize release
if: ${{ !failure() && !cancelled() && needs.preflight.result == 'success' && needs.release.result == 'success' && needs.preflight.outputs.release_channel == 'stable' }}
Expand Down
2 changes: 2 additions & 0 deletions apps/web/src/branding.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ describe("branding", () => {

expect(branding.HOSTED_APP_CHANNEL).toBe("nightly");
expect(branding.HOSTED_APP_CHANNEL_LABEL).toBe("Nightly");
expect(branding.APP_STAGE_LABEL).toBe("Nightly");
expect(branding.APP_DISPLAY_NAME).toBe("T3 Code (Nightly)");
});

it("ignores unknown hosted app channels", async () => {
Expand Down
12 changes: 7 additions & 5 deletions apps/web/src/branding.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,15 @@ function readInjectedDesktopAppBranding(): DesktopAppBranding | null {
const injectedDesktopAppBranding = readInjectedDesktopAppBranding();
const hostedAppChannel = import.meta.env.VITE_HOSTED_APP_CHANNEL?.trim().toLowerCase();

export const HOSTED_APP_CHANNEL =
hostedAppChannel === "latest" || hostedAppChannel === "nightly" ? hostedAppChannel : null;
export const HOSTED_APP_CHANNEL_LABEL =
HOSTED_APP_CHANNEL === "nightly" ? "Nightly" : HOSTED_APP_CHANNEL === "latest" ? "Latest" : null;
export const APP_BASE_NAME = injectedDesktopAppBranding?.baseName ?? "T3 Code";
export const APP_STAGE_LABEL =
injectedDesktopAppBranding?.stageLabel ?? (import.meta.env.DEV ? "Dev" : "Alpha");
injectedDesktopAppBranding?.stageLabel ??
HOSTED_APP_CHANNEL_LABEL ??
(import.meta.env.DEV ? "Dev" : "Alpha");
export const APP_DISPLAY_NAME =
injectedDesktopAppBranding?.displayName ?? `${APP_BASE_NAME} (${APP_STAGE_LABEL})`;
export const APP_VERSION = import.meta.env.APP_VERSION || "0.0.0";
export const HOSTED_APP_CHANNEL =
hostedAppChannel === "latest" || hostedAppChannel === "nightly" ? hostedAppChannel : null;
export const HOSTED_APP_CHANNEL_LABEL =
HOSTED_APP_CHANNEL === "nightly" ? "Nightly" : HOSTED_APP_CHANNEL === "latest" ? "Latest" : null;
2 changes: 1 addition & 1 deletion apps/web/src/components/settings/SettingsPanels.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -892,7 +892,7 @@ export function GeneralSettingsPanel() {
</SettingsSection>

<SettingsSection title="About">
{isElectron ? (
{isElectron || HOSTED_APP_CHANNEL ? (
<AboutVersionSection />
) : (
<SettingsRow
Expand Down
11 changes: 10 additions & 1 deletion apps/web/vercel.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
import { matchers, routes, type VercelConfig } from "@vercel/config/v1";
import { matchers, routes, type Transform, type VercelConfig } from "@vercel/config/v1";

const ROUTER_HOST = "app.t3.codes";
const HOSTED_WEB_CHANNEL_COOKIE = "t3code_web_channel";
const LATEST_ORIGIN = "https://latest.app.t3.codes";
const NIGHTLY_ORIGIN = "https://nightly.app.t3.codes";
const CLEAN_CHANNEL_QUERY_TRANSFORMS = [
{
type: "request.query",
op: "delete",
target: { key: "channel" },
},
] satisfies Transform[];

function channelCookie(channel: "latest" | "nightly"): string {
return [
Expand All @@ -28,6 +35,7 @@ export const config: VercelConfig = {
{
src: "/__t3code/channel",
has: [matchers.query("channel", "nightly")],
transforms: CLEAN_CHANNEL_QUERY_TRANSFORMS,
headers: {
Location: "/",
"Set-Cookie": channelCookie("nightly"),
Expand All @@ -36,6 +44,7 @@ export const config: VercelConfig = {
},
{
src: "/__t3code/channel",
transforms: CLEAN_CHANNEL_QUERY_TRANSFORMS,
headers: {
Location: "/",
"Set-Cookie": channelCookie("latest"),
Expand Down
20 changes: 11 additions & 9 deletions docs/release.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ Optional GitHub Actions variables:

Required Vercel domains:

- `app.t3.codes`: the stable router domain users open.
- `app.t3.codes`: the router domain users open, updated by stable releases.
- `latest.app.t3.codes`: channel alias updated by stable releases.
- `nightly.app.t3.codes`: channel alias updated by nightly releases.

Expand All @@ -62,11 +62,13 @@ visiting `/__t3code/channel?channel=latest` or
the matching channel alias.

The release deploy job rewrites release package versions before upload so the
hosted app's About panel renders the release version. It also passes
`VITE_HOSTED_APP_CHANNEL=latest|nightly`, which renders the hosted update track
selector in the About panel. Changing the selector navigates through
`/__t3code/channel` on the router domain so the user's channel cookie is updated
before redirecting to the hosted app root.
hosted app's About panel renders the release version. Stable deploys alias the
same deployment to both the `latest` channel and the router domain so the router
rules stay current. Nightly deploys only alias the `nightly` channel. The job
also passes `VITE_HOSTED_APP_CHANNEL=latest|nightly`, which renders the hosted
update track selector in the About panel. Changing the selector navigates
through `/__t3code/channel` on the router domain so the user's channel cookie is
updated before redirecting to the hosted app root.

One-time Vercel dashboard setup:

Expand All @@ -75,9 +77,9 @@ One-time Vercel dashboard setup:
3. Disable automatic Git deployments in the dashboard if desired; the committed
`vercel.ts` setting is the source-of-truth, but disconnecting Git in the
dashboard is also safe.
4. Promote or alias one deployment containing the router rules in `apps/web/vercel.ts` to
`app.t3.codes` once. Future release jobs should only update the channel
aliases.
4. Run one stable release deployment, or manually alias the current stable
deployment, so `app.t3.codes` points at a deployment containing the router
rules in `apps/web/vercel.ts`. Future stable releases keep this alias current.

## Nightly builds

Expand Down
Loading