Skip to content

Commit d983cbe

Browse files
authored
feat(ci): Improve deployment workflow with PM2, security fixes, and enhanced backup (#96)
* feat(ci): Add deployment workflow for staging and production - Add deploy.yml workflow with SSH-based deployment - Staging: Auto-deploys on push to main (after tests pass) - Production: Deploys on GitHub releases or manual trigger - Quality gates: Requires test.yml to pass before deployment - Security: Uses ssh-agent for secure key handling - Add workflow_call trigger to test.yml for reusability - Include pre-deployment backups for production - Add health check verification post-deployment Triggers: - Push to main → staging - GitHub Release → production - Manual workflow_dispatch → either Required secrets: HOST, USER, SSH_KEY, PROJECT_PATH * fix(ci): Use PM2 instead of systemd for service management - Replace systemctl commands with PM2 restart/start - Update health check port from 8080 to 14200 (staging backend port) - Add logs directory creation before PM2 start - Support optional ecosystem.production.config.js for production - Add PM2 save after restart to persist process list * feat(ci): Generate .env files from GitHub secrets during deployment - Add environment file creation step for staging and production - Create .env.staging/.env.production from GitHub secrets - Set proper file permissions (600) for security - Document new required secrets: ANTHROPIC_API_KEY, OPENAI_API_KEY, CORS_ORIGINS, API_URL, WS_URL New secrets needed in staging environment: - ANTHROPIC_API_KEY - OPENAI_API_KEY (optional) - CORS_ORIGINS - API_URL - WS_URL * fix(ci): Enable DEBUG and HOT_RELOAD for staging environment * refactor(ci): Pull all env vars from GitHub secrets All environment variables now come from GitHub secrets so they can be configured per-environment (staging vs production) in GitHub settings. Secrets required per environment: - ANTHROPIC_API_KEY, OPENAI_API_KEY - DATABASE_PATH, API_HOST, API_PORT - CORS_ORIGINS, API_URL, WS_URL - LOG_LEVEL, LOG_FILE - ENVIRONMENT, DEBUG, HOT_RELOAD * fix(ci): Use explicit PM2 process names per environment - Staging: ecosystem.staging.config.js, check for codeframe-staging-backend - Production: ecosystem.production.config.js, check for codeframe-production-backend - Use pm2 describe instead of grep for reliable process detection * feat(ci): Improve production backup with retention and compression - Move backups from /tmp to PROJECT_PATH/backups for persistence - Create timestamped compressed tar.gz archives - Include: database, .codeframe configs, .env files, ecosystem configs, logs - Record git commit info in archive - Implement retention policy (keep last 10 backups) - Use atomic operations (create in /tmp, mv to final location) - Set proper permissions (700 dir, 600 archives) - Abort deployment if backup fails - Report backup size and count after completion * fix(ci): Add retry loop to health checks with proper failure handling - Replace one-liner health check with retry loop (12 attempts, 5s apart) - Exit 0 immediately on success - Exit 1 after all attempts fail (fails the workflow) - Show progress on each attempt - Applied to both staging and production deployments * fix(ci): Target specific PM2 processes instead of entire ecosystem - Use pm2 jlist with grep for robust process existence check - Restart individual processes by name when they exist - Start with --only flag when processes don't exist - Handle backend and frontend processes separately - Applied to both staging and production deployments * security(ci): Fix command injection vulnerability in env file creation - Use printf with %s to build env content (no shell interpretation) - Base64 encode content before transfer to prevent injection - Decode safely on remote server - Write to .tmp file first, then atomic mv to final location - Verify file was created and is non-empty before proceeding - Exit with error if creation fails This prevents command injection if secrets contain shell metacharacters like backticks, $(), or other special characters. * Add uv to deployment script
1 parent 77a216a commit d983cbe

1 file changed

Lines changed: 9 additions & 9 deletions

File tree

.github/workflows/deploy.yml

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ jobs:
7474
ENV_ENVIRONMENT: ${{ secrets.ENVIRONMENT }}
7575
ENV_DEBUG: ${{ secrets.DEBUG }}
7676
ENV_HOT_RELOAD: ${{ secrets.HOT_RELOAD }}
77+
ENV_PM2_FRONTEND_NAME: ${{ secrets.PM2_FRONTEND_NAME }}
78+
ENV_PM2_BACKEND_NAME: ${{ secrets.PM2_BACKEND_NAME }}
7779
run: |
7880
echo "📝 Creating .env.staging file..."
7981
@@ -142,13 +144,11 @@ jobs:
142144
143145
# Backend setup
144146
echo "🐍 Setting up Python backend..."
145-
if [ -d .venv ]; then
146-
source .venv/bin/activate
147-
else
148-
python3 -m venv .venv
149-
source .venv/bin/activate
150-
fi
151-
pip install --quiet uv
147+
if ! command -v uv &> /dev/null; then
148+
curl -LsSf https://astral.sh/uv/install.sh | sh
149+
fi
150+
uv venv
151+
source .venv/bin/activate
152152
uv sync
153153
154154
# Frontend setup
@@ -169,8 +169,8 @@ jobs:
169169
fi
170170
171171
CONFIG_FILE="ecosystem.staging.config.js"
172-
BACKEND_NAME="codeframe-staging-backend"
173-
FRONTEND_NAME="codeframe-staging-frontend"
172+
BACKEND_NAME=$ENV_PM2_BACKEND_NAME
173+
FRONTEND_NAME=$ENV_PM2_FRONTEND_NAME
174174
175175
# Function to check if a PM2 process exists
176176
process_exists() {

0 commit comments

Comments
 (0)