Skip to content
Merged

Dev #13

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 44 additions & 4 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,14 @@ on:
- dev
paths:
- 'server/**'
- 'client/**'
- 'k8s/**'
- '.github/workflows/**'
workflow_dispatch: # Allow manual trigger from GitHub UI

concurrency:
group: deploy-${{ github.ref }}
cancel-in-progress: true

env:
DOCKER_IMAGE: tharusha69/apexpos-backend
Expand All @@ -19,7 +25,7 @@ env:

jobs:
# ─────────────────────────────────────────────
# Job 1: Lint & Build client (optional validation)
# Job 1a: Lint & Build client (runs in PARALLEL)
# ─────────────────────────────────────────────
lint-client:
name: 🔍 Lint & Build Frontend
Expand Down Expand Up @@ -47,12 +53,46 @@ jobs:
working-directory: client

# ─────────────────────────────────────────────
# Job 2: Build & Push Docker image
# Job 1b: Validate backend (runs in PARALLEL)
# ─────────────────────────────────────────────
test-backend:
name: 🧪 Validate Backend
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
cache-dependency-path: server/package-lock.json

- name: Install dependencies
run: npm ci
working-directory: server

- name: Syntax check all JS files
run: |
echo "🔍 Checking JavaScript syntax..."
find . -name '*.js' -not -path './node_modules/*' | while read f; do
node --check "$f" || exit 1
done
echo "✅ All files pass syntax check"
working-directory: server

- name: Run tests
run: npm test --if-present || echo "⚠️ No tests configured yet"
working-directory: server
continue-on-error: true

# ─────────────────────────────────────────────
# Job 2: Build & Push Docker image (waits for BOTH)
# ─────────────────────────────────────────────
build-push:
name: 🐳 Build & Push Docker Image
runs-on: ubuntu-latest
needs: lint-client
needs: [lint-client, test-backend] # Parallel gate — both must pass
outputs:
image_tag: ${{ steps.meta.outputs.version }}
steps:
Expand Down Expand Up @@ -98,7 +138,7 @@ jobs:
name: ${{ github.ref == 'refs/heads/main' && 'production' || 'staging' }}
steps:
- name: Deploy to EC2 via SSH
uses: appleboy/ssh-action@v1.0.3
uses: appleboy/ssh-action@v1.2.0
with:
host: ${{ env.EC2_HOST }}
username: ${{ env.EC2_USER }}
Expand Down
43 changes: 26 additions & 17 deletions Jenkinsfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,14 @@ pipeline {
DEPLOYMENT_FILE = 'k8s/backend/deployment.yml'
NAMESPACE = 'apexpos'
DEPLOYMENT = 'apexpos-backend'
// Limit Node memory consumption to 256MB to prevent OOM
NODE_OPTIONS = '--max-old-space-size=256'
}

options {
buildDiscarder(logRotator(numToKeepStr: '5'))
buildDiscarder(logRotator(numToKeepStr: '3'))
timeout(time: 20, unit: 'MINUTES')
disableConcurrentBuilds()
}

stages {
Expand All @@ -21,23 +24,25 @@ pipeline {
}
}

stage('Install & Lint') {
parallel {
stage('Backend Deps') {
steps {
dir('server') {
sh 'npm ci --omit=dev'
}
}
// Run sequentially (NOT in parallel) to conserve memory on t3.micro
stage('Backend Dependencies') {
steps {
dir('server') {
echo '📦 Installing Backend Dependencies...'
sh 'npm ci --omit=dev --no-audit --no-fund'
}
stage('Frontend Lint & Build') {
steps {
dir('client') {
sh 'npm ci'
sh 'npm run lint'
sh 'npm run build'
}
}
}
}

stage('Frontend Dependencies & Build') {
steps {
dir('client') {
echo '📦 Installing Frontend Dependencies...'
sh 'npm ci --no-audit --no-fund'
echo '🔍 Linting Frontend...'
sh 'npm run lint'
echo '🚀 Building Frontend Production Bundle...'
sh 'npm run build'
}
}
}
Expand All @@ -51,6 +56,7 @@ pipeline {
}
steps {
dir('server') {
echo '🐳 Building Docker Image...'
sh "docker build -t ${DOCKER_IMAGE}:${BUILD_NUMBER} ."
sh "docker tag ${DOCKER_IMAGE}:${BUILD_NUMBER} ${DOCKER_IMAGE}:latest"
}
Expand All @@ -65,6 +71,7 @@ pipeline {
}
}
steps {
echo '📤 Pushing Image to Docker Hub...'
sh """
echo ${DOCKER_HUB_CREDS_PSW} | docker login -u ${DOCKER_HUB_CREDS_USR} --password-stdin
docker push ${DOCKER_IMAGE}:${BUILD_NUMBER}
Expand All @@ -81,6 +88,7 @@ pipeline {
}
}
steps {
echo '🔄 Restarting Kubernetes Deployment...'
sh """
export KUBECONFIG=/root/.kube/config
kubectl rollout restart deployment/${DEPLOYMENT} -n ${NAMESPACE}
Expand All @@ -97,6 +105,7 @@ pipeline {
}
}
steps {
echo '🩺 Running API health check...'
sh """
sleep 10
curl -f http://localhost:30500/ || exit 1
Expand Down
2 changes: 1 addition & 1 deletion k8s/backend/configmap.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@ data:
PORT: "5000"
NODE_ENV: "production"
# Allow local dev + EC2 NodePort access + Vercel frontend
ALLOWED_ORIGINS: "http://localhost,http://127.0.0.1,http://YOUR_EC2_IP,http://YOUR_EC2_IP:30500,https://apexpos.vercel.app" # Update YOUR_EC2_IP before deploy
ALLOWED_ORIGINS: "http://localhost,http://127.0.0.1,http://13.206.37.231,http://13.206.37.231:30500,https://client-jade-phi.vercel.app,https://client-75ejziams-tharusha-bashithas-projects.vercel.app"
2 changes: 1 addition & 1 deletion k8s/backend/deployment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ spec:
containers:
- name: backend
image: tharusha69/apexpos-backend:latest
imagePullPolicy: IfNotPresent
imagePullPolicy: Always
ports:
- containerPort: 5000
envFrom:
Expand Down
7 changes: 3 additions & 4 deletions scripts/install-jenkins.sh
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,11 @@ if docker ps -a --format '{{.Names}}' | grep -q '^jenkins$'; then
fi
fi

echo "Starting Jenkins with memory limits (400MB max)..."
echo "Starting Jenkins with memory limits (700MB max)..."

docker run -d --name jenkins \
--restart unless-stopped \
--memory="400m" \
--memory-swap="600m" \
--memory="700m" \
--cpus="0.8" \
-p 8080:8080 -p 50000:50000 \
-e JAVA_OPTS="-Xmx256m -Xms128m -XX:MaxMetaspaceSize=128m -Dhudson.model.DirectoryBrowserSupport.CSP=" \
Expand All @@ -39,7 +38,7 @@ docker run -d --name jenkins \
jenkins/jenkins:lts-jdk17

echo ""
echo "✅ Jenkins starting on port 8080 (memory limited to 400MB)"
echo "✅ Jenkins starting on port 8080 (memory limited to 700MB)"
echo "⏳ Wait ~60 seconds for Jenkins to fully start..."
echo ""
echo "Initial admin password (run after 60 seconds):"
Expand Down
Loading