chore: add dev:setup script to generate .env and missing secrets (#7555)

Co-authored-by: pandeymangg <anshuman.pandey9999@gmail.com>
This commit is contained in:
Matti Nannt
2026-03-24 09:26:32 +01:00
committed by GitHub
parent 6da4c6f352
commit 2b49dbecd3
7 changed files with 185 additions and 62 deletions
@@ -32,21 +32,13 @@ icon: "github"
pnpm install
```
4. **Create a `.env` file from the template:**
4. **Create a development `.env` file and generate the required secrets:**
```bash
cp .env.example .env
pnpm dev:setup
```
5. **Generate & set the required secrets:**
```bash
sed -i '/^ENCRYPTION_KEY=/c\ENCRYPTION_KEY='$(openssl rand -hex 32) .env
sed -i '/^NEXTAUTH_SECRET=/c\NEXTAUTH_SECRET='$(openssl rand -hex 32) .env
sed -i '/^CRON_SECRET=/c\CRON_SECRET='$(openssl rand -hex 32) .env
```
6. **Generate the Next.js AGENTS.md file (optional, for AI-assisted development):**
5. **Generate the Next.js AGENTS.md file (optional, for AI-assisted development):**
This step generates an `AGENTS.md` file at the repository root that provides Next.js documentation context for AI coding assistants (e.g. Cursor, GitHub Copilot). It runs `npx @next/codemod agents-md` under the hood. Re-run it whenever you upgrade Next.js.
@@ -54,7 +46,7 @@ icon: "github"
pnpm agents:update
```
7. **Launch the development setup:**
6. **Launch the development setup:**
```bash
pnpm go
```
+4 -12
View File
@@ -32,21 +32,13 @@ icon: "code"
pnpm install
```
4. **Create a `.env` file:**
4. **Create a development `.env` file and generate the required secrets:**
```bash
cp .env.example .env
pnpm dev:setup
```
5. **Generate & set secret values:**
```bash
sed -i '/^ENCRYPTION_KEY=/c\ENCRYPTION_KEY='$(openssl rand -hex 32) .env
sed -i '/^NEXTAUTH_SECRET=/c\NEXTAUTH_SECRET='$(openssl rand -hex 32) .env
sed -i '/^CRON_SECRET=/c\CRON_SECRET='$(openssl rand -hex 32) .env
```
6. **Generate the Next.js AGENTS.md file (optional, for AI-assisted development):**
5. **Generate the Next.js AGENTS.md file (optional, for AI-assisted development):**
This step generates an `AGENTS.md` file at the repository root that provides Next.js documentation context for AI coding assistants (e.g. Cursor, GitHub Copilot). It runs `npx @next/codemod agents-md` under the hood. Re-run it whenever you upgrade Next.js.
@@ -54,7 +46,7 @@ icon: "code"
pnpm agents:update
```
7. **Run the development setup:**
6. **Run the development setup:**
```bash
pnpm go
```
+4 -12
View File
@@ -34,21 +34,13 @@ Here are the requirements for setting up Formbricks on Linux:
pnpm install
```
4. **Create a `.env` file based on `.env.example`:**
4. **Create a development `.env` file and generate the required secrets:**
```bash
cp .env.example .env
pnpm dev:setup
```
5. **Generate & set the secret values:**
```bash
sed -i '/^ENCRYPTION_KEY=/c\ENCRYPTION_KEY='$(openssl rand -hex 32) .env
sed -i '/^NEXTAUTH_SECRET=/c\NEXTAUTH_SECRET='$(openssl rand -hex 32) .env
sed -i '/^CRON_SECRET=/c\CRON_SECRET='$(openssl rand -hex 32) .env
```
6. **Generate the Next.js AGENTS.md file (optional, for AI-assisted development):**
5. **Generate the Next.js AGENTS.md file (optional, for AI-assisted development):**
This step generates an `AGENTS.md` file at the repository root that provides Next.js documentation context for AI coding assistants (e.g. Cursor, GitHub Copilot). It runs `npx @next/codemod agents-md` under the hood. Re-run it whenever you upgrade Next.js.
@@ -56,7 +48,7 @@ Here are the requirements for setting up Formbricks on Linux:
pnpm agents:update
```
7. **Start the development setup:**
6. **Start the development setup:**
```bash
pnpm go
```
+4 -12
View File
@@ -34,21 +34,13 @@ icon: "apple"
pnpm install
```
4. **Create a `.env` file from the example:**
4. **Create a development `.env` file and generate the required secrets:**
```bash
cp .env.example .env
pnpm dev:setup
```
5. **Generate & set secret values (using BSD sed syntax for macOS):**
```bash
sed -i '' '/^ENCRYPTION_KEY=/s|.*|ENCRYPTION_KEY='$(openssl rand -hex 32)'|' .env
sed -i '' '/^NEXTAUTH_SECRET=/s|.*|NEXTAUTH_SECRET='$(openssl rand -hex 32)'|' .env
sed -i '' '/^CRON_SECRET=/s|.*|CRON_SECRET='$(openssl rand -hex 32)'|' .env
```
6. **Generate the Next.js AGENTS.md file (optional, for AI-assisted development):**
5. **Generate the Next.js AGENTS.md file (optional, for AI-assisted development):**
This step generates an `AGENTS.md` file at the repository root that provides Next.js documentation context for AI coding assistants (e.g. Cursor, GitHub Copilot). It runs `npx @next/codemod agents-md` under the hood. Re-run it whenever you upgrade Next.js.
@@ -56,7 +48,7 @@ icon: "apple"
pnpm agents:update
```
7. **Start the development setup:**
6. **Start the development setup:**
```bash
pnpm go
```
+4 -13
View File
@@ -37,22 +37,13 @@ icon: "windows"
pnpm install
```
4. **Create a `.env` file:**
4. **Create a development `.env` file and generate the required secrets:**
```bash
cp .env.example .env
pnpm dev:setup
```
5. **Generate & set secret values (Linux commands work in WSL2):**
```bash
sed -i '/^ENCRYPTION_KEY=/c\ENCRYPTION_KEY='$(openssl rand -hex 32) .env
sed -i '/^NEXTAUTH_SECRET=/c\NEXTAUTH_SECRET='$(openssl rand -hex 32) .env
sed -i '/^CRON_SECRET=/c\CRON_SECRET='$(openssl rand -hex 32) .env
```
6. **Generate the Next.js AGENTS.md file (optional, for AI-assisted development):**
5. **Generate the Next.js AGENTS.md file (optional, for AI-assisted development):**
This step generates an `AGENTS.md` file at the repository root that provides Next.js documentation context for AI coding assistants (e.g. Cursor, GitHub Copilot). It runs `npx @next/codemod agents-md` under the hood. Re-run it whenever you upgrade Next.js.
@@ -60,7 +51,7 @@ icon: "windows"
pnpm agents:update
```
7. **Start the development setup:**
6. **Start the development setup:**
```bash
pnpm go
```
+2 -1
View File
@@ -42,7 +42,8 @@
"generate-translations": "pnpm i18n:web:generate && pnpm i18n:surveys:generate",
"scan-translations": "pnpm --filter @formbricks/i18n-utils scan-translations",
"i18n": "pnpm generate-translations && pnpm scan-translations",
"i18n:validate": "pnpm scan-translations"
"i18n:validate": "pnpm scan-translations",
"dev:setup": "bash scripts/setup-dev-env.sh"
},
"dependencies": {
"react": "19.2.4",
+163
View File
@@ -0,0 +1,163 @@
#!/usr/bin/env bash
set -euo pipefail
readonly SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
readonly REPO_ROOT="$(cd -- "${SCRIPT_DIR}/.." && pwd)"
readonly ENV_TEMPLATE_PATH="${REPO_ROOT}/.env.example"
readonly ENV_PATH="${REPO_ROOT}/.env"
readonly REQUIRED_GENERATED_KEYS=("ENCRYPTION_KEY" "NEXTAUTH_SECRET" "CRON_SECRET")
TEMP_FILE=""
cleanup() {
if [[ -n "${TEMP_FILE}" && -f "${TEMP_FILE}" ]]; then
rm -f "${TEMP_FILE}"
fi
}
trap cleanup EXIT
log() {
printf '%s\n' "$1"
}
fail() {
printf 'Error: %s\n' "$1" >&2
exit 1
}
require_command() {
if ! command -v "$1" >/dev/null 2>&1; then
fail "Required command not found: $1"
fi
}
ensure_prerequisites() {
require_command "awk"
require_command "mktemp"
require_command "openssl"
}
ensure_env_template_exists() {
if [[ ! -f "${ENV_TEMPLATE_PATH}" ]]; then
fail "Could not find template file at ${ENV_TEMPLATE_PATH}"
fi
}
copy_env_template_if_missing() {
if [[ -f "${ENV_PATH}" ]]; then
return 1
fi
cp "${ENV_TEMPLATE_PATH}" "${ENV_PATH}"
return 0
}
read_env_value() {
local key="$1"
awk -F= -v key="${key}" '
$0 ~ "^[[:space:]]*" key "[[:space:]]*=" {
value = substr($0, index($0, "=") + 1)
gsub(/^[[:space:]]+|[[:space:]]+$/, "", value)
if ((value ~ /^".*"$/) || (value ~ /^'\''.*'\''$/)) {
value = substr(value, 2, length(value) - 2)
}
print value
exit
}
' "${ENV_PATH}"
}
is_valid_encryption_key() {
local value="${1-}"
[[ ${#value} -eq 32 || "${value}" =~ ^[[:xdigit:]]{64}$ ]]
}
should_generate_secret() {
local key="$1"
local value="${2-}"
if [[ -z "${value}" ]]; then
return 0
fi
if [[ "${key}" == "ENCRYPTION_KEY" ]] && ! is_valid_encryption_key "${value}"; then
return 0
fi
return 1
}
upsert_env_value() {
local key="$1"
local value="$2"
TEMP_FILE="$(mktemp "${ENV_PATH}.tmp.XXXXXX")"
awk -v key="${key}" -v value="${value}" '
BEGIN {
replaced = 0
}
$0 ~ "^[[:space:]]*" key "[[:space:]]*=" {
print key "=" value
replaced = 1
next
}
{
print
}
END {
if (!replaced) {
print key "=" value
}
}
' "${ENV_PATH}" > "${TEMP_FILE}"
mv "${TEMP_FILE}" "${ENV_PATH}"
TEMP_FILE=""
}
main() {
local env_created="false"
local updated_keys=()
local key=""
local current_value=""
ensure_prerequisites
ensure_env_template_exists
if copy_env_template_if_missing; then
env_created="true"
fi
for key in "${REQUIRED_GENERATED_KEYS[@]}"; do
current_value="$(read_env_value "${key}")"
if should_generate_secret "${key}" "${current_value}"; then
upsert_env_value "${key}" "$(openssl rand -hex 32)"
updated_keys+=("${key}")
fi
done
if [[ "${env_created}" == "true" ]]; then
log "Created .env from .env.example."
else
log "Using existing .env."
fi
if [[ ${#updated_keys[@]} -gt 0 ]]; then
log "Updated generated secrets: ${updated_keys[*]}."
else
log ".env already contains all required generated secrets."
fi
log "Development environment file is ready."
}
main "$@"