feat: add Portless HTTPS development URLs across all workspaces - #129
Conversation
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
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. Comment |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
This stack of pull requests is managed by Graphite. Learn more about stacking. |
c8c1146 to
d43c188
Compare
d43c188 to
2e158ae
Compare
c1f2b0d to
b5a54c6
Compare
|
@codex review |
2e158ae to
a44c326
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2e158ae89c
ℹ️ 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".
| ) | ||
|
|
||
| if (!projectName) return { changedFiles } | ||
| if (!projectName) return { changedFiles: [...changedFiles] } |
There was a problem hiding this comment.
Rewrite copied workspace hostnames before returning
When template add copies a workspace into an already-renamed scaffold, addWorkspaces calls renameProject without projectName, so this return skips the new .localhost replacement. restorePortlessWorkspaces only changes the package.json route name; files such as Desktop's tauri.conf.json, API environment defaults, and the Workflows command remain on *.init.localhost. For example, adding Desktop to a foo scaffold exposes desktop.foo.localhost while Tauri waits for desktop.init.localhost, preventing development startup.
Useful? React with 👍 / 👎.
| ]) | ||
| const workspacePaths = workspaces | ||
| .flat() | ||
| .map((workspace) => relative(rootDir, workspace.directory)) |
There was a problem hiding this comment.
Normalize workspace paths before deriving route names
On Windows, node:path.relative returns paths such as apps\app, but getWorkspaceRouteName compares against apps/app and splits only on /. Every project setup or root rename on Windows therefore writes names such as apps\app.foo instead of the bare foo route, and similarly malformed names for other workspaces; normalize to POSIX separators or derive the route from the workspace kind and name.
Useful? React with 👍 / 👎.
| and route health. Set `PORTLESS=0` when running a root or workspace `dev` command to | ||
| bypass the proxy and use each tool's documented fallback port. |
There was a problem hiding this comment.
Make the advertised direct-port mode self-consistent
When PORTLESS=0 actually bypasses the proxy, only the listening ports fall back: the supplied App/API environment defaults still use https://*.localhost, and packages/workflows still polls https://api.init.localhost/workflows. Consequently direct-mode App authentication and API origin checks target unavailable proxy origins, while Inngest cannot reach a concurrently bypassed API. The fallback needs matching direct URLs or the documentation must require explicit URL overrides rather than claiming the root or workspace command is sufficient.
Useful? React with 👍 / 👎.
a44c326 to
03da37e
Compare
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 03da37e9a9
ℹ️ 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".
| env.PORTLESS_URL?.replace(new URL(env.BASE_URL).hostname, new URL(origin).hostname) ?? | ||
| origin | ||
| ).origin |
There was a problem hiding this comment.
Preserve legacy local origins when Portless is active
When an existing checkout retains the previous .env.local values (BASE_URL=http://localhost:3000 and ALLOWED_API_ORIGINS=http://localhost:3001), Portless supplies https://api.init.localhost here, but replacing localhost with the identical origin hostname leaves the API URL unchanged. allowedOrigins therefore becomes the API's own origin rather than https://init.localhost, causing CORS, Better Auth, and Files SDK requests from the App to be rejected after upgrading unless every developer manually recreates their environment file.
Useful? React with 👍 / 👎.
| for (const path of await replaceTextInFiles( | ||
| rootDir, | ||
| `${normalizedSourceScope}.localhost`, | ||
| `${normalizedScope}.localhost` |
There was a problem hiding this comment.
Keep project hostnames during workspace-only renames
When running bun template rename --workspace apps/api --scope bar in a project whose scope is foo, this unconditional replacement now rewrites the selected workspace's URLs from *.foo.localhost to *.bar.localhost, while the early return below deliberately leaves its Portless route name as api.foo. The API consequently advertises and trusts a hostname that Portless does not serve; hostname replacement should be limited to project renames or the template-copy restoration flow.
Useful? React with 👍 / 👎.

Portless (
0.15.5) is added as a pinned rootdevDependencyto provide stable HTTPS development URLs for every HTTP-serving workspace. Each workspace'sdevscript is replaced withportless, and the underlying framework command moves todev:app. A package-localportlessobject in eachpackage.jsondeclares the workspace's route name and target script, following Portless's recommended Turborepo pattern.The normalized npm scope owns the hostname suffix. With the default
initscope, the App is reachable athttps://init.localhost, the API athttps://api.init.localhost, and all other workspaces at<workspace>.init.localhost.apps/appholds the bare project hostname; every other workspace is prefixed with its directory name. Portless assigns upstream ports dynamically, so hardcoded port numbers becomePORT-aware fallbacks (Number(process.env.PORT ?? <default>)).The Inngest dev server moves from Docker Compose into
packages/workflowsas a proper package workspace.inngest-cli@1.40.0is added as a localdevDependency, thedevanddev:appscripts follow the same Portless pattern as other workspaces, and the Dockerinngestservice is removed. Thedocker:upcommand gains--remove-orphansto clean up the now-removed service.Environment templates for
apps/api,apps/app, andapps/webare updated soBASE_URL,PUBLIC_BASE_URL,PUBLIC_SITE_URL,ALLOWED_API_ORIGINS, andAUTH_TRUSTED_ORIGINSreference the Portless HTTPS origins instead oflocalhostport URLs. Generator templates and the files-client default endpoint are updated to match.scripts/template/portless.tsis introduced withupdatePortlessProjectNameandrestorePortlessWorkspaces.renameProjectinscripts/template/rename.tsnow callsupdatePortlessProjectNameand replaces<scope>.localhostoccurrences whenever a root project rename or scope change occurs; a workspace-only rename (whereprojectNameisundefined) leaves project-wide Portless route names untouched.template addcallsrestorePortlessWorkspacesafter copying a workspace so its route name reflects the current scope.Documentation in
getting-started.mdanddevelopment.mdreplaces the static port table with the named HTTPS URL convention, explains first-run certificate trust,portless doctor, dynamic port assignment, and thePORTLESS=0direct-port fallback. Infrastructure ports for Redis, the database, and Minio remain documented as fixed; the Inngest Docker port is removed.