Refactor database environment variable usage across workflows and application code
All checks were successful
Deploy to Web Server flyer-crawler.projectium.com / deploy (push) Successful in 3m53s

- Updated Gitea workflows to standardize on `DB_NAME` instead of `DB_DATABASE` for database name references.
- Modified deployment, backup, reset, and restore workflows to ensure consistent environment variable usage.
- Removed dotenv dependency and preload script, transitioning to environment variable management directly in scripts.
- Adjusted application code to utilize `DB_NAME` for database connections and logging.
- Enhanced README to reflect changes in environment variable configuration and usage.
- Cleaned up package.json scripts to remove unnecessary preload references.
This commit is contained in:
2025-12-04 18:02:38 -08:00
parent 80d2b1ffe6
commit 9d552b7456
22 changed files with 127 additions and 176 deletions

View File

@@ -85,8 +85,7 @@ jobs:
DB_PORT: ${{ secrets.DB_PORT }}
DB_USER: ${{ secrets.DB_USER }}
DB_PASSWORD: ${{ secrets.DB_PASSWORD }}
DB_DATABASE: "flyer-crawler-test"
DB_NAME: "flyer-crawler-test"
DB_NAME: "flyer-crawler-test" # Explicitly set for tests
# --- Redis credentials for the test suite ---
REDIS_URL: "redis://localhost:6379"
@@ -103,7 +102,7 @@ jobs:
run: |
# Fail-fast check to ensure secrets are configured in Gitea for testing.
if [ -z "$DB_HOST" ] || [ -z "$DB_USER" ] || [ -z "$DB_PASSWORD" ] || [ -z "$DB_DATABASE" ] || [ -z "$GEMINI_API_KEY" ] || [ -z "$REDIS_PASSWORD" ]; then
if [ -z "$DB_HOST" ] || [ -z "$DB_USER" ] || [ -z "$DB_PASSWORD" ] || [ -z "$DB_NAME" ] || [ -z "$GEMINI_API_KEY" ] || [ -z "$REDIS_PASSWORD_TEST" ]; then
echo "ERROR: One or more test secrets (DB_*, GEMINI_API_KEY, REDIS_PASSWORD_TEST) are not set in Gitea repository secrets."
exit 1
fi
@@ -207,11 +206,11 @@ jobs:
DB_HOST: ${{ secrets.DB_HOST }}
DB_PORT: ${{ secrets.DB_PORT }}
DB_USER: ${{ secrets.DB_USER }}
DB_PASSWORD: ${{ secrets.DB_PASSWORD }}
DB_DATABASE: ${{ secrets.DB_DATABASE_PROD }} # Assumes a secret for the production DB name.
DB_PASSWORD: ${{ secrets.DB_PASSWORD }} # This is used by psql
DB_NAME: ${{ secrets.DB_DATABASE_PROD }} # This is used by the application
run: |
# Fail-fast check to ensure secrets are configured in Gitea.
if [ -z "$DB_HOST" ] || [ -z "$DB_USER" ] || [ -z "$DB_PASSWORD" ] || [ -z "$DB_DATABASE" ]; then
if [ -z "$DB_HOST" ] || [ -z "$DB_USER" ] || [ -z "$DB_PASSWORD" ] || [ -z "$DB_NAME" ]; then
echo "ERROR: One or more production database secrets (DB_HOST, DB_USER, DB_PASSWORD, DB_DATABASE_PROD) are not set in Gitea repository settings."
exit 1
fi
@@ -226,7 +225,7 @@ jobs:
# The `psql` command requires PGPASSWORD to be set.
# `\t` sets tuples-only mode and `\A` unaligns output to get just the raw value.
# The `|| echo "none"` ensures the command doesn't fail if the table or row doesn't exist yet.
DEPLOYED_HASH=$(PGPASSWORD="$DB_PASSWORD" psql -v ON_ERROR_STOP=1 -h "$DB_HOST" -p "$DB_PORT" -U "$DB_USER" -d "$DB_DATABASE" -c "SELECT schema_hash FROM public.schema_info WHERE id = 1;" -t -A || echo "none")
DEPLOYED_HASH=$(PGPASSWORD="$DB_PASSWORD" psql -v ON_ERROR_STOP=1 -h "$DB_HOST" -p "$DB_PORT" -U "$DB_USER" -d "$DB_NAME" -c "SELECT schema_hash FROM public.schema_info WHERE id = 1;" -t -A || echo "none")
echo "Deployed DB Schema Hash: $DEPLOYED_HASH"
# Check if the hash is "none" (command failed) OR if it's an empty string (table exists but is empty).
@@ -272,26 +271,51 @@ jobs:
mkdir -p "$APP_PATH/flyer-images/icons" "$APP_PATH/flyer-images/archive" # Ensure all required subdirectories exist
# 1. Copy the backend source code and project files first.
# CRITICAL: We exclude '.env', 'node_modules', '.git', 'dist', and now 'flyer-images' to protect user content.
rsync -avz --delete --exclude '.env' --exclude '.env.test' --exclude 'node_modules' --exclude '.git' --exclude 'dist' --exclude 'flyer-images' ./ "$APP_PATH/"
# CRITICAL: We exclude 'node_modules', '.git', 'dist', and 'flyer-images' to protect user content and avoid overwriting build artifacts.
rsync -avz --delete --exclude 'node_modules' --exclude '.git' --exclude 'dist' --exclude 'flyer-images' ./ "$APP_PATH/"
# 2. Copy the built frontend assets into the same directory.
# This will correctly place index.html and the assets/ folder in the webroot.
rsync -avz --exclude '.env.local' dist/ "/var/www/flyer-crawler.projectium.com"
rsync -avz dist/ "/var/www/flyer-crawler.projectium.com"
echo "Application deployment complete."
- name: Install Backend Dependencies and Restart Server
env:
# These credentials are required for the psql command at the end of this step.
# --- Production Secrets Injection ---
# These secrets are injected into the environment for the PM2 process.
# Your Node.js application will read these directly from `process.env`.
# Database Credentials
DB_HOST: ${{ secrets.DB_HOST }}
DB_PORT: ${{ secrets.DB_PORT }}
DB_USER: ${{ secrets.DB_USER }}
DB_PASSWORD: ${{ secrets.DB_PASSWORD }}
DB_DATABASE: ${{ secrets.DB_DATABASE_PROD }}
DB_PASSWORD: ${{ secrets.DB_PASSWORD }} # Used by psql
DB_NAME: ${{ secrets.DB_DATABASE_PROD }} # Standardize on the existing prod secret name
# Redis Credentials
REDIS_URL: "redis://localhost:6379" # Assuming Redis is on the same server
REDIS_PASSWORD: ${{ secrets.REDIS_PASSWORD_PROD }}
# Application Secrets
FRONTEND_URL: "https://flyer-crawler.projectium.com"
JWT_SECRET: ${{ secrets.JWT_SECRET }}
GEMINI_API_KEY: ${{ secrets.VITE_GOOGLE_GENAI_API_KEY }} # Re-use the same secret for the server
GOOGLE_MAPS_API_KEY: ${{ secrets.GOOGLE_MAPS_API_KEY }}
WORKER_CONCURRENCY: ${{ secrets.WORKER_CONCURRENCY }}
# SMTP (email)
SMTP_HOST: "localhost"
SMTP_PORT: "1025"
SMTP_SECURE: "false"
SMTP_USER: ""
SMTP_PASS: ""
SMTP_FROM_EMAIL: "noreply@flyer-crawler.projectium.com"
run: |
# Fail-fast check to ensure secrets are configured in Gitea.
if [ -z "$DB_HOST" ] || [ -z "$DB_USER" ] || [ -z "$DB_PASSWORD" ] || [ -z "$DB_DATABASE" ]; then
echo "ERROR: One or more production database secrets (DB_HOST, DB_USER, DB_PASSWORD, DB_DATABASE_PROD) are not set in Gitea repository settings."
if [ -z "$DB_HOST" ] || [ -z "$DB_USER" ] || [ -z "$DB_PASSWORD" ] || [ -z "$DB_NAME" ]; then
echo "ERROR: One or more production database secrets (DB_HOST, DB_USER, DB_PASSWORD, DB_NAME_PROD) are not set in Gitea repository settings."
exit 1
fi
@@ -307,13 +331,13 @@ jobs:
# After a successful deployment, update the schema hash in the database.
# This ensures the next deployment will compare against this new state.
echo "Updating schema hash in production database..."
CURRENT_HASH=$(cat sql/master_schema_rollup.sql | dos2unix | sha256sum | awk '{ print $1 }')
PGPASSWORD="$DB_PASSWORD" psql -v ON_ERROR_STOP=1 -h "$DB_HOST" -p "$DB_PORT" -U "$DB_USER" -d "$DB_DATABASE" -c \
CURRENT_HASH=$(cat sql/master_schema_rollup.sql | dos2unix | sha256sum | awk '{ print $1 }')
PGPASSWORD="$DB_PASSWORD" psql -v ON_ERROR_STOP=1 -h "$DB_HOST" -p "$DB_PORT" -U "$DB_USER" -d "$DB_NAME" -c \
"INSERT INTO public.schema_info (id, schema_hash, deployed_at) VALUES (1, '$CURRENT_HASH', NOW())
ON CONFLICT (id) DO UPDATE SET schema_hash = EXCLUDED.schema_hash, deployed_at = NOW();"
# Verify the hash was updated
UPDATED_HASH=$(PGPASSWORD="$DB_PASSWORD" psql -v ON_ERROR_STOP=1 -h "$DB_HOST" -p "$DB_PORT" -U "$DB_USER" -d "$DB_DATABASE" -c "SELECT schema_hash FROM public.schema_info WHERE id = 1;" -t -A)
UPDATED_HASH=$(PGPASSWORD="$DB_PASSWORD" psql -v ON_ERROR_STOP=1 -h "$DB_HOST" -p "$DB_PORT" -U "$DB_USER" -d "$DB_NAME" -c "SELECT schema_hash FROM public.schema_info WHERE id = 1;" -t -A)
if [ "$CURRENT_HASH" = "$UPDATED_HASH" ]; then
echo "✅ Schema hash successfully updated in the database to: $UPDATED_HASH"
else
@@ -323,8 +347,7 @@ jobs:
- name: Show PM2 Environment for Production
run: |
echo "--- Displaying recent PM2 logs for flyer-crawler-api ---"
# After a reload, the server restarts. We'll show the last 20 lines of the log
# to see the startup messages, which include the environment variables loaded from the .env file.
# After a reload, the server restarts. We'll show the last 20 lines of the log to see the startup messages.
sleep 5 # Wait a few seconds for the app to start and log its output.
pm2 describe flyer-crawler-api || echo "Could not find pm2 process."
pm2 logs flyer-crawler-api --lines 20 --nostream || echo "Could not find pm2 process."