feat: Implement configuration bundling for customer-specific builds and enhance build scripts
This commit is contained in:
parent
4e5deab7e9
commit
a355c13c82
5 changed files with 750 additions and 22 deletions
162
docs/CONFIGURATION_BUILD.md
Normal file
162
docs/CONFIGURATION_BUILD.md
Normal file
|
|
@ -0,0 +1,162 @@
|
|||
# Configuration Management for Builds
|
||||
|
||||
This document explains how configuration is handled when building executables and installers for WebDrop Bridge.
|
||||
|
||||
## Overview
|
||||
|
||||
WebDrop Bridge uses `.env` files for runtime configuration. When building distributable packages (exe, MSI, or DMG), the `.env` file is **bundled into the application** so that users receive pre-configured settings.
|
||||
|
||||
## Configuration File
|
||||
|
||||
The configuration file must be named `.env` and contains settings like:
|
||||
|
||||
```dotenv
|
||||
APP_NAME=WebDrop Bridge
|
||||
APP_VERSION=0.1.0
|
||||
WEBAPP_URL=https://example.com
|
||||
ALLOWED_ROOTS=Z:/,C:/Users/Public
|
||||
ALLOWED_URLS=
|
||||
LOG_LEVEL=INFO
|
||||
LOG_FILE=logs/webdrop_bridge.log
|
||||
ENABLE_LOGGING=true
|
||||
WINDOW_WIDTH=1024
|
||||
WINDOW_HEIGHT=768
|
||||
```
|
||||
|
||||
See `.env.example` for a template with all available options.
|
||||
|
||||
## Building with Default Configuration
|
||||
|
||||
If you want to use the project's `.env` file (in the project root), simply run:
|
||||
|
||||
### Windows
|
||||
```bash
|
||||
python build/scripts/build_windows.py --msi
|
||||
```
|
||||
|
||||
### macOS
|
||||
```bash
|
||||
bash build/scripts/build_macos.sh
|
||||
```
|
||||
|
||||
**Important:** The build will **fail** if `.env` doesn't exist. This prevents accidentally shipping without configuration.
|
||||
|
||||
## Building with Custom Configuration
|
||||
|
||||
For different customers or deployments, you can specify a custom `.env` file:
|
||||
|
||||
### Windows
|
||||
```bash
|
||||
python build/scripts/build_windows.py --msi --env-file path/to/customer1.env
|
||||
```
|
||||
|
||||
### macOS
|
||||
```bash
|
||||
bash build/scripts/build_macos.sh --env-file path/to/customer1.env
|
||||
```
|
||||
|
||||
The custom `.env` file will be bundled into the executable and users will receive those pre-configured settings.
|
||||
|
||||
## Example: Multi-Customer Setup
|
||||
|
||||
If you have different customer configurations:
|
||||
|
||||
```
|
||||
webdrop_bridge/
|
||||
├── .env # Default project configuration
|
||||
├── .env.example # Template
|
||||
├── build/
|
||||
│ └── scripts/
|
||||
│ ├── build_windows.py
|
||||
│ └── build_macos.sh
|
||||
├── customer_configs/ # Create this for customer-specific settings
|
||||
│ ├── acme_corp.env
|
||||
│ ├── globex_corporation.env
|
||||
│ └── initech.env
|
||||
└── ...
|
||||
```
|
||||
|
||||
Then build for each customer:
|
||||
|
||||
```bash
|
||||
# ACME Corp
|
||||
python build/scripts/build_windows.py --msi --env-file customer_configs/acme_corp.env
|
||||
|
||||
# Globex Corporation
|
||||
python build/scripts/build_windows.py --msi --env-file customer_configs/globex_corporation.env
|
||||
|
||||
# Initech
|
||||
python build/scripts/build_windows.py --msi --env-file customer_configs/initech.env
|
||||
```
|
||||
|
||||
Each MSI will include that customer's specific configuration (URLs, allowed paths, etc.).
|
||||
|
||||
## What Gets Bundled
|
||||
|
||||
When building, the `.env` file is:
|
||||
1. ✅ Copied into the PyInstaller bundle
|
||||
2. ✅ Extracted to the application's working directory when the app starts
|
||||
3. ✅ Automatically loaded by `Config.from_env()` at startup
|
||||
|
||||
Users **do not** need to create their own `.env` files.
|
||||
|
||||
## After Installation
|
||||
|
||||
When users run the installed application:
|
||||
1. The embedded `.env` is automatically available
|
||||
2. Settings are loaded and applied
|
||||
3. Users can optionally create a custom `.env` in the installation directory to override settings
|
||||
|
||||
This allows:
|
||||
- **Pre-configured deployments** for your customers
|
||||
- **Easy customization** by users (just edit the `.env` file)
|
||||
- **No manual setup** required after installation
|
||||
|
||||
## Build Command Reference
|
||||
|
||||
### Windows
|
||||
```bash
|
||||
# Default (.env from project root)
|
||||
python build/scripts/build_windows.py --msi
|
||||
|
||||
# Custom .env file
|
||||
python build/scripts/build_windows.py --msi --env-file customer_configs/acme.env
|
||||
|
||||
# Without MSI (just EXE)
|
||||
python build/scripts/build_windows.py
|
||||
|
||||
# Sign executable (requires CODE_SIGN_CERT env var)
|
||||
python build/scripts/build_windows.py --msi --code-sign
|
||||
```
|
||||
|
||||
### macOS
|
||||
```bash
|
||||
# Default (.env from project root)
|
||||
bash build/scripts/build_macos.sh
|
||||
|
||||
# Custom .env file
|
||||
bash build/scripts/build_macos.sh --env-file customer_configs/acme.env
|
||||
|
||||
# Sign app (requires Apple developer certificate)
|
||||
bash build/scripts/build_macos.sh --sign
|
||||
|
||||
# Notarize app (requires Apple ID)
|
||||
bash build/scripts/build_macos.sh --notarize
|
||||
```
|
||||
|
||||
## Configuration Validation
|
||||
|
||||
The build process validates that:
|
||||
1. ✅ The specified `.env` file exists
|
||||
2. ✅ All required environment variables are present
|
||||
3. ✅ Values are valid (LOG_LEVEL is valid, paths exist for ALLOWED_ROOTS, etc.)
|
||||
|
||||
If validation fails, the build stops with a clear error message.
|
||||
|
||||
## Version Management
|
||||
|
||||
The `APP_VERSION` is read from two places (in order):
|
||||
1. `.env` file (if specified)
|
||||
2. `src/webdrop_bridge/__init__.py` (as fallback)
|
||||
|
||||
This allows you to override the version per customer if needed.
|
||||
299
docs/CUSTOMER_BUILD_EXAMPLES.md
Normal file
299
docs/CUSTOMER_BUILD_EXAMPLES.md
Normal file
|
|
@ -0,0 +1,299 @@
|
|||
# Customer-Specific Build Examples
|
||||
|
||||
This document shows practical examples of how to build WebDrop Bridge for different customers or deployment scenarios.
|
||||
|
||||
## Scenario 1: Single Build with Default Configuration
|
||||
|
||||
**Situation:** You have one main configuration for your primary customer or general use.
|
||||
|
||||
**Setup:**
|
||||
```
|
||||
webdrop_bridge/
|
||||
├── .env # Your main configuration
|
||||
└── build/
|
||||
└── scripts/
|
||||
└── build_windows.py
|
||||
```
|
||||
|
||||
**Build Command:**
|
||||
```bash
|
||||
python build/scripts/build_windows.py --msi
|
||||
```
|
||||
|
||||
**Result:** `WebDropBridge-x.x.x-Setup.msi` with your `.env` configuration bundled.
|
||||
|
||||
---
|
||||
|
||||
## Scenario 2: Multi-Customer Builds
|
||||
|
||||
**Situation:** You support multiple customers, each with different URLs, allowed paths, etc.
|
||||
|
||||
**Setup:**
|
||||
```
|
||||
webdrop_bridge/
|
||||
├── .env # Default project config
|
||||
├── build/
|
||||
│ └── scripts/
|
||||
│ └── build_windows.py
|
||||
└── deploy/ # Create this directory
|
||||
└── customer_configs/
|
||||
├── README.md
|
||||
├── acme_corp.env
|
||||
├── globex_corporation.env
|
||||
├── initech.env
|
||||
└── wayne_enterprises.env
|
||||
```
|
||||
|
||||
**Customer Config Example:** `deploy/customer_configs/acme_corp.env`
|
||||
```dotenv
|
||||
APP_NAME=WebDrop Bridge - ACME Corp Edition
|
||||
APP_VERSION=1.0.0
|
||||
WEBAPP_URL=https://acme-drop.example.com/drop
|
||||
ALLOWED_ROOTS=Z:/acme_files/,C:/Users/Public/ACME
|
||||
LOG_LEVEL=INFO
|
||||
LOG_FILE=logs/webdrop_bridge.log
|
||||
ENABLE_LOGGING=true
|
||||
WINDOW_WIDTH=1024
|
||||
WINDOW_HEIGHT=768
|
||||
```
|
||||
|
||||
**Build Commands:**
|
||||
```bash
|
||||
# Build for ACME Corp
|
||||
python build/scripts/build_windows.py --msi --env-file deploy/customer_configs/acme_corp.env
|
||||
|
||||
# Build for Globex
|
||||
python build/scripts/build_windows.py --msi --env-file deploy/customer_configs/globex_corporation.env
|
||||
|
||||
# Build for Initech
|
||||
python build/scripts/build_windows.py --msi --env-file deploy/customer_configs/initech.env
|
||||
|
||||
# Build for Wayne Enterprises
|
||||
python build/scripts/build_windows.py --msi --env-file deploy/customer_configs/wayne_enterprises.env
|
||||
```
|
||||
|
||||
**Result:** Four separate MSI files:
|
||||
- `WebDropBridge-1.0.0-Setup.msi` (ACME - says "ACME Corp Edition")
|
||||
- `WebDropBridge-1.0.0-Setup.msi` (Globex - say "Globex Edition")
|
||||
- etc.
|
||||
|
||||
---
|
||||
|
||||
## Scenario 3: Development vs. Production Builds
|
||||
|
||||
**Situation:** You want different settings for internal testing vs. customer releases.
|
||||
|
||||
**Setup:**
|
||||
```
|
||||
webdrop_bridge/
|
||||
├── .env # Production config (primary)
|
||||
├── build/
|
||||
│ └── scripts/
|
||||
│ └── build_windows.py
|
||||
└── build_configs/
|
||||
├── development.env # For internal testing
|
||||
├── staging.env # Pre-production testing
|
||||
└── production.env # For customers (same as project .env)
|
||||
```
|
||||
|
||||
**Development Config:** `build_configs/development.env`
|
||||
```dotenv
|
||||
APP_NAME=WebDrop Bridge DEV
|
||||
WEBAPP_URL=http://localhost:3000
|
||||
LOG_LEVEL=DEBUG
|
||||
LOG_FILE=logs/webdrop_bridge.log
|
||||
ENABLE_LOGGING=true
|
||||
WINDOW_WIDTH=1024
|
||||
WINDOW_HEIGHT=768
|
||||
```
|
||||
|
||||
**Build Commands:**
|
||||
```bash
|
||||
# Development build (for testing)
|
||||
python build/scripts/build_windows.py --env-file build_configs/development.env
|
||||
|
||||
# Staging build (pre-release testing)
|
||||
python build/scripts/build_windows.py --env-file build_configs/staging.env
|
||||
|
||||
# Production build (for customers)
|
||||
python build/scripts/build_windows.py --msi
|
||||
# OR explicitly:
|
||||
python build/scripts/build_windows.py --msi --env-file build_configs/production.env
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Scenario 4: Building with Code Signing
|
||||
|
||||
**Situation:** You have a code signing certificate and want to sign releases.
|
||||
|
||||
**Prerequisites:**
|
||||
- Set environment variable: `CODE_SIGN_CERT=path/to/certificate.pfx`
|
||||
- Set environment variable: `CODE_SIGN_PASSWORD=your_password`
|
||||
|
||||
**Build Command:**
|
||||
```bash
|
||||
python build/scripts/build_windows.py --msi --code-sign --env-file deploy/customer_configs/acme_corp.env
|
||||
```
|
||||
|
||||
**Result:** Signed MSI installer ready for enterprise deployment.
|
||||
|
||||
---
|
||||
|
||||
## Scenario 5: Automated Build Pipeline
|
||||
|
||||
**Situation:** You have multiple customers and want to automate builds.
|
||||
|
||||
**Script:** `build_all_customers.ps1`
|
||||
```powershell
|
||||
# Build WebDrop Bridge for all customers
|
||||
|
||||
$PROJECT_ROOT = "C:\Development\VS Code Projects\webdrop_bridge"
|
||||
$CONFIG_DIR = "$PROJECT_ROOT\deploy\customer_configs"
|
||||
$BUILD_SCRIPT = "$PROJECT_ROOT\build\scripts\build_windows.py"
|
||||
|
||||
# Get all .env files for customers
|
||||
$customerConfigs = @(
|
||||
"acme_corp.env",
|
||||
"globex_corporation.env",
|
||||
"initech.env",
|
||||
"wayne_enterprises.env"
|
||||
)
|
||||
|
||||
$timestamp = Get-Date -Format "yyyy-MM-dd_HH-mm-ss"
|
||||
$output_dir = "$PROJECT_ROOT\build\releases\$timestamp"
|
||||
New-Item -ItemType Directory -Path $output_dir -Force | Out-Null
|
||||
|
||||
Write-Host "🚀 Building WebDrop Bridge for all customers..." -ForegroundColor Cyan
|
||||
Write-Host ""
|
||||
|
||||
foreach ($config in $customerConfigs) {
|
||||
$customer_name = $config -replace '\.env$', ''
|
||||
$config_path = "$CONFIG_DIR\$config"
|
||||
|
||||
Write-Host "Building for $customer_name..." -ForegroundColor Yellow
|
||||
|
||||
# Build
|
||||
python $BUILD_SCRIPT --msi --env-file "$config_path"
|
||||
|
||||
# Copy to output directory
|
||||
$msi_file = Get-ChildItem "$PROJECT_ROOT\build\dist\windows\*.msi" | Sort-Object LastWriteTime | Select-Object -Last 1
|
||||
if ($msi_file) {
|
||||
Copy-Item $msi_file.FullName "$output_dir\WebDropBridge-${customer_name}.msi"
|
||||
Write-Host "✅ Built: WebDropBridge-${customer_name}.msi" -ForegroundColor Green
|
||||
}
|
||||
|
||||
Write-Host ""
|
||||
}
|
||||
|
||||
Write-Host "✅ All builds complete!" -ForegroundColor Green
|
||||
Write-Host "📦 Outputs in: $output_dir"
|
||||
```
|
||||
|
||||
**Run:**
|
||||
```bash
|
||||
.\build_all_customers.ps1
|
||||
```
|
||||
|
||||
**Result:** All customer builds in a timestamped directory:
|
||||
```
|
||||
build/releases/2024-01-30_14-30-00/
|
||||
├── WebDropBridge-acme_corp.msi
|
||||
├── WebDropBridge-globex_corporation.msi
|
||||
├── WebDropBridge-initech.msi
|
||||
└── WebDropBridge-wayne_enterprises.msi
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Configuration Best Practices
|
||||
|
||||
### 1. **Version Numbers**
|
||||
Keep APP_VERSION in sync across all builds. Options:
|
||||
- Use project `.env` with single source of truth
|
||||
- Or explicitly set in each customer config
|
||||
|
||||
### 2. **Naming Convention**
|
||||
Customer configs:
|
||||
```
|
||||
deploy/customer_configs/
|
||||
├── {customer_name_lowercase}.env
|
||||
├── {customer_name_lowercase}-staging.env
|
||||
└── {customer_name_lowercase}-dev.env
|
||||
```
|
||||
|
||||
### 3. **Security**
|
||||
- Don't commit customer configs to git (if they contain sensitive URLs)
|
||||
- Use `.gitignore`: `deploy/customer_configs/*.env` (but keep template)
|
||||
- Store customer configs in secure location (separate backup/version control)
|
||||
|
||||
### 4. **Documentation**
|
||||
In each customer config, add comments:
|
||||
```dotenv
|
||||
# WebDropBridge Configuration - ACME Corp
|
||||
# Last updated: 2024-01-30
|
||||
# Contact: support@acmecorp.com
|
||||
|
||||
# The web application they'll connect to
|
||||
WEBAPP_URL=https://acme-drop.example.com/drop
|
||||
|
||||
# Directories they can access
|
||||
ALLOWED_ROOTS=Z:/acme_files/,C:/Users/Public/ACME
|
||||
```
|
||||
|
||||
### 5. **Testing**
|
||||
Before building for a customer:
|
||||
1. Copy their config to `.env` in project root
|
||||
2. Run the app: `python src/webdrop_bridge/main.py`
|
||||
3. Test the configuration loads correctly
|
||||
4. Then build: `python build/scripts/build_windows.py --msi`
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### "Configuration file not found"
|
||||
**Problem:** `.env` file specified with `--env-file` doesn't exist.
|
||||
|
||||
**Solution:**
|
||||
```bash
|
||||
# Check the file exists
|
||||
ls deploy/customer_configs/acme_corp.env
|
||||
|
||||
# Use full path if relative path doesn't work
|
||||
python build/scripts/build_windows.py --msi --env-file C:\full\path\to\acme_corp.env
|
||||
```
|
||||
|
||||
### Build fails with no --env-file specified
|
||||
**Problem:** Project root `.env` doesn't exist, but no `--env-file` provided.
|
||||
|
||||
**Solution:**
|
||||
```bash
|
||||
# Option 1: Create .env in project root
|
||||
copy .env.example .env
|
||||
# Edit .env as needed
|
||||
|
||||
# Option 2: Specify custom location
|
||||
python build/scripts/build_windows.py --msi --env-file deploy/customer_configs/your_config.env
|
||||
```
|
||||
|
||||
### App shows wrong configuration
|
||||
**Problem:** Built app has old configuration.
|
||||
|
||||
**Solution:**
|
||||
1. Delete previous build: `rmdir /s build\dist`
|
||||
2. Verify you're using correct `.env`:
|
||||
- Check with `python build/scripts/build_windows.py --help`
|
||||
- Look at the console output during build: "📋 Using configuration: ..."
|
||||
3. Rebuild
|
||||
|
||||
---
|
||||
|
||||
## Summary
|
||||
|
||||
With the new configuration bundling system, you can:
|
||||
- ✅ Build once, configure for different customers
|
||||
- ✅ Maintain centralized customer configurations
|
||||
- ✅ Automate multi-customer builds
|
||||
- ✅ Deploy to different environments (dev/staging/prod)
|
||||
- ✅ No manual customer setup required after installation
|
||||
Loading…
Add table
Add a link
Reference in a new issue