Skip to content

Commit 90a0bd2

Browse files
committed
2 parents bb7c63f + be4ba6b commit 90a0bd2

File tree

7 files changed

+424
-5
lines changed

7 files changed

+424
-5
lines changed

.github/workflows/docker-build-push.yml

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ jobs:
3939
MONGODB_URI: mongodb://localhost:27017/glow_test
4040

4141
- name: Upload backend test results
42-
uses: actions/upload-artifact@v4 # Changed from v3 to v4
42+
uses: actions/upload-artifact@v4
4343
if: always()
4444
with:
4545
name: backend-test-results
@@ -73,15 +73,15 @@ jobs:
7373
CI: true
7474

7575
- name: Upload frontend test results
76-
uses: actions/upload-artifact@v4 # Changed from v3 to v4
76+
uses: actions/upload-artifact@v4
7777
if: always()
7878
with:
7979
name: frontend-test-results
8080
path: frontend/coverage/
8181

8282
build-backend:
8383
runs-on: ubuntu-latest
84-
needs: [test-backend] # Only build if tests pass
84+
needs: [test-backend]
8585

8686
steps:
8787
- name: Checkout code
@@ -127,7 +127,7 @@ jobs:
127127

128128
build-frontend:
129129
runs-on: ubuntu-latest
130-
needs: [test-frontend] # Only build if tests pass
130+
needs: [test-frontend]
131131

132132
steps:
133133
- name: Checkout code
@@ -171,4 +171,31 @@ jobs:
171171
run: |
172172
curl -X POST "${{ secrets.RENDER_FRONTEND_DEPLOY_HOOK }}"
173173
env:
174-
RENDER_FRONTEND_DEPLOY_HOOK: ${{ secrets.RENDER_FRONTEND_DEPLOY_HOOK }}
174+
RENDER_FRONTEND_DEPLOY_HOOK: ${{ secrets.RENDER_FRONTEND_DEPLOY_HOOK }}
175+
176+
integration-tests:
177+
runs-on: ubuntu-latest
178+
needs: [build-backend, build-frontend]
179+
if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master'
180+
181+
steps:
182+
- name: Checkout code
183+
uses: actions/checkout@v4
184+
185+
- name: Wait for deployments to complete
186+
run: |
187+
echo "⏳ Waiting for Render deployments to complete..."
188+
sleep 120 # Wait 2 minutes for deployments
189+
190+
- name: Make integration test script executable
191+
run: chmod +x CICD/scripts/integration-test.sh
192+
193+
- name: Run integration tests
194+
run: |
195+
echo "🔄 Running integration tests..."
196+
CICD/scripts/integration-test.sh
197+
198+
- name: Integration tests passed
199+
run: |
200+
echo "✅ All integration tests passed successfully!"
201+
echo "🚀 Deployment pipeline completed successfully!"

CICD/README.md

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
# CSCC01 Assignment 2 - CI/CD Submission (Team: Microsofties)
2+
3+
This folder contains the Dockerfiles, CI/CD workflows, integration test scripts, and documentation required for Assignment 2.
4+
5+
---
6+
7+
## What This Project Does
8+
9+
This project automates the CI/CD pipeline for a full-stack web application using:
10+
11+
- **GitHub Actions** for continuous integration and deployment
12+
- **Docker & Docker Hub** for containerization and versioning
13+
- **Render** for live deployment of frontend and backend containers
14+
15+
---
16+
17+
## Folder Structure
18+
19+
CICD/
20+
21+
├── backend/
22+
23+
│ └── Dockerfile
24+
25+
├── frontend/
26+
27+
│ └── Dockerfile
28+
29+
├── scripts/
30+
31+
│ └── integration-test.sh
32+
33+
├── workflows/
34+
35+
│ └── ci-cd.yml
36+
37+
├── README.md
38+
39+
└── Report.pdf
40+
41+
---
42+
43+
## CI/CD Workflow
44+
45+
On every push to `main`, GitHub Actions will:
46+
47+
1. Run **unit tests** for both frontend and backend using Jest
48+
2. Build and tag Docker images (`latest` and versioned)
49+
3. Push images to Docker Hub
50+
4. Trigger **Render deploy hooks** for both frontend and backend
51+
5. Wait for services to go live
52+
6. Run **integration tests** by hitting live endpoints via `curl`
53+
54+
---
55+
56+
## Integration Tests
57+
58+
The integration tests (`scripts/integration-test.sh`) validate the deployed containers by:
59+
60+
- Hitting the backend health check at `/api/health`
61+
- Hitting a key backend API route `/api/water-data`
62+
- Checking that the frontend root (`/`) returns a response
63+
64+
---
65+
66+
## Environment Variables (Set in Render)
67+
68+
**Backend:**
69+
70+
- `MONGODB_URI` → MongoDB Atlas connection string
71+
- `JWT_SECRET` → Secret key for token generation
72+
73+
**Frontend:**
74+
75+
- `REACT_APP_API_URL` → URL of deployed backend (e.g., `https://glow-backend-v4-0-0.onrender.com`)
76+
77+
---
78+
79+
## Manual Test Commands (Optional)
80+
81+
From project root:
82+
83+
```bash
84+
# Run backend locally
85+
cd backend
86+
npm install
87+
npm test
88+
89+
# Run frontend locally
90+
cd frontend
91+
npm install
92+
npm test
93+
94+
# Run integration test against deployed services
95+
bash CICD/scripts/integration-test.sh

CICD/Report.pdf

108 KB
Binary file not shown.

CICD/backend/Dockerfile

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Use the official Node.js runtime as the base image
2+
FROM node:18-alpine
3+
4+
# Set the working directory inside the container
5+
WORKDIR /app
6+
7+
# Copy package.json and package-lock.json (if available)
8+
COPY package*.json ./
9+
10+
# Install dependencies
11+
RUN npm ci --only=production
12+
13+
# Copy the rest of the application code
14+
COPY . .
15+
16+
# Create a non-root user to run the application
17+
RUN addgroup -g 1001 -S nodejs
18+
RUN adduser -S backend -u 1001
19+
20+
# Change ownership of the app directory to the nodejs user
21+
RUN chown -R backend:nodejs /app
22+
USER backend
23+
24+
# Expose the port the app runs on
25+
EXPOSE 5000
26+
27+
# Define the command to run the application
28+
CMD ["npm", "start"]

CICD/frontend/Dockerfile

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# Use the official Node.js runtime as the base image
2+
FROM node:18-alpine
3+
4+
# Set the working directory inside the container
5+
WORKDIR /app
6+
7+
# Copy package.json and package-lock.json (if available)
8+
COPY package*.json ./
9+
10+
# Install dependencies
11+
RUN npm ci --only=production
12+
13+
# Copy the rest of the application code
14+
COPY . .
15+
16+
# Build the Next.js application
17+
RUN npm run build
18+
19+
# Create a non-root user to run the application
20+
RUN addgroup -g 1001 -S nodejs
21+
RUN adduser -S frontend -u 1001
22+
23+
# Change ownership of the app directory to the nodejs user
24+
RUN chown -R frontend:nodejs /app
25+
USER frontend
26+
27+
# Expose the port the app runs on
28+
EXPOSE 3000
29+
30+
# Define the command to run the application
31+
CMD ["npm", "start"]

CICD/scripts/integration-test.sh

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
#!/bin/bash
2+
3+
echo "🔁 Running integration tests on deployed containers..."
4+
5+
# Function to test endpoint with retries
6+
test_endpoint() {
7+
local url=$1
8+
local name=$2
9+
local max_attempts=5
10+
local wait_time=30
11+
12+
for attempt in $(seq 1 $max_attempts); do
13+
echo "🔍 Testing $name (attempt $attempt/$max_attempts)..."
14+
15+
if curl --fail --silent --show-error --max-time 120 "$url"; then
16+
echo "$name is responding"
17+
return 0
18+
else
19+
echo "⚠️ $name failed, waiting ${wait_time}s before retry..."
20+
sleep $wait_time
21+
fi
22+
done
23+
24+
echo "$name failed after $max_attempts attempts"
25+
return 1
26+
}
27+
28+
# Test backend health
29+
test_endpoint "https://glow-backend-v4-0-0.onrender.com/api/health" "Backend health check" || exit 1
30+
31+
# Test backend functional route
32+
test_endpoint "https://glow-backend-v4-0-0.onrender.com/api/water-data" "Backend water data endpoint" || exit 1
33+
34+
# Test frontend
35+
test_endpoint "https://glow-frontend-v4-0-0.onrender.com" "Frontend application" || exit 1
36+
37+
echo "🎉 All integration tests passed successfully!"

0 commit comments

Comments
 (0)