1010 IMAGE_NAME : ${{ github.repository }}
1111
1212jobs :
13+ check-changes :
14+ name : Check What Changed
15+ runs-on : [self-hosted, home]
16+ outputs :
17+ backend-changed : ${{ steps.changes.outputs.backend }}
18+ frontend-changed : ${{ steps.changes.outputs.frontend }}
19+ steps :
20+ - name : Checkout code
21+ uses : actions/checkout@v4
22+ with :
23+ fetch-depth : 2 # Need at least 2 commits to compare
24+
25+ - name : Check for changes
26+ id : changes
27+ run : |
28+ # Check if this is the first commit (no previous commit to compare)
29+ if git rev-parse HEAD~1 >/dev/null 2>&1; then
30+ # Compare with previous commit
31+ BACKEND_CHANGED=$(git diff --name-only HEAD~1 HEAD | grep -E '^(cmd/|internal/|pkg/|go\.|configs/|deployments/|\.github/workflows/deploy\.yml)' || echo '')
32+ FRONTEND_CHANGED=$(git diff --name-only HEAD~1 HEAD | grep -E '^frontend/' || echo '')
33+ else
34+ # First commit - build everything
35+ BACKEND_CHANGED="initial"
36+ FRONTEND_CHANGED="initial"
37+ fi
38+
39+ # Set outputs
40+ if [ -n "$BACKEND_CHANGED" ]; then
41+ echo "backend=true" >> $GITHUB_OUTPUT
42+ echo "🔍 Backend changes detected: $BACKEND_CHANGED"
43+ else
44+ echo "backend=false" >> $GITHUB_OUTPUT
45+ echo "✅ No backend changes detected"
46+ fi
47+
48+ if [ -n "$FRONTEND_CHANGED" ]; then
49+ echo "frontend=true" >> $GITHUB_OUTPUT
50+ echo "🔍 Frontend changes detected: $FRONTEND_CHANGED"
51+ else
52+ echo "frontend=false" >> $GITHUB_OUTPUT
53+ echo "✅ No frontend changes detected"
54+ fi
55+
1356 build-and-push :
14- name : Build and Push to GHCR
57+ name : Build and Push Backend
1558 runs-on : [self-hosted, home]
59+ needs : check-changes
60+ if : needs.check-changes.outputs.backend-changed == 'true'
1661 permissions :
1762 contents : read
1863 packages : write
56101 build-frontend-image :
57102 name : Build Frontend Container
58103 runs-on : [self-hosted, home]
104+ needs : check-changes
105+ if : needs.check-changes.outputs.frontend-changed == 'true'
59106 permissions :
60107 contents : read
61108 packages : write
@@ -99,10 +146,22 @@ jobs:
99146 deploy-via-portainer :
100147 name : Deploy via Portainer
101148 runs-on : [self-hosted, home]
102- needs : [build-and-push, build-frontend-image]
103- if : success() && github.ref == 'refs/heads/main'
149+ needs : [check-changes, build-and-push, build-frontend-image]
150+ if : always() && github.ref == 'refs/heads/main' &&
151+ (needs.build-and-push.result == 'success' || needs.build-and-push.result == 'skipped') &&
152+ (needs.build-frontend-image.result == 'success' || needs.build-frontend-image.result == 'skipped') &&
153+ (needs.check-changes.outputs.backend-changed == 'true' || needs.check-changes.outputs.frontend-changed == 'true')
104154
105155 steps :
156+ - name : Deployment Info
157+ run : |
158+ echo "📋 **Deployment Information**" >> $GITHUB_STEP_SUMMARY
159+ echo "" >> $GITHUB_STEP_SUMMARY
160+ echo "- **Backend Changed**: ${{ needs.check-changes.outputs.backend-changed }}" >> $GITHUB_STEP_SUMMARY
161+ echo "- **Frontend Changed**: ${{ needs.check-changes.outputs.frontend-changed }}" >> $GITHUB_STEP_SUMMARY
162+ echo "- **Backend Build**: ${{ needs.build-and-push.result }}" >> $GITHUB_STEP_SUMMARY
163+ echo "- **Frontend Build**: ${{ needs.build-frontend-image.result }}" >> $GITHUB_STEP_SUMMARY
164+
106165 - name : Verify Portainer Connection
107166 run : |
108167 echo "🔍 Verifying connection to Portainer..."
@@ -128,10 +187,14 @@ jobs:
128187 PORTAINER_URL : https://portainer.sankalpnarula.com
129188 PORTAINER_TOKEN : ${{ secrets.PORTAINER_ACCESS_TOKEN }}
130189 STACK_NAME : ocpp-chaos-sim
190+ BACKEND_CHANGED : ${{ needs.check-changes.outputs.backend-changed }}
191+ FRONTEND_CHANGED : ${{ needs.check-changes.outputs.frontend-changed }}
131192 run : |
132193 set -e
133194
134195 echo "🚀 Starting deployment process..."
196+ echo "Backend changed: $BACKEND_CHANGED"
197+ echo "Frontend changed: $FRONTEND_CHANGED"
135198
136199 # Get stack ID
137200 echo "🔍 Looking for stack: $STACK_NAME"
@@ -148,14 +211,14 @@ jobs:
148211
149212 echo "📋 Found stack ID: $STACK_ID"
150213
151- # Get endpoint ID (usually 1 for local Docker, but let's be sure)
214+ # Get endpoint ID
152215 ENDPOINT_ID=$(curl -s -H "X-API-Key: $PORTAINER_TOKEN" \
153216 "$PORTAINER_URL/api/stacks/$STACK_ID" | \
154217 jq -r '.EndpointId')
155218
156219 echo "🎯 Using endpoint ID: $ENDPOINT_ID"
157220
158- # Trigger stack update (pull latest images and redeploy )
221+ # Trigger stack update (always pull images, even if only one service changed )
159222 echo "🔄 Triggering stack redeployment with image pull..."
160223 RESPONSE=$(curl -s -w "%{http_code}" -X PUT \
161224 -H "X-API-Key: $PORTAINER_TOKEN" \
@@ -188,17 +251,6 @@ jobs:
188251 jq -r '.Status // "unknown"')
189252
190253 echo "📊 Stack status: $STACK_STATUS"
191-
192- # Optional: Check if services are running
193- echo "🔍 Checking service status..."
194- SERVICES=$(curl -s -H "X-API-Key: $PORTAINER_TOKEN" \
195- "$PORTAINER_URL/api/endpoints/$ENDPOINT_ID/docker/services" | \
196- jq -r '.[] | select(.Spec.Labels."com.docker.compose.project" == "'$STACK_NAME'") | "\(.Spec.Name): \(.ServiceStatus.RunningTasks)/\(.Spec.Mode.Replicated.Replicas)"' 2>/dev/null || echo "Service status unavailable")
197-
198- if [ "$SERVICES" != "Service status unavailable" ]; then
199- echo "📋 Services:"
200- echo "$SERVICES"
201- fi
202254
203255 - name : Deployment Summary
204256 if : always()
@@ -208,13 +260,28 @@ jobs:
208260 if [ "${{ job.status }}" = "success" ]; then
209261 echo "✅ **Status**: Deployment successful" >> $GITHUB_STEP_SUMMARY
210262 echo "🔗 **Portainer**: [View Stack](https://portainer.sankalpnarula.com)" >> $GITHUB_STEP_SUMMARY
211- echo "📦 **Backend Image**: \`ghcr.io/${{ github.repository }}:latest\`" >> $GITHUB_STEP_SUMMARY
212- echo "📦 **Frontend Image**: \`ghcr.io/${{ github.repository }}-frontend:latest\`" >> $GITHUB_STEP_SUMMARY
263+ if [ "${{ needs.check-changes.outputs.backend-changed }}" = "true" ]; then
264+ echo "📦 **Backend Image**: \`ghcr.io/${{ github.repository }}:latest\` (updated)" >> $GITHUB_STEP_SUMMARY
265+ else
266+ echo "📦 **Backend Image**: \`ghcr.io/${{ github.repository }}:latest\` (unchanged)" >> $GITHUB_STEP_SUMMARY
267+ fi
268+ if [ "${{ needs.check-changes.outputs.frontend-changed }}" = "true" ]; then
269+ echo "📦 **Frontend Image**: \`ghcr.io/${{ github.repository }}-frontend:latest\` (updated)" >> $GITHUB_STEP_SUMMARY
270+ else
271+ echo "📦 **Frontend Image**: \`ghcr.io/${{ github.repository }}-frontend:latest\` (unchanged)" >> $GITHUB_STEP_SUMMARY
272+ fi
213273 echo "" >> $GITHUB_STEP_SUMMARY
214- echo "**Deployment included:**" >> $GITHUB_STEP_SUMMARY
215- echo "- ✅ Pull latest images from GHCR" >> $GITHUB_STEP_SUMMARY
216- echo "- ✅ Recreate containers with new images" >> $GITHUB_STEP_SUMMARY
217- echo "- ✅ Prune old unused images" >> $GITHUB_STEP_SUMMARY
274+ echo "**What was deployed:**" >> $GITHUB_STEP_SUMMARY
275+ if [ "${{ needs.check-changes.outputs.backend-changed }}" = "true" ]; then
276+ echo "- ✅ Backend: Built and deployed new image" >> $GITHUB_STEP_SUMMARY
277+ else
278+ echo "- ⏭️ Backend: No changes, using existing image" >> $GITHUB_STEP_SUMMARY
279+ fi
280+ if [ "${{ needs.check-changes.outputs.frontend-changed }}" = "true" ]; then
281+ echo "- ✅ Frontend: Built and deployed new image" >> $GITHUB_STEP_SUMMARY
282+ else
283+ echo "- ⏭️ Frontend: No changes, using existing image" >> $GITHUB_STEP_SUMMARY
284+ fi
218285 else
219286 echo "❌ **Status**: Deployment failed" >> $GITHUB_STEP_SUMMARY
220287 echo "🔍 **Check**: Review job logs for details" >> $GITHUB_STEP_SUMMARY
0 commit comments