Skip to content

Commit 4a0837d

Browse files
committed
added deployment workflow
1 parent f665ea8 commit 4a0837d

File tree

1 file changed

+159
-0
lines changed

1 file changed

+159
-0
lines changed

.github/workflows/deploy.yml

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
name: Deploy to OpenStack
2+
3+
# Required GitHub Environment Secrets:
4+
#
5+
# Create two environments in GitHub: "production" and "staging"
6+
# Settings → Environments → New environment
7+
#
8+
# For each environment, add these secrets:
9+
# - SSH_HOST: OpenStack instance hostname or IP address
10+
# - SSH_USER: SSH username for the instance
11+
# - SSH_PRIVATE_KEY: Private SSH key for authentication
12+
# - SITE_URL: Site URL (for build)
13+
# - BACKEND_URL: Backend URL (for build)
14+
# - DEPLOY_PATH: (Optional) Deployment path (defaults to ~/processordb-website for prod, ~/processordb-website-staging for staging)
15+
# - PORT: (Optional, staging only) Port for staging app (defaults to 3001 for same instance, set to 3000 for separate instance)
16+
17+
on:
18+
push:
19+
branches:
20+
- main
21+
- dev
22+
23+
jobs:
24+
deploy:
25+
runs-on: ubuntu-latest
26+
27+
# Determine environment based on branch
28+
environment: ${{ github.ref == 'refs/heads/main' && 'production' || 'staging' }}
29+
30+
env:
31+
ENVIRONMENT: ${{ github.ref == 'refs/heads/main' && 'production' || 'staging' }}
32+
33+
steps:
34+
- name: Checkout code
35+
uses: actions/checkout@v4
36+
37+
- name: Setup Node.js
38+
uses: actions/setup-node@v4
39+
with:
40+
node-version: '20'
41+
cache: 'npm'
42+
43+
- name: Install dependencies
44+
run: npm ci
45+
46+
- name: Set environment variables
47+
id: env
48+
run: |
49+
if [ "${{ github.ref }}" == "refs/heads/main" ]; then
50+
echo "SSH_HOST=${{ secrets.SSH_HOST }}" >> $GITHUB_ENV
51+
echo "SSH_USER=${{ secrets.SSH_USER }}" >> $GITHUB_ENV
52+
echo "SSH_PRIVATE_KEY=${{ secrets.SSH_PRIVATE_KEY }}" >> $GITHUB_ENV
53+
echo "SITE_URL=${{ secrets.SITE_URL }}" >> $GITHUB_ENV
54+
echo "BACKEND_URL=${{ secrets.BACKEND_URL }}" >> $GITHUB_ENV
55+
echo "DEPLOY_PATH=${{ secrets.DEPLOY_PATH || '~/processordb-website' }}" >> $GITHUB_ENV
56+
echo "PM2_APP_NAME=ProcessorDB-website" >> $GITHUB_ENV
57+
echo "PM2_PORT=3000" >> $GITHUB_ENV
58+
echo "ECOSYSTEM_FILE=ecosystem.config.js" >> $GITHUB_ENV
59+
else
60+
# For staging, use port from secret or default to 3001 (same instance) or 3000 (separate)
61+
# If using same instance as production, use 3001. If separate instance, use 3000.
62+
# You can override by setting PORT secret in staging environment
63+
DEPLOY_PATH="${{ secrets.DEPLOY_PATH || '~/processordb-website-staging' }}"
64+
STAGING_PORT="${{ secrets.PORT || '3001' }}"
65+
66+
echo "SSH_HOST=${{ secrets.SSH_HOST }}" >> $GITHUB_ENV
67+
echo "SSH_USER=${{ secrets.SSH_USER }}" >> $GITHUB_ENV
68+
echo "SSH_PRIVATE_KEY=${{ secrets.SSH_PRIVATE_KEY }}" >> $GITHUB_ENV
69+
echo "SITE_URL=${{ secrets.SITE_URL }}" >> $GITHUB_ENV
70+
echo "BACKEND_URL=${{ secrets.BACKEND_URL }}" >> $GITHUB_ENV
71+
echo "DEPLOY_PATH=$DEPLOY_PATH" >> $GITHUB_ENV
72+
echo "PM2_APP_NAME=ProcessorDB-website-staging" >> $GITHUB_ENV
73+
echo "PM2_PORT=$STAGING_PORT" >> $GITHUB_ENV
74+
echo "ECOSYSTEM_FILE=ecosystem.staging.config.js" >> $GITHUB_ENV
75+
fi
76+
77+
- name: Build application
78+
run: npm run build
79+
env:
80+
SITE_URL: ${{ env.SITE_URL }}
81+
BACKEND_URL: ${{ env.BACKEND_URL }}
82+
83+
- name: Create staging ecosystem config
84+
if: github.ref != 'refs/heads/main'
85+
run: |
86+
PM2_PORT="${{ env.PM2_PORT }}"
87+
cat > ecosystem.staging.config.js << EOF
88+
module.exports = {
89+
apps : [{
90+
name: "ProcessorDB-website-staging",
91+
port: "$PM2_PORT",
92+
exec_mode: "cluster",
93+
instances: "max",
94+
script: "./.output/server/index.mjs"
95+
}]
96+
}
97+
EOF
98+
99+
- name: Create deployment archive
100+
run: |
101+
FILES=".output ecosystem.config.js package.json package-lock.json public server nuxt.config.ts"
102+
if [ -f "ecosystem.staging.config.js" ]; then
103+
FILES="$FILES ecosystem.staging.config.js"
104+
fi
105+
tar -czf deploy.tar.gz $FILES
106+
107+
- name: Setup SSH
108+
uses: webfactory/[email protected]
109+
with:
110+
ssh-private-key: ${{ env.SSH_PRIVATE_KEY }}
111+
112+
- name: Add server to known hosts
113+
run: |
114+
mkdir -p ~/.ssh
115+
ssh-keyscan -H ${{ env.SSH_HOST }} >> ~/.ssh/known_hosts
116+
117+
- name: Deploy to ${{ env.ENVIRONMENT }}
118+
run: |
119+
DEPLOY_PATH="${{ env.DEPLOY_PATH }}"
120+
PM2_APP_NAME="${{ env.PM2_APP_NAME }}"
121+
ECOSYSTEM_FILE="${{ env.ECOSYSTEM_FILE }}"
122+
123+
# Copy files to server
124+
scp -r deploy.tar.gz ${{ env.SSH_USER }}@${{ env.SSH_HOST }}:$DEPLOY_PATH/
125+
126+
# SSH into server and deploy
127+
ssh ${{ env.SSH_USER }}@${{ env.SSH_HOST }} "bash -s" << EOF
128+
set -e
129+
cd $DEPLOY_PATH
130+
131+
# Extract deployment files
132+
tar -xzf deploy.tar.gz
133+
134+
# Install/update dependencies
135+
source ~/.nvm/nvm.sh
136+
npm ci --production
137+
138+
# Use staging ecosystem config if it exists, otherwise use production
139+
if [ -f "$ECOSYSTEM_FILE" ]; then
140+
PM2_CONFIG="$ECOSYSTEM_FILE"
141+
else
142+
PM2_CONFIG="ecosystem.config.js"
143+
fi
144+
145+
# Restart PM2 application
146+
pm2 restart $PM2_APP_NAME || pm2 start $PM2_CONFIG
147+
148+
# Save PM2 process list for auto-restart on reboot
149+
pm2 save --force
150+
151+
# Clean up
152+
rm -f deploy.tar.gz
153+
154+
echo "Deployment to ${{ env.ENVIRONMENT }} completed successfully"
155+
EOF
156+
157+
- name: Cleanup
158+
if: always()
159+
run: rm -f deploy.tar.gz

0 commit comments

Comments
 (0)