diff --git a/.changeset/hosted-static-web-dist.md b/.changeset/hosted-static-web-dist.md new file mode 100644 index 00000000000..557859a43a9 --- /dev/null +++ b/.changeset/hosted-static-web-dist.md @@ -0,0 +1,5 @@ +--- +"@t3tools/web": patch +--- + +Build release web dist archives as hosted static apps. diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 75878dc504f..0d25a9ee4cb 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -663,6 +663,8 @@ jobs: T3CODE_CLERK_PUBLISHABLE_KEY: "" T3CODE_CLERK_JWT_TEMPLATE: "" T3CODE_RELAY_URL: "" + VITE_HOSTED_STATIC_APP: "true" + VITE_HOSTED_APP_CHANNEL: ${{ needs.preflight.outputs.release_channel == 'stable' && 'latest' || 'nightly' }} steps: - name: Checkout uses: actions/checkout@v6 diff --git a/FORK.md b/FORK.md index 3ce56a76cf3..7afaf0edf0d 100644 --- a/FORK.md +++ b/FORK.md @@ -21,6 +21,7 @@ This repository is a fork of `pingdotgg/t3code`. Keep this file focused on fork - macOS passkey entitlements are only enabled when Apple notarization/profile configuration is present. - Windows releases can sign with the static certificate when Azure Trusted Signing is not configured. - Fork release jobs use GitHub-hosted runners where upstream private runners are unavailable. +- Web dist release archives are built as hosted static apps and carry the release channel. ### Desktop Updater Channels diff --git a/apps/web/src/hostedPairing.ts b/apps/web/src/hostedPairing.ts index 2caf844af9b..176c0aa4691 100644 --- a/apps/web/src/hostedPairing.ts +++ b/apps/web/src/hostedPairing.ts @@ -10,8 +10,20 @@ export interface HostedPairingRequest { export type HostedAppChannel = "latest" | "nightly"; +function hostedStaticAppEnabled(): boolean { + return import.meta.env.VITE_HOSTED_STATIC_APP === "true"; +} + +function currentOrigin(): string | null { + return typeof window === "undefined" ? null : window.location.origin; +} + export function configuredHostedAppUrl(): string { - return import.meta.env.VITE_HOSTED_APP_URL?.trim() || DEFAULT_HOSTED_APP_URL; + return ( + import.meta.env.VITE_HOSTED_APP_URL?.trim() || + (hostedStaticAppEnabled() ? currentOrigin() : null) || + DEFAULT_HOSTED_APP_URL + ); } function configuredBackendUrl(): string { @@ -36,6 +48,10 @@ export function isHostedStaticApp(url: URL = new URL(window.location.href)): boo return false; } + if (hostedStaticAppEnabled()) { + return true; + } + if (configuredHostedAppChannel()) { return true; } diff --git a/apps/web/src/vite-env.d.ts b/apps/web/src/vite-env.d.ts index d8a6d71b49a..03a1e86ce5e 100644 --- a/apps/web/src/vite-env.d.ts +++ b/apps/web/src/vite-env.d.ts @@ -5,6 +5,7 @@ import type { DesktopBridge, LocalApi } from "@t3tools/contracts"; interface ImportMetaEnv { readonly VITE_HTTP_URL: string; readonly VITE_WS_URL: string; + readonly VITE_HOSTED_STATIC_APP: string; readonly VITE_HOSTED_APP_URL: string; readonly VITE_HOSTED_APP_CHANNEL: string; readonly VITE_CLERK_PUBLISHABLE_KEY: string; diff --git a/apps/web/vite.config.ts b/apps/web/vite.config.ts index 54e1f26b07e..485212ad84c 100644 --- a/apps/web/vite.config.ts +++ b/apps/web/vite.config.ts @@ -21,6 +21,7 @@ const configuredClerkJwtTemplate = repoEnv.VITE_CLERK_JWT_TEMPLATE?.trim() || "" const configuredRelayTracingUrl = repoEnv.VITE_RELAY_OTLP_TRACES_URL?.trim() || ""; const configuredRelayTracingDataset = repoEnv.VITE_RELAY_OTLP_TRACES_DATASET?.trim() || ""; const configuredRelayTracingToken = repoEnv.VITE_RELAY_OTLP_TRACES_TOKEN?.trim() || ""; +const configuredHostedStaticApp = process.env.VITE_HOSTED_STATIC_APP?.trim() || ""; const configuredHostedAppChannel = process.env.VITE_HOSTED_APP_CHANNEL?.trim() || ""; const configuredAppVersion = process.env.APP_VERSION?.trim() || pkg.version; const configuredHostedAppUrl = (() => { @@ -121,6 +122,7 @@ export default defineConfig(() => { configuredRelayTracingDataset, ), "import.meta.env.VITE_RELAY_OTLP_TRACES_TOKEN": JSON.stringify(configuredRelayTracingToken), + "import.meta.env.VITE_HOSTED_STATIC_APP": JSON.stringify(configuredHostedStaticApp), "import.meta.env.VITE_HOSTED_APP_URL": JSON.stringify(configuredHostedAppUrl ?? ""), "import.meta.env.VITE_HOSTED_APP_CHANNEL": JSON.stringify(configuredHostedAppChannel), "import.meta.env.APP_VERSION": JSON.stringify(configuredAppVersion),