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