Skip to content

Commit 7ca8d65

Browse files
authored
chore: migrate BuildConfig to dotenv (#8112)
Replaces the legacy JSON-based BuildConfig system with modern dotenv environment variable configuration. > Re-submission of the BuildConfig portion from #8111, without the Cypress reorganization changes. ### Changes - Deleted `BuildConfig.json` and `BuildConfig.json.example` - Created `.env.example` with minimal required variables (`DB_*`, `POEDITOR_TOKEN`) - Updated 3 locale scripts to use `require('dotenv').config()` - Hardcoded POEditor project ID (77079) in scripts - Simplified GitHub Actions workflow to pass `POEDITOR_TOKEN` as env var only - Added `dotenv` to devDependencies - Updated `.gitignore` to exclude `.env` and `.env.local` - Updated documentation in `locale/README.md` and `scripts/README.md` ### Migration for Developers ```bash cp .env.example .env # Add your POEDITOR_TOKEN value for locale:download and locale:audit tasks # DB_* variables are optional — defaults work for both local and Docker ```
2 parents ea59552 + 6e45607 commit 7ca8d65

File tree

12 files changed

+98
-116
lines changed

12 files changed

+98
-116
lines changed

.env.example

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Database Configuration for locale build scripts
2+
# Both local dev and Docker use the same defaults
3+
DB_HOST=localhost
4+
DB_PORT=3306
5+
DB_NAME=churchcrm
6+
DB_USER=churchcrm
7+
DB_PASSWORD=changeme
8+
9+
# POEditor API Configuration for locale:download and locale:audit
10+
# Get your token from: https://poeditor.com/account/api
11+
POEDITOR_TOKEN=

.github/workflows/locale-poeditor-download.yml

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -90,15 +90,10 @@ jobs:
9090
fi
9191
echo "✅ POEditor token is configured"
9292
93-
- name: Create BuildConfig file
94-
if: inputs.operation_mode != 'audit-only'
95-
uses: jsdaniell/create-json@v1.2.3
96-
with:
97-
name: "BuildConfig.json"
98-
json: '{"POEditor": { "id": "77079", "token": "${{ secrets.POEDITOR_TOKEN }}"}}'
99-
10093
- name: Download locales from POEditor
10194
if: inputs.operation_mode != 'audit-only'
95+
env:
96+
POEDITOR_TOKEN: ${{ secrets.POEDITOR_TOKEN }}
10297
run: |
10398
set -e # Exit on any command failure
10499
echo "🌍 Downloading locales from POEditor..."

.gitignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@
33
.idea/
44
.DS_Store
55

6+
# Environment variables (local and overrides)
7+
.env
8+
.env.local
9+
610
#Exclude folders
711
vendor
812
node_modules
@@ -24,7 +28,6 @@ src/skin/external
2428

2529
# Configuration files with passwords
2630
src/Include/Config.php
27-
BuildConfig.json
2831
orm/propel.php
2932

3033
# Perpl/Propel generated config

BuildConfig.json.example

Lines changed: 0 additions & 25 deletions
This file was deleted.

locale/README.md

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -35,18 +35,22 @@ ChurchCRM uses [POEditor](https://poeditor.com) as the primary translation manag
3535

3636
### Setup Requirements
3737

38-
1. **POEditor Project Configuration**
39-
- Project ID and API token must be configured in `BuildConfig.json`
40-
- See `BuildConfig.json.example` for structure
41-
42-
2. **BuildConfig.json Structure**
43-
```json
44-
{
45-
"POEditor": {
46-
"id": "YOUR_PROJECT_ID",
47-
"token": "YOUR_API_TOKEN"
48-
}
49-
}
38+
1. **Environment Configuration**
39+
- Copy `.env.example` to `.env` (or `.env.local` for local-only overrides)
40+
- Set `POEDITOR_TOKEN` from your POEditor API access (https://poeditor.com/account/api)
41+
- Database credentials default to `localhost/churchcrm/changeme` (works for both local dev and Docker)
42+
43+
2. **.env Configuration**
44+
```bash
45+
# Database (optional - defaults shown)
46+
DB_HOST=localhost
47+
DB_PORT=3306
48+
DB_NAME=churchcrm
49+
DB_USER=churchcrm
50+
DB_PASSWORD=changeme
51+
52+
# POEditor (required for locale:download)
53+
POEDITOR_TOKEN=your_api_token_here
5054
```
5155

5256
### POEditor Workflow
@@ -232,9 +236,9 @@ The system generates several runtime files:
232236
- Verify Gettext files exist in `textdomain/`
233237

234238
2. **POEditor Sync Failures**
235-
- Verify `BuildConfig.json` has correct API credentials
239+
- Verify `POEDITOR_TOKEN` is set in `.env` file
236240
- Check network connectivity to POEditor API
237-
- Ensure project ID matches your POEditor project
241+
- Ensure token has proper POEditor API permissions
238242

239243
3. **Term Extraction Errors**
240244
- Ensure `xgettext` is installed on system

locale/scripts/locale-audit.js

Lines changed: 15 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@
1414
* - Saves comprehensive audit report to locale/poeditor-audit.md
1515
* - No external dependencies (uses Node.js built-ins)
1616
*
17+
* Requires environment variables:
18+
* - POEDITOR_TOKEN (from POEditor API Access)
19+
*
20+
* Note: POEditor project ID is hardcoded as 77079 (ChurchCRM official project)
21+
*
1722
* Output Files:
1823
* - Console: Formatted table output for immediate review
1924
* - src/locale/poeditor.json: Raw API response (for compatibility)
@@ -23,40 +28,29 @@
2328
* reports as they represent base locales rather than translation targets.
2429
*/
2530

31+
require('dotenv').config();
32+
2633
const fs = require('fs');
2734
const path = require('path');
2835
const config = require('./locale-config');
2936

3037
class LocaleAuditor {
3138
constructor() {
32-
this.configPath = config.buildConfigJson;
33-
this.configExamplePath = config.buildConfigExample;
3439
this.localesPath = config.localesJson;
3540
this.outputPath = config.poeditor.outputJson;
3641
this.reportPath = config.poeditor.auditReport;
37-
this.config = null;
42+
this.projectId = '77079'; // ChurchCRM POEditor project ID
43+
this.apiToken = process.env.POEDITOR_TOKEN;
3844
this.locales = null;
3945
}
4046

4147
/**
42-
* Load configuration from BuildConfig.json or BuildConfig.json.example
48+
* Load configuration from environment variables
4349
*/
4450
loadConfig() {
4551
try {
46-
let configFile = this.configPath;
47-
if (!fs.existsSync(this.configPath)) {
48-
if (fs.existsSync(this.configExamplePath)) {
49-
console.log('⚠️ BuildConfig.json not found, using BuildConfig.json.example');
50-
configFile = this.configExamplePath;
51-
} else {
52-
throw new Error(`Configuration file not found: neither ${this.configPath} nor ${this.configExamplePath} exist`);
53-
}
54-
}
55-
56-
this.config = JSON.parse(fs.readFileSync(configFile, 'utf8'));
57-
58-
if (!this.config.POEditor || !this.config.POEditor.token || !this.config.POEditor.id) {
59-
throw new Error('POEditor configuration missing in BuildConfig.json');
52+
if (!this.apiToken) {
53+
throw new Error('POEDITOR_TOKEN environment variable is required');
6054
}
6155

6256
console.log('✅ Configuration loaded successfully');
@@ -93,8 +87,8 @@ class LocaleAuditor {
9387
console.log('🌍 Downloading language statistics from POEditor...');
9488

9589
const formData = new URLSearchParams();
96-
formData.append('api_token', this.config.POEditor.token);
97-
formData.append('id', this.config.POEditor.id);
90+
formData.append('api_token', this.apiToken);
91+
formData.append('id', this.projectId);
9892

9993
const response = await fetch('https://api.poeditor.com/v2/languages/list', {
10094
method: 'POST',
@@ -278,7 +272,7 @@ class LocaleAuditor {
278272
markdown += `- Locales with 📝 **Monitor** (<5% completion) are tracked for future addition when they reach 5%\n`;
279273

280274
markdown += `\n## Technical Notes\n\n`;
281-
markdown += `- **Data Source:** POEditor API (Project ID: ${this.config.POEditor.id})\n`;
275+
markdown += `- **Data Source:** POEditor API (Project ID: ${this.projectId})\n`;
282276
markdown += `- **Audit Script:** \`locale/locale-audit.js\`\n`;
283277
markdown += `- **Configuration:** \`src/locale/locales.json\`\n`;
284278
markdown += `- **Command:** \`npm run locale-audit\`\n\n`;

locale/scripts/locale-build-db.js

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,18 @@
1313
* - Generates PHP files with gettext() calls
1414
* - Handles countries and locales data
1515
*
16+
* Requires environment variables:
17+
* - DB_HOST (default: localhost)
18+
* - DB_PORT (default: 3306)
19+
* - DB_NAME (default: churchcrm)
20+
* - DB_USER (default: churchcrm)
21+
* - DB_PASSWORD (default: changeme)
22+
*
1623
* Output: Creates PHP files in db-strings/ directory for xgettext processing
1724
*/
1825

26+
require('dotenv').config();
27+
1928
const fs = require('fs');
2029
const mysql = require('mysql2/promise');
2130
const path = require('path');
@@ -29,39 +38,29 @@ if (process.argv.includes('--temp-dir')) {
2938

3039
class DatabaseTermExtractor {
3140
constructor() {
32-
this.configPath = config.buildConfigJson;
33-
this.configExamplePath = config.buildConfigExample;
3441
this.stringsDir = config.temp.dbStrings;
3542
this.stringFiles = [];
3643
this.connection = null;
3744
}
3845

3946
/**
40-
* Load database configuration from BuildConfig.json or BuildConfig.json.example
47+
* Load database configuration from environment variables
4148
*/
4249
loadConfig() {
4350
console.log('=====================================================');
4451
console.log('========== Building locale from DB started ==========');
4552
console.log('=====================================================\n');
4653

47-
let configFile = this.configPath;
48-
if (!fs.existsSync(this.configPath)) {
49-
if (fs.existsSync(this.configExamplePath)) {
50-
console.log(`⚠️ BuildConfig.json not found, using BuildConfig.json.example\n`);
51-
configFile = this.configExamplePath;
52-
} else {
53-
throw new Error(`ERROR: Neither ${this.configPath} nor ${this.configExamplePath} exist`);
54-
}
55-
}
56-
57-
const buildConfig = fs.readFileSync(configFile, 'utf8');
58-
const config = JSON.parse(buildConfig);
59-
60-
if (!config.Env?.local?.database) {
61-
throw new Error(`ERROR: The configuration file does not have local db env, check BuildConfig.json.example for schema`);
62-
}
54+
const dbConfig = {
55+
server: process.env.DB_HOST || 'localhost',
56+
port: process.env.DB_PORT || 3306,
57+
database: process.env.DB_NAME || 'churchcrm',
58+
user: process.env.DB_USER || 'churchcrm',
59+
password: process.env.DB_PASSWORD || 'changeme'
60+
};
6361

64-
return config.Env.local.database;
62+
console.log(`📦 Using database: ${dbConfig.user}@${dbConfig.server}:${dbConfig.port}/${dbConfig.database}`);
63+
return dbConfig;
6564
}
6665

6766
/**

locale/scripts/locale-config.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
*
44
* Centralized configuration for all locale build scripts to ensure
55
* consistent paths and settings across the build system.
6+
*
7+
* Configuration is now loaded via environment variables (.env file).
8+
* See .env.example for required variables.
69
*/
710

811
const path = require('path');
@@ -22,8 +25,6 @@ const LocaleConfig = {
2225
i18nDir: path.join(PROJECT_ROOT, 'src/locale/i18n'),
2326
localesDir: path.join(PROJECT_ROOT, 'locale/locales'),
2427

25-
buildConfigJson: path.join(PROJECT_ROOT, 'BuildConfig.json'),
26-
buildConfigExample: path.join(PROJECT_ROOT, 'BuildConfig.json.example'),
2728
i18nextParserConfig: path.join(__dirname, 'i18next-parser.config.js'),
2829

2930
temp: {

locale/scripts/poeditor-downloader.js

Lines changed: 11 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -11,18 +11,20 @@
1111
* npm run locale:download -- --locale fi # Download Finnish only
1212
*
1313
* Requires:
14-
* - BuildConfig.json (or BuildConfig.json.example) with POEditor.id and POEditor.token
14+
* - POEDITOR_TOKEN environment variable (from .env or POEditor API Access)
1515
* - No additional npm packages (uses native https module)
16+
*
17+
* Note: POEditor project ID is hardcoded as 77079 (ChurchCRM official project)
1618
*/
1719

20+
require('dotenv').config();
21+
1822
const fs = require('fs');
1923
const path = require('path');
2024
const https = require('https');
2125
const { URLSearchParams } = require('url');
2226

2327
// Configuration
24-
const CONFIG_FILE = path.join(__dirname, '../../BuildConfig.json');
25-
const CONFIG_EXAMPLE_FILE = path.join(__dirname, '../../BuildConfig.json.example');
2628
const LOCALES_FILE = path.join(__dirname, '../../src/locale/locales.json');
2729
const JSON_OUTPUT_DIR = path.join(__dirname, '../../src/locale/i18n');
2830
const MASTER_LIST_DIR = path.join(__dirname, '../'); // /locale directory for master English list
@@ -38,29 +40,13 @@ const FILE_FORMATS = [
3840
{ type: 'mo', dir: TEXTDOMAIN_OUTPUT_DIR, ext: 'mo', filename: (locale) => `${locale}/LC_MESSAGES/messages.mo` },
3941
];
4042

41-
// Load configuration
42-
let buildConfig;
43-
let configFile = CONFIG_FILE;
44-
try {
45-
if (!fs.existsSync(CONFIG_FILE)) {
46-
if (fs.existsSync(CONFIG_EXAMPLE_FILE)) {
47-
console.log('⚠️ BuildConfig.json not found, using BuildConfig.json.example');
48-
configFile = CONFIG_EXAMPLE_FILE;
49-
} else {
50-
throw new Error('Neither BuildConfig.json nor BuildConfig.json.example exist');
51-
}
52-
}
53-
buildConfig = JSON.parse(fs.readFileSync(configFile, 'utf8'));
54-
} catch (e) {
55-
console.error(`❌ Error reading configuration: ${e.message}`);
56-
process.exit(1);
57-
}
58-
59-
const projectId = buildConfig?.POEditor?.id;
60-
const apiToken = buildConfig?.POEditor?.token;
43+
// Load configuration from environment
44+
const apiToken = process.env.POEDITOR_TOKEN;
45+
const projectId = '77079'; // ChurchCRM POEditor project ID
6146

62-
if (!projectId || !apiToken) {
63-
console.error('❌ Missing POEditor configuration in BuildConfig.json');
47+
if (!apiToken) {
48+
console.error('❌ POEDITOR_TOKEN environment variable is required');
49+
console.error(' Get your token from: https://poeditor.com/account/api');
6450
process.exit(1);
6551
}
6652

package-lock.json

Lines changed: 14 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)