-
Notifications
You must be signed in to change notification settings - Fork 0
217 lines (183 loc) · 7.01 KB
/
test.yml
File metadata and controls
217 lines (183 loc) · 7.01 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
# .github/workflows/cicd-pipeline.yml
name: Complete CI/CD Pipeline
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main, develop ]
workflow_dispatch:
env:
IMAGE_NAME: vite-react-app
NAMESPACE: production
EXTERNAL_PORT: 8080
jobs:
test:
name: Run Tests
runs-on: self-hosted
steps:
- name: Checkout Code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install Dependencies
run: npm ci
- name: Run Linter
run: npm run lint || echo "Linting step skipped"
continue-on-error: true
- name: Run tests
run: npm test
- name: Generate coverage report
run: npm test -- --coverage
continue-on-error: true
- name: Upload coverage
uses: actions/upload-artifact@v4
if: always()
with:
name: coverage-report
path: coverage/
retention-days: 30
build-and-deploy:
name: Build & Deploy to MicroK8s
runs-on: self-hosted
needs: test
if: github.event_name == 'push'
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set image tag
id: image-tag
run: |
TAG="${{ env.IMAGE_NAME }}:${{ github.sha }}"
echo "tag=$TAG" >> $GITHUB_OUTPUT
echo "Image tag: $TAG"
- name: Build Docker image in MicroK8s
run: |
# Build image with Docker and import to MicroK8s
docker build -t ${{ steps.image-tag.outputs.tag }} .
docker save ${{ steps.image-tag.outputs.tag }} > /tmp/app-image.tar
microk8s ctr image import /tmp/app-image.tar
rm /tmp/app-image.tar
# Tag as latest
docker tag ${{ steps.image-tag.outputs.tag }} ${{ env.IMAGE_NAME }}:latest
docker save ${{ env.IMAGE_NAME }}:latest > /tmp/app-image-latest.tar
microk8s ctr image import /tmp/app-image-latest.tar
rm /tmp/app-image-latest.tar
- name: Verify Image in MicroK8s
run: |
echo "Images available in MicroK8s:"
microk8s ctr images ls | grep ${{ env.IMAGE_NAME }}
- name: Setup kubectl
run: |
mkdir -p ~/.kube
microk8s config > ~/.kube/config
- name: Create namespace if not exists
run: |
microk8s kubectl create namespace ${{ env.NAMESPACE }} --dry-run=client -o yaml | microk8s kubectl apply -f -
- name: Update deployment manifest with new image
run: |
sed -i "s|image:.*${{ env.IMAGE_NAME }}.*|image: ${{ steps.image-tag.outputs.tag }}|g" k8s/deployment.yaml
- name: Apply Kubernetes manifests
run: |
microk8s kubectl apply -f k8s/ --namespace=${{ env.NAMESPACE }}
- name: Configure external access with LoadBalancer
run: |
EXTERNAL_IP=$(curl -s ifconfig.me)
echo "External IP: $EXTERNAL_IP"
# Create LoadBalancer service with external IP
cat <<EOF | microk8s kubectl apply -f -
apiVersion: v1
kind: Service
metadata:
name: vite-react-app-service
namespace: ${{ env.NAMESPACE }}
spec:
type: LoadBalancer
externalIPs:
- $EXTERNAL_IP
selector:
app: vite-react-app
ports:
- protocol: TCP
port: ${{ env.EXTERNAL_PORT }}
targetPort: 80
EOF
- name: Wait for rollout
run: |
microk8s kubectl rollout status deployment/vite-react-app \
--namespace=${{ env.NAMESPACE }} \
--timeout=5m
- name: Verify deployment
run: |
echo "Pods:"
microk8s kubectl get pods --namespace=${{ env.NAMESPACE }}
echo ""
echo "Services:"
microk8s kubectl get services --namespace=${{ env.NAMESPACE }}
echo ""
echo "Deployment:"
microk8s kubectl get deployment --namespace=${{ env.NAMESPACE }}
- name: Get service URL
id: service-url
run: |
EXTERNAL_IP=$(curl -s ifconfig.me)
echo "url=http://$EXTERNAL_IP:${{ env.EXTERNAL_PORT }}" >> $GITHUB_OUTPUT
echo "Application URL: http://$EXTERNAL_IP:${{ env.EXTERNAL_PORT }}"
- name: Deployment Summary
run: |
EXTERNAL_IP=$(curl -s ifconfig.me)
echo "## Deployment Status :rocket:" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Namespace:** ${{ env.NAMESPACE }}" >> $GITHUB_STEP_SUMMARY
echo "**Image:** ${{ steps.image-tag.outputs.tag }}" >> $GITHUB_STEP_SUMMARY
echo "**Commit:** ${{ github.sha }}" >> $GITHUB_STEP_SUMMARY
echo "**External URL:** http://$EXTERNAL_IP:${{ env.EXTERNAL_PORT }}" >> $GITHUB_STEP_SUMMARY
echo "**Port:** ${{ env.EXTERNAL_PORT }}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### Pods Status" >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
microk8s kubectl get pods --namespace=${{ env.NAMESPACE }} >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### Service Status" >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
microk8s kubectl get svc --namespace=${{ env.NAMESPACE }} >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
- name: Cleanup old images
run: |
# Keep only the last 5 images
microk8s ctr images ls | grep ${{ env.IMAGE_NAME }} | grep -v latest | awk '{print $1}' | sort -r | tail -n +6 | xargs -r microk8s ctr images rm || true
rollback:
name: Rollback on Failure
runs-on: self-hosted
needs: build-and-deploy
if: failure()
steps:
- name: Setup kubectl
run: |
mkdir -p ~/.kube
microk8s config > ~/.kube/config
- name: Rollback deployment
run: |
microk8s kubectl rollout undo deployment/vite-react-app \
--namespace=${{ env.NAMESPACE }}
- name: Wait for rollback
run: |
microk8s kubectl rollout status deployment/vite-react-app \
--namespace=${{ env.NAMESPACE }} \
--timeout=3m
- name: Verify rollback
run: |
microk8s kubectl get pods --namespace=${{ env.NAMESPACE }}
- name: Rollback Summary
run: |
echo "## Rollback Completed :warning:" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "Deployment has been rolled back to previous version" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### Current Pods" >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
microk8s kubectl get pods --namespace=${{ env.NAMESPACE }} >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY