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
9 changes: 5 additions & 4 deletions SELF_HOSTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -235,9 +235,10 @@ directly to MinIO for presigned artifact uploads and downloads, and sends all
other paths, including web auth, browser tRPC, Slack OAuth, and UI routes, to
`web:3000`.

After those values are in place, use the admin **Settings → Live Previews**
page to confirm the detected runtime config, validate the wildcard preview
hostname, and opt previews in at the deployment and environment levels.
After those values are in place, open any task's preview pane as an admin to
confirm the detected runtime config and validate the wildcard preview
hostname. Live previews are always enabled: they publish for every environment
that defines preview ports once the runtime config is ready.

## Model Provider

Expand Down Expand Up @@ -522,7 +523,7 @@ the queue workers keep running.

`PREVIEW_PROXY_BASE_URL` and `PREVIEW_DOMAINS` no longer block startup when
unset: live previews simply report as not configured until you set the values
via env or from **Settings → Live Previews**.
via env or from the preview pane's admin setup on any task page.

`SETUP_TOKEN` protects the pre-auth `/setup` bootstrap wizard, which admits the
deployment's first admin. Until initial setup completes, the wizard rejects
Expand Down
1 change: 0 additions & 1 deletion apps/controller/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
"@roomote/compute-providers": "workspace:^",
"@roomote/db": "workspace:^",
"@roomote/env": "workspace:^",
"@roomote/feature-flags": "workspace:^",
"@roomote/redis": "workspace:^",
"@roomote/sdk": "workspace:^",
"@roomote/types": "workspace:^",
Expand Down
45 changes: 35 additions & 10 deletions apps/controller/src/__tests__/utils.test.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

31 changes: 4 additions & 27 deletions apps/controller/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,6 @@ import {
type NamedPort,
resolveComputeProviderTarget,
} from '@roomote/types';
import {
areDeploymentPreviewsEnabled,
normalizeMetadataRecord,
} from '@roomote/feature-flags';
import {
type TaskRun,
type DatabaseOrTransaction,
Expand All @@ -33,10 +29,6 @@ interface NamedPortsResult {
environmentConfig?: EnvironmentConfig;
}

interface DeploymentRuntimeFlags {
livePreviewsEnabled: boolean;
}

type ShouldEnableAuthBypassForTaskRunParams = {
environmentConfig?: EnvironmentConfig;
namedPorts: NamedPort[];
Expand All @@ -56,25 +48,14 @@ function configuredPreviewPortNeedsAuthBypass(port: NamedPort): boolean {
return requiresPreviewAuth(port) && port.proxied !== false;
}

async function resolveDeploymentRuntimeFlags(): Promise<DeploymentRuntimeFlags> {
const settings = await db.query.deploymentSettings.findFirst({
columns: {
metadata: true,
},
});

const metadata = normalizeMetadataRecord(settings?.metadata);
async function isPreviewRuntimeReady(): Promise<boolean> {
const previewRuntimeConfig = await resolveEffectivePreviewRuntimeConfig({
runtimeEnv: process.env,
defaultPreviewProxyBaseUrl: Env.PREVIEW_PROXY_BASE_URL,
defaultPreviewDomains: Env.PREVIEW_DOMAINS,
});

return {
livePreviewsEnabled:
areDeploymentPreviewsEnabled(metadata) &&
previewRuntimeConfig.analysis.isReady,
};
return previewRuntimeConfig.analysis.isReady;
}

export function shouldEnableAuthBypassForTaskRun({
Expand Down Expand Up @@ -122,14 +103,10 @@ export async function getNamedPortsForTaskRun(

if (environment) {
environmentConfig = environment.config;
const deploymentRuntimeFlags = await resolveDeploymentRuntimeFlags();
const previewRuntimeReady = await isPreviewRuntimeReady();

namedPorts = getNamedPortsForEnvironment({
ports:
deploymentRuntimeFlags.livePreviewsEnabled &&
environmentConfig.previews_enabled !== false
? environmentConfig.ports
: undefined,
ports: previewRuntimeReady ? environmentConfig.ports : undefined,
});

// Check if environment has a ready snapshot we can use.
Expand Down
4 changes: 2 additions & 2 deletions apps/docs/environment-variables.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ The exact order depends on the setting. A few important cases:
- Model role env vars such as `R_MODEL` override the same role selected
in **Settings > Models**.
- Preview env vars such as `PREVIEW_PROXY_BASE_URL` override values saved from
**Settings > Live Previews**.
the preview pane's admin setup on the task page.
- Sandbox provider credentials resolve as process env first, then saved
deployment env vars. The default sandbox provider is special: an explicit
admin selection saved in Roomote wins over `DEFAULT_COMPUTE_PROVIDER` because
Expand Down Expand Up @@ -331,7 +331,7 @@ apply semantics.

| Env var | Required | Used for |
| --------------------------- | --------------- | ------------------------------------------------------------------------------------------------------------ |
| `PREVIEW_PROXY_BASE_URL` | Preview support | Public preview-proxy origin. Overrides **Settings > Live Previews** when set. |
| `PREVIEW_PROXY_BASE_URL` | Preview support | Public preview-proxy origin. Overrides the origin saved from the preview pane's admin setup when set. |
| `PREVIEW_DOMAINS` | Optional | Comma-separated preview domains allowed by the preview proxy. Usually derived from `PREVIEW_PROXY_BASE_URL`. |
| `ROOMOTE_PREVIEW_DOMAIN` | Optional | Roomote preview domain override used by preview runtime analysis. |
| `PREVIEW_TOKEN_TTL_SECONDS` | Optional | Preview auth token lifetime. Defaults to 3600 seconds. |
Expand Down
1 change: 0 additions & 1 deletion apps/docs/environments/definition.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,6 @@ agentInstructions: |
| `services` | list | no | Managed services to start. See [Services](#services). |
| `docker_projects` | list | no | Existing Compose or Dockerfile projects to build and start. See [Docker projects](#docker-projects). |
| `ports` | list | no | Named preview ports. See [Ports](#ports). |
| `previews_enabled` | boolean | no | Explicitly enable or disable live previews without deleting port definitions. |
| `oidc` | map | no | Sandbox OIDC targets. See [OIDC](#oidc). |
| `mcpServers` | map | no | Custom MCP servers for this environment. See [MCP servers](#mcp-servers). |
| `skills` | map | no | Installable skills by `owner/repo`. See [Skills](#skills). |
Expand Down
8 changes: 6 additions & 2 deletions apps/web/src/app/(authenticated)/settings/previews/page.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import { LivePreviewsSettingsPage } from '@/components/settings/pages/LivePreviewsSettingsPage';
import { redirect } from 'next/navigation';

import { SETTINGS_PATHS } from '@/lib/settings';

// Live previews are always enabled; the setup experience now lives in the
// task page's preview pane. Redirect old bookmarks to environment settings.
export default function Page() {
return <LivePreviewsSettingsPage />;
redirect(SETTINGS_PATHS.environments);
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 13 additions & 3 deletions apps/web/src/app/(sandbox)/task/[taskId]/PreviewCommand.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,12 @@ interface PreviewCommandProps {
export function PreviewCommand({ taskRun, asleep }: PreviewCommandProps) {
const { initialPaths, previewUrl, previewUrls, primaryPortName } =
usePreviewUrls(taskRun ?? {});
const { openPreviewView, previewPath, previewServiceName } =
useTaskSidePanel();
const {
openPreviewSetupView,
openPreviewView,
previewPath,
previewServiceName,
} = useTaskSidePanel();
const { openPreviewPane } = usePreviewPane();
const {
previewServiceName: resolvedPreviewServiceName,
Expand All @@ -40,13 +44,18 @@ export function PreviewCommand({ taskRun, asleep }: PreviewCommandProps) {

const commands: Parameters<typeof useRegisterCommands>[0] = [];

if (resolvedPreviewUrl && taskRun?.id) {
if (taskRun?.id && taskRun.payload?.environmentId) {
commands.push({
id: 'task-live-preview',
icon: AppWindow,
label: 'Live Preview',
group: 'Task actions',
action: () => {
if (!resolvedPreviewUrl) {
openPreviewSetupView();
return;
}

openPreviewPane(
resolvedPreviewUrl,
taskRun.id,
Expand All @@ -67,6 +76,7 @@ export function PreviewCommand({ taskRun, asleep }: PreviewCommandProps) {
asleep,
taskRun,
openPreviewPane,
openPreviewSetupView,
openPreviewView,
resolvedPreviewServiceName,
resolvedPreviewUrl,
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading