parent
cfd96bb643
commit
36a07b3df1
9 changed files with 408 additions and 0 deletions
@ -0,0 +1,52 @@ |
|||||||
|
name: CI Tests |
||||||
|
|
||||||
|
on: |
||||||
|
push: |
||||||
|
branches: [ develop, feature/*, beta ] |
||||||
|
pull_request: |
||||||
|
branches: [ develop, beta, main ] |
||||||
|
|
||||||
|
jobs: |
||||||
|
test: |
||||||
|
runs-on: ubuntu-latest |
||||||
|
|
||||||
|
strategy: |
||||||
|
matrix: |
||||||
|
node-version: [16.x, 18.x] |
||||||
|
|
||||||
|
steps: |
||||||
|
- name: Checkout code |
||||||
|
uses: actions/checkout@v3 |
||||||
|
|
||||||
|
- name: Setup Node.js ${{ matrix.node-version }} |
||||||
|
uses: actions/setup-node@v3 |
||||||
|
with: |
||||||
|
node-version: ${{ matrix.node-version }} |
||||||
|
cache: 'npm' |
||||||
|
|
||||||
|
- name: Install dependencies |
||||||
|
run: npm ci |
||||||
|
|
||||||
|
- name: Run linting |
||||||
|
run: npm run lint |
||||||
|
|
||||||
|
- name: Run tests |
||||||
|
run: npm test |
||||||
|
|
||||||
|
- name: Run coverage |
||||||
|
run: npm run test:coverage |
||||||
|
|
||||||
|
- name: Upload coverage reports |
||||||
|
uses: codecov/codecov-action@v3 |
||||||
|
if: matrix.node-version == '18.x' |
||||||
|
|
||||||
|
security-scan: |
||||||
|
runs-on: ubuntu-latest |
||||||
|
steps: |
||||||
|
- name: Checkout code |
||||||
|
uses: actions/checkout@v3 |
||||||
|
|
||||||
|
- name: Run security audit |
||||||
|
run: | |
||||||
|
npm audit --audit-level high |
||||||
|
npm audit fix --dry-run |
@ -0,0 +1,56 @@ |
|||||||
|
name: Deploy to Beta |
||||||
|
|
||||||
|
on: |
||||||
|
push: |
||||||
|
branches: [ beta ] |
||||||
|
|
||||||
|
jobs: |
||||||
|
deploy: |
||||||
|
runs-on: ubuntu-latest |
||||||
|
environment: beta |
||||||
|
|
||||||
|
steps: |
||||||
|
- name: Checkout code |
||||||
|
uses: actions/checkout@v3 |
||||||
|
|
||||||
|
- name: Setup Node.js |
||||||
|
uses: actions/setup-node@v3 |
||||||
|
with: |
||||||
|
node-version: '18.x' |
||||||
|
cache: 'npm' |
||||||
|
|
||||||
|
- name: Install dependencies |
||||||
|
run: npm ci --only=production |
||||||
|
|
||||||
|
- name: Build application |
||||||
|
run: npm run build |
||||||
|
|
||||||
|
- name: Create deployment package |
||||||
|
run: | |
||||||
|
mkdir -p deploy |
||||||
|
cp -r src dist package*.json ecosystem.config.js scripts deploy/ |
||||||
|
tar -czf deploy-$(date +%Y%m%d-%H%M%S).tar.gz -C deploy . |
||||||
|
|
||||||
|
- name: Deploy to Beta Server |
||||||
|
env: |
||||||
|
DEPLOY_HOST: ${{ secrets.BETA_HOST }} |
||||||
|
DEPLOY_USER: ${{ secrets.DEPLOY_USER }} |
||||||
|
DEPLOY_KEY: ${{ secrets.DEPLOY_KEY }} |
||||||
|
DEPLOY_PATH: ${{ secrets.BETA_DEPLOY_PATH }} |
||||||
|
run: | |
||||||
|
# Setup SSH |
||||||
|
mkdir -p ~/.ssh |
||||||
|
echo "$DEPLOY_KEY" > ~/.ssh/deploy_key |
||||||
|
chmod 600 ~/.ssh/deploy_key |
||||||
|
ssh-keyscan -H $DEPLOY_HOST >> ~/.ssh/known_hosts |
||||||
|
|
||||||
|
# Upload and deploy |
||||||
|
scp -i ~/.ssh/deploy_key deploy-*.tar.gz $DEPLOY_USER@$DEPLOY_HOST:/tmp/ |
||||||
|
ssh -i ~/.ssh/deploy_key $DEPLOY_USER@$DEPLOY_HOST "bash -s" < scripts/deploy.sh beta |
||||||
|
|
||||||
|
- name: Health Check |
||||||
|
env: |
||||||
|
HEALTH_CHECK_URL: ${{ secrets.BETA_HEALTH_CHECK_URL }} |
||||||
|
run: | |
||||||
|
sleep 30 |
||||||
|
curl -f $HEALTH_CHECK_URL || exit 1 |
@ -0,0 +1,89 @@ |
|||||||
|
name: Deploy to Production |
||||||
|
|
||||||
|
on: |
||||||
|
push: |
||||||
|
branches: [ main ] |
||||||
|
|
||||||
|
jobs: |
||||||
|
deploy: |
||||||
|
runs-on: ubuntu-latest |
||||||
|
environment: production |
||||||
|
|
||||||
|
steps: |
||||||
|
- name: Checkout code |
||||||
|
uses: actions/checkout@v3 |
||||||
|
|
||||||
|
- name: Setup Node.js |
||||||
|
uses: actions/setup-node@v3 |
||||||
|
with: |
||||||
|
node-version: '18.x' |
||||||
|
cache: 'npm' |
||||||
|
|
||||||
|
- name: Install dependencies |
||||||
|
run: npm ci --only=production |
||||||
|
|
||||||
|
- name: Build application |
||||||
|
run: npm run build |
||||||
|
|
||||||
|
- name: Run final tests |
||||||
|
run: npm test |
||||||
|
|
||||||
|
- name: Create backup |
||||||
|
env: |
||||||
|
DEPLOY_HOST: ${{ secrets.PROD_HOST }} |
||||||
|
DEPLOY_USER: ${{ secrets.DEPLOY_USER }} |
||||||
|
DEPLOY_KEY: ${{ secrets.DEPLOY_KEY }} |
||||||
|
DEPLOY_PATH: ${{ secrets.PROD_DEPLOY_PATH }} |
||||||
|
run: | |
||||||
|
mkdir -p ~/.ssh |
||||||
|
echo "$DEPLOY_KEY" > ~/.ssh/deploy_key |
||||||
|
chmod 600 ~/.ssh/deploy_key |
||||||
|
ssh-keyscan -H $DEPLOY_HOST >> ~/.ssh/known_hosts |
||||||
|
|
||||||
|
# Create backup |
||||||
|
ssh -i ~/.ssh/deploy_key $DEPLOY_USER@$DEPLOY_HOST " |
||||||
|
if [ -d $DEPLOY_PATH ]; then |
||||||
|
cp -r $DEPLOY_PATH $DEPLOY_PATH.backup.$(date +%Y%m%d-%H%M%S) |
||||||
|
fi |
||||||
|
" |
||||||
|
|
||||||
|
- name: Deploy to Production |
||||||
|
env: |
||||||
|
DEPLOY_HOST: ${{ secrets.PROD_HOST }} |
||||||
|
DEPLOY_USER: ${{ secrets.DEPLOY_USER }} |
||||||
|
DEPLOY_KEY: ${{ secrets.DEPLOY_KEY }} |
||||||
|
DEPLOY_PATH: ${{ secrets.PROD_DEPLOY_PATH }} |
||||||
|
run: | |
||||||
|
# Create deployment package |
||||||
|
mkdir -p deploy |
||||||
|
cp -r src dist package*.json ecosystem.config.js scripts deploy/ |
||||||
|
tar -czf deploy-$(date +%Y%m%d-%H%M%S).tar.gz -C deploy . |
||||||
|
|
||||||
|
# Upload and deploy |
||||||
|
scp -i ~/.ssh/deploy_key deploy-*.tar.gz $DEPLOY_USER@$DEPLOY_HOST:/tmp/ |
||||||
|
ssh -i ~/.ssh/deploy_key $DEPLOY_USER@$DEPLOY_HOST "bash -s" < scripts/deploy.sh production |
||||||
|
|
||||||
|
- name: Health Check and Rollback on Failure |
||||||
|
env: |
||||||
|
DEPLOY_HOST: ${{ secrets.PROD_HOST }} |
||||||
|
DEPLOY_USER: ${{ secrets.DEPLOY_USER }} |
||||||
|
DEPLOY_KEY: ${{ secrets.DEPLOY_KEY }} |
||||||
|
HEALTH_CHECK_URL: ${{ secrets.PROD_HEALTH_CHECK_URL }} |
||||||
|
run: | |
||||||
|
# Wait for application to start |
||||||
|
sleep 30 |
||||||
|
|
||||||
|
# Health check with retry |
||||||
|
for i in {1..5}; do |
||||||
|
if curl -f $HEALTH_CHECK_URL; then |
||||||
|
echo "Health check passed" |
||||||
|
exit 0 |
||||||
|
fi |
||||||
|
echo "Health check failed, retry $i/5" |
||||||
|
sleep 10 |
||||||
|
done |
||||||
|
|
||||||
|
# If health check fails, rollback |
||||||
|
echo "Health check failed, initiating rollback" |
||||||
|
ssh -i ~/.ssh/deploy_key $DEPLOY_USER@$DEPLOY_HOST "bash -s" < scripts/rollback.sh |
||||||
|
exit 1 |
@ -0,0 +1,14 @@ |
|||||||
|
[Unit] |
||||||
|
Description=Gitea Actions Runner |
||||||
|
After=network.target |
||||||
|
|
||||||
|
[Service] |
||||||
|
Type=simple |
||||||
|
User=git |
||||||
|
WorkingDirectory=/opt/act_runner |
||||||
|
ExecStart=/usr/local/bin/act_runner daemon |
||||||
|
Restart=always |
||||||
|
RestartSec=5 |
||||||
|
|
||||||
|
[Install] |
||||||
|
WantedBy=multi-user.target |
@ -0,0 +1,28 @@ |
|||||||
|
module.exports = { |
||||||
|
apps: [{ |
||||||
|
name: 'your-app-name', |
||||||
|
script: './src/app.js', |
||||||
|
instances: 'max', |
||||||
|
exec_mode: 'cluster', |
||||||
|
env: { |
||||||
|
NODE_ENV: 'development', |
||||||
|
PORT: 3000 |
||||||
|
}, |
||||||
|
env_beta: { |
||||||
|
NODE_ENV: 'staging', |
||||||
|
PORT: 3001 |
||||||
|
}, |
||||||
|
env_production: { |
||||||
|
NODE_ENV: 'production', |
||||||
|
PORT: 3000 |
||||||
|
}, |
||||||
|
error_file: './logs/err.log', |
||||||
|
out_file: './logs/out.log', |
||||||
|
log_file: './logs/combined.log', |
||||||
|
time: true, |
||||||
|
max_memory_restart: '1G', |
||||||
|
restart_delay: 4000, |
||||||
|
max_restarts: 10, |
||||||
|
min_uptime: '10s' |
||||||
|
}] |
||||||
|
}; |
@ -0,0 +1,38 @@ |
|||||||
|
#!/bin/bash |
||||||
|
|
||||||
|
APP_NAME="your-app-name" |
||||||
|
HEALTH_URL=${1:-"http://localhost:3000/health"} |
||||||
|
MAX_RETRIES=${2:-10} |
||||||
|
RETRY_INTERVAL=${3:-5} |
||||||
|
|
||||||
|
echo "🔍 Starting health check for $APP_NAME..." |
||||||
|
|
||||||
|
for i in $(seq 1 $MAX_RETRIES); do |
||||||
|
echo "Attempt $i/$MAX_RETRIES..." |
||||||
|
|
||||||
|
# بررسی وضعیت PM2 |
||||||
|
if ! pm2 list | grep -q $APP_NAME; then |
||||||
|
echo "❌ PM2 process not found" |
||||||
|
sleep $RETRY_INTERVAL |
||||||
|
continue |
||||||
|
fi |
||||||
|
|
||||||
|
# بررسی وضعیت online بودن |
||||||
|
if ! pm2 list | grep $APP_NAME | grep -q "online"; then |
||||||
|
echo "❌ PM2 process not online" |
||||||
|
sleep $RETRY_INTERVAL |
||||||
|
continue |
||||||
|
fi |
||||||
|
|
||||||
|
# بررسی HTTP endpoint |
||||||
|
if curl -f -s $HEALTH_URL > /dev/null; then |
||||||
|
echo "✅ Health check passed!" |
||||||
|
exit 0 |
||||||
|
fi |
||||||
|
|
||||||
|
echo "❌ Health check failed, retrying in ${RETRY_INTERVAL}s..." |
||||||
|
sleep $RETRY_INTERVAL |
||||||
|
done |
||||||
|
|
||||||
|
echo "💥 Health check failed after $MAX_RETRIES attempts" |
||||||
|
exit 1 |
Loading…
Reference in new issue