From 4aa4868a5472587d86b978fba68750403fad8156 Mon Sep 17 00:00:00 2001 From: Tom Moor Date: Thu, 29 Jan 2026 21:08:35 -0500 Subject: [PATCH] feat: Add Heroku Review Apps support for preview deployments (#11304) - Add pr-predeploy script and review environment config in app.json - Use smaller addon tiers for review apps to reduce costs - Auto-derive URL from HEROKU_APP_NAME when URL is not set - Make URL optional for review apps Co-authored-by: Claude Opus 4.5 --- app.json | 26 +++++++++++++++++++++++--- server/env.ts | 8 +++++++- 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/app.json b/app.json index e6a3a00515..8efb67cf44 100644 --- a/app.json +++ b/app.json @@ -21,7 +21,23 @@ } ], "scripts": { - "postdeploy": "yarn sequelize db:migrate" + "postdeploy": "yarn sequelize db:migrate", + "pr-predeploy": "yarn sequelize db:migrate" + }, + "environments": { + "review": { + "scripts": { + "postdeploy": "yarn sequelize db:migrate" + }, + "addons": [ + { + "plan": "heroku-redis:mini" + }, + { + "plan": "heroku-postgresql:essential-0" + } + ] + } }, "env": { "NODE_ENV": { @@ -43,8 +59,12 @@ "required": true }, "URL": { - "description": "https://{your app name}.herokuapp.com, or the domain you are binding to", - "required": true + "description": "https://{your app name}.herokuapp.com, or the domain you are binding to. For review apps, this is auto-generated.", + "required": false + }, + "HEROKU_APP_NAME": { + "description": "Automatically set by Heroku for review apps", + "required": false }, "GOOGLE_CLIENT_ID": { "description": "See https://developers.google.com/identity/protocols/OAuth2 to create a new Google OAuth client. You must configure at least one of Slack or Google to control login.", diff --git a/server/env.ts b/server/env.ts index 9e39773edd..e34a5fd882 100644 --- a/server/env.ts +++ b/server/env.ts @@ -200,6 +200,7 @@ export class Environment { /** * The fully qualified, external facing domain name of the server. + * If not set, will be derived from HEROKU_APP_NAME for Heroku deployments. */ @Public @IsNotEmpty() @@ -208,7 +209,12 @@ export class Environment { require_protocol: true, require_tld: false, }) - public URL = (environment.URL ?? "").replace(/\/$/, ""); + public URL = ( + environment.URL ?? + (environment.HEROKU_APP_NAME + ? `https://${environment.HEROKU_APP_NAME}.herokuapp.com` + : "") + ).replace(/\/$/, ""); /** * If using a Cloudfront/Cloudflare distribution or similar it can be set below.