Skip to content

added deployment workflow #1

added deployment workflow

added deployment workflow #1

Workflow file for this run

name: Deploy to OpenStack
# Required GitHub Environment Secrets:
#
# Create two environments in GitHub: "production" and "staging"
# Settings → Environments → New environment
#
# For each environment, add these secrets:
# - SSH_HOST: OpenStack instance hostname or IP address
# - SSH_USER: SSH username for the instance
# - SSH_PRIVATE_KEY: Private SSH key for authentication
# - SITE_URL: Site URL (for build)
# - BACKEND_URL: Backend URL (for build)
# - DEPLOY_PATH: (Optional) Deployment path (defaults to ~/processordb-website for prod, ~/processordb-website-staging for staging)
# - PORT: (Optional, staging only) Port for staging app (defaults to 3001 for same instance, set to 3000 for separate instance)
on:
push:
branches:
- main
- dev
jobs:
deploy:
runs-on: ubuntu-latest
# Determine environment based on branch
environment: ${{ github.ref == 'refs/heads/main' && 'production' || 'staging' }}
env:
ENVIRONMENT: ${{ github.ref == 'refs/heads/main' && 'production' || 'staging' }}
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Set environment variables
id: env
run: |
if [ "${{ github.ref }}" == "refs/heads/main" ]; then
echo "SSH_HOST=${{ secrets.SSH_HOST }}" >> $GITHUB_ENV
echo "SSH_USER=${{ secrets.SSH_USER }}" >> $GITHUB_ENV
echo "SSH_PRIVATE_KEY=${{ secrets.SSH_PRIVATE_KEY }}" >> $GITHUB_ENV
echo "SITE_URL=${{ secrets.SITE_URL }}" >> $GITHUB_ENV
echo "BACKEND_URL=${{ secrets.BACKEND_URL }}" >> $GITHUB_ENV
echo "DEPLOY_PATH=${{ secrets.DEPLOY_PATH || '~/processordb-website' }}" >> $GITHUB_ENV
echo "PM2_APP_NAME=ProcessorDB-website" >> $GITHUB_ENV
echo "PM2_PORT=3000" >> $GITHUB_ENV
echo "ECOSYSTEM_FILE=ecosystem.config.js" >> $GITHUB_ENV
else
# For staging, use port from secret or default to 3001 (same instance) or 3000 (separate)
# If using same instance as production, use 3001. If separate instance, use 3000.
# You can override by setting PORT secret in staging environment
DEPLOY_PATH="${{ secrets.DEPLOY_PATH || '~/processordb-website-staging' }}"
STAGING_PORT="${{ secrets.PORT || '3001' }}"
echo "SSH_HOST=${{ secrets.SSH_HOST }}" >> $GITHUB_ENV
echo "SSH_USER=${{ secrets.SSH_USER }}" >> $GITHUB_ENV
echo "SSH_PRIVATE_KEY=${{ secrets.SSH_PRIVATE_KEY }}" >> $GITHUB_ENV
echo "SITE_URL=${{ secrets.SITE_URL }}" >> $GITHUB_ENV
echo "BACKEND_URL=${{ secrets.BACKEND_URL }}" >> $GITHUB_ENV
echo "DEPLOY_PATH=$DEPLOY_PATH" >> $GITHUB_ENV
echo "PM2_APP_NAME=ProcessorDB-website-staging" >> $GITHUB_ENV
echo "PM2_PORT=$STAGING_PORT" >> $GITHUB_ENV
echo "ECOSYSTEM_FILE=ecosystem.staging.config.js" >> $GITHUB_ENV
fi
- name: Build application
run: npm run build
env:
SITE_URL: ${{ env.SITE_URL }}
BACKEND_URL: ${{ env.BACKEND_URL }}
- name: Create staging ecosystem config
if: github.ref != 'refs/heads/main'
run: |
PM2_PORT="${{ env.PM2_PORT }}"
cat > ecosystem.staging.config.js << EOF
module.exports = {
apps : [{
name: "ProcessorDB-website-staging",
port: "$PM2_PORT",
exec_mode: "cluster",
instances: "max",
script: "./.output/server/index.mjs"
}]
}
EOF
- name: Create deployment archive
run: |
FILES=".output ecosystem.config.js package.json package-lock.json public server nuxt.config.ts"
if [ -f "ecosystem.staging.config.js" ]; then
FILES="$FILES ecosystem.staging.config.js"
fi
tar -czf deploy.tar.gz $FILES
- name: Setup SSH
uses: webfactory/[email protected]
with:
ssh-private-key: ${{ env.SSH_PRIVATE_KEY }}
- name: Add server to known hosts
run: |
mkdir -p ~/.ssh
ssh-keyscan -H ${{ env.SSH_HOST }} >> ~/.ssh/known_hosts
- name: Deploy to ${{ env.ENVIRONMENT }}
run: |
DEPLOY_PATH="${{ env.DEPLOY_PATH }}"
PM2_APP_NAME="${{ env.PM2_APP_NAME }}"
ECOSYSTEM_FILE="${{ env.ECOSYSTEM_FILE }}"
# Copy files to server
scp -r deploy.tar.gz ${{ env.SSH_USER }}@${{ env.SSH_HOST }}:$DEPLOY_PATH/
# SSH into server and deploy
ssh ${{ env.SSH_USER }}@${{ env.SSH_HOST }} "bash -s" << EOF
set -e
cd $DEPLOY_PATH
# Extract deployment files
tar -xzf deploy.tar.gz
# Install/update dependencies
source ~/.nvm/nvm.sh
npm ci --production
# Use staging ecosystem config if it exists, otherwise use production
if [ -f "$ECOSYSTEM_FILE" ]; then
PM2_CONFIG="$ECOSYSTEM_FILE"
else
PM2_CONFIG="ecosystem.config.js"
fi
# Restart PM2 application
pm2 restart $PM2_APP_NAME || pm2 start $PM2_CONFIG
# Save PM2 process list for auto-restart on reboot
pm2 save --force
# Clean up
rm -f deploy.tar.gz
echo "Deployment to ${{ env.ENVIRONMENT }} completed successfully"
EOF
- name: Cleanup
if: always()
run: rm -f deploy.tar.gz