Fix: Make CI .env manipulation robust against missing trailing newlines (#15189)
## Problem CI workflow started timing out on October 14, 2025 after commit `d750df7fff` removed the trailing newline from `.env.example`. ## Root Cause When `.env.example` lacks a trailing newline: ```bash # Last line without newline # CLICKHOUSE_URL=...twenty ``` And CI runs: ```bash echo "NODE_PORT=3002" >> .env ``` Result: ```bash # CLICKHOUSE_URL=...twentyNODE_PORT=3002 ← Commented out! ``` Server starts on default port 3000 instead of 3002, health check fails. ## Fix 1. **Restore trailing newline** to `.env.example` 2. **Make all CI `.env` operations robust** by adding `echo "" >> .env` before appending 3. **Simplified `set_env_var`** function to always add newline first Now works regardless of whether template files have trailing newlines. ## Files Changed - 6 CI workflow files - 1 .env.example file
This commit is contained in:
@@ -124,13 +124,14 @@ jobs:
|
||||
- name: Setup current branch database
|
||||
run: |
|
||||
npx nx reset:env twenty-server
|
||||
# Function to set or update environment variable
|
||||
set_env_var() {
|
||||
local var_name="$1"
|
||||
local var_value="$2"
|
||||
local env_file="packages/twenty-server/.env"
|
||||
|
||||
if grep -q "^${var_name}=" "$env_file"; then
|
||||
echo "" >> "$env_file"
|
||||
|
||||
if grep -q "^${var_name}=" "$env_file" 2>/dev/null; then
|
||||
sed -i "s|^${var_name}=.*|${var_name}=${var_value}|" "$env_file"
|
||||
else
|
||||
echo "${var_name}=${var_value}" >> "$env_file"
|
||||
@@ -276,13 +277,14 @@ jobs:
|
||||
- name: Setup main branch database
|
||||
run: |
|
||||
npx nx reset:env twenty-server
|
||||
# Function to set or update environment variable
|
||||
set_env_var() {
|
||||
local var_name="$1"
|
||||
local var_value="$2"
|
||||
local env_file="packages/twenty-server/.env"
|
||||
|
||||
if grep -q "^${var_name}=" "$env_file"; then
|
||||
echo "" >> "$env_file"
|
||||
|
||||
if grep -q "^${var_name}=" "$env_file" 2>/dev/null; then
|
||||
sed -i "s|^${var_name}=.*|${var_name}=${var_value}|" "$env_file"
|
||||
else
|
||||
echo "${var_name}=${var_value}" >> "$env_file"
|
||||
|
||||
@@ -81,6 +81,7 @@ jobs:
|
||||
- name: Server / Append billing config to .env.test
|
||||
working-directory: packages/twenty-server
|
||||
run: |
|
||||
echo "" >> .env.test
|
||||
echo "IS_BILLING_ENABLED=true" >> .env.test
|
||||
echo "BILLING_STRIPE_API_KEY=test-api-key" >> .env.test
|
||||
echo "BILLING_STRIPE_BASE_PLAN_PRODUCT_ID=test-base-plan-product-id" >> .env.test
|
||||
|
||||
@@ -140,6 +140,7 @@ jobs:
|
||||
run: |
|
||||
cd packages/twenty-front
|
||||
touch .env
|
||||
echo "" >> .env
|
||||
echo "REACT_APP_SERVER_BASE_URL: $REACT_APP_SERVER_BASE_URL" >> .env
|
||||
- name: Publish to Chromatic
|
||||
run: npx nx run twenty-front:chromatic:ci
|
||||
|
||||
@@ -218,6 +218,7 @@ jobs:
|
||||
uses: ./.github/workflows/actions/yarn-install
|
||||
- name: Update .env.test for integrations tests
|
||||
run: |
|
||||
echo "" >> .env.test
|
||||
echo "IS_BILLING_ENABLED=true" >> .env.test
|
||||
echo "BILLING_STRIPE_API_KEY=test-api-key" >> .env.test
|
||||
echo "BILLING_STRIPE_BASE_PLAN_PRODUCT_ID=test-base-plan-product-id" >> .env.test
|
||||
|
||||
@@ -33,6 +33,7 @@ jobs:
|
||||
echo "Setting up .env file..."
|
||||
cp .env.example .env
|
||||
echo "Generating secrets..."
|
||||
echo "" >> .env
|
||||
echo "# === Randomly generated secrets ===" >>.env
|
||||
echo "APP_SECRET=$(openssl rand -base64 32)" >>.env
|
||||
echo "PGPASSWORD_SUPERUSER=$(openssl rand -hex 16)" >>.env
|
||||
|
||||
@@ -37,6 +37,7 @@ jobs:
|
||||
cp packages/twenty-docker/.env.example packages/twenty-docker/.env
|
||||
|
||||
echo "Generating secrets..."
|
||||
echo "" >> packages/twenty-docker/.env
|
||||
echo "# === Randomly generated secrets ===" >> packages/twenty-docker/.env
|
||||
echo "APP_SECRET=$(openssl rand -base64 32)" >> packages/twenty-docker/.env
|
||||
echo "PG_DATABASE_PASSWORD=$(openssl rand -hex 16)" >> packages/twenty-docker/.env
|
||||
@@ -60,6 +61,7 @@ jobs:
|
||||
# Update the SERVER_URL with the tunnel URL
|
||||
echo "Setting SERVER_URL to ${{ steps.expose-tunnel.outputs.tunnel-url }}"
|
||||
sed -i '/SERVER_URL=/d' .env
|
||||
echo "" >> .env
|
||||
echo "SERVER_URL=${{ steps.expose-tunnel.outputs.tunnel-url }}" >> .env
|
||||
|
||||
# Start the services
|
||||
|
||||
@@ -78,4 +78,5 @@ FRONTEND_URL=http://localhost:3001
|
||||
# CLOUDFLARE_WEBHOOK_SECRET=
|
||||
# IS_CONFIG_VARIABLES_IN_DB_ENABLED=false
|
||||
# ANALYTICS_ENABLED=
|
||||
# CLICKHOUSE_URL=http://default:clickhousePassword@localhost:8123/twenty
|
||||
# CLICKHOUSE_URL=http://default:clickhousePassword@localhost:8123/twenty
|
||||
|
||||
|
||||
@@ -23,4 +23,4 @@ MESSAGING_PROVIDER_GMAIL_CALLBACK_URL=http://localhost:3000/auth/google-gmail/ge
|
||||
AUTH_MICROSOFT_CALLBACK_URL=http://localhost:3000/auth/microsoft/redirect
|
||||
AUTH_MICROSOFT_APIS_CALLBACK_URL=http://localhost:3000/auth/microsoft-apis/get-access-token
|
||||
|
||||
CLICKHOUSE_URL=http://default:clickhousePassword@localhost:8123/twenty
|
||||
CLICKHOUSE_URL=http://default:clickhousePassword@localhost:8123/twenty
|
||||
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
import { type DataSource } from 'typeorm';
|
||||
|
||||
const tableName = 'billingCustomer';
|
||||
|
||||
export const seedBillingCustomers = async (
|
||||
dataSource: DataSource,
|
||||
schemaName: string,
|
||||
workspaceId: string,
|
||||
) => {
|
||||
await dataSource
|
||||
.createQueryBuilder()
|
||||
.insert()
|
||||
.into(`${schemaName}.${tableName}`, ['workspaceId', 'stripeCustomerId'])
|
||||
.orIgnore()
|
||||
.values([
|
||||
{
|
||||
workspaceId,
|
||||
stripeCustomerId: 'cus_default0',
|
||||
},
|
||||
])
|
||||
.execute();
|
||||
};
|
||||
+2
@@ -1,5 +1,6 @@
|
||||
import { type DataSource } from 'typeorm';
|
||||
|
||||
import { seedBillingCustomers } from 'src/engine/workspace-manager/dev-seeder/core/billing/utils/seed-billing-customers.util';
|
||||
import { seedBillingSubscriptions } from 'src/engine/workspace-manager/dev-seeder/core/billing/utils/seed-billing-subscriptions.util';
|
||||
import { seedAgents } from 'src/engine/workspace-manager/dev-seeder/core/utils/seed-agents.util';
|
||||
import { seedApiKeys } from 'src/engine/workspace-manager/dev-seeder/core/utils/seed-api-keys.util';
|
||||
@@ -43,6 +44,7 @@ export const seedCoreSchema = async ({
|
||||
}
|
||||
|
||||
if (seedBilling) {
|
||||
await seedBillingCustomers(dataSource, schemaName, workspaceId);
|
||||
await seedBillingSubscriptions(dataSource, schemaName, workspaceId);
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user