Skip to content

Updating frontend architecture #16

Updating frontend architecture

Updating frontend architecture #16

Workflow file for this run

name: Build and Deploy
on:
push:
branches: ["main"]
workflow_dispatch: # Allow manual triggering
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
PORTAINER_WEBHOOK_URL: ${{ secrets.PORTAINER_WEBHOOK_URL }}
jobs:
check-changes:
name: Check What Changed
runs-on: [self-hosted, home]
outputs:
backend-changed: ${{ steps.changes.outputs.backend }}
frontend-changed: ${{ steps.changes.outputs.frontend }}
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 2 # Need at least 2 commits to compare
- name: Check for changes
id: changes
run: |
# Check if this is the first commit (no previous commit to compare)
if git rev-parse HEAD~1 >/dev/null 2>&1; then
# Compare with previous commit
BACKEND_CHANGED=$(git diff --name-only HEAD~1 HEAD | grep -E '^(cmd/|internal/|pkg/|go\.|configs/|deployments/|\.github/workflows/deploy\.yml)' || echo '')
FRONTEND_CHANGED=$(git diff --name-only HEAD~1 HEAD | grep -E '^frontend/' || echo '')
else
# First commit - build everything
BACKEND_CHANGED="initial"
FRONTEND_CHANGED="initial"
fi
# Set outputs
if [ -n "$BACKEND_CHANGED" ]; then
echo "backend=true" >> $GITHUB_OUTPUT
echo "πŸ” Backend changes detected: $BACKEND_CHANGED"
else
echo "backend=false" >> $GITHUB_OUTPUT
echo "βœ… No backend changes detected"
fi
if [ -n "$FRONTEND_CHANGED" ]; then
echo "frontend=true" >> $GITHUB_OUTPUT
echo "πŸ” Frontend changes detected: $FRONTEND_CHANGED"
else
echo "frontend=false" >> $GITHUB_OUTPUT
echo "βœ… No frontend changes detected"
fi
build-and-push:
name: Build and Push Backend
runs-on: [self-hosted, home]
needs: check-changes
if: needs.check-changes.outputs.backend-changed == 'true'
permissions:
contents: read
packages: write
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=ref,event=branch
type=sha,prefix={{branch}}-
type=raw,value=latest,enable={{is_default_branch}}
- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: .
file: ./deployments/Dockerfile
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
platforms: linux/amd64,linux/arm64
build-frontend-image:
name: Build Frontend Container
runs-on: [self-hosted, home]
needs: check-changes
if: needs.check-changes.outputs.frontend-changed == 'true'
permissions:
contents: read
packages: write
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata for frontend
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-frontend
tags: |
type=ref,event=branch
type=sha,prefix={{branch}}-
type=raw,value=latest,enable={{is_default_branch}}
- name: Build and push Frontend Docker image
uses: docker/build-push-action@v5
with:
context: ./frontend
file: ./frontend/Dockerfile
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
platforms: linux/amd64,linux/arm64
deploy-via-portainer:
name: Deploy via Portainer
runs-on: [self-hosted, home]
needs: [check-changes, build-and-push, build-frontend-image]
if: always() && github.ref == 'refs/heads/main' &&
(needs.build-and-push.result == 'success' || needs.build-and-push.result == 'skipped') &&
(needs.build-frontend-image.result == 'success' || needs.build-frontend-image.result == 'skipped') &&
(needs.check-changes.outputs.backend-changed == 'true' || needs.check-changes.outputs.frontend-changed == 'true')
steps:
- name: Deployment Info
run: |
echo "πŸ“‹ **Deployment Information**" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "- **Backend Changed**: ${{ needs.check-changes.outputs.backend-changed }}" >> $GITHUB_STEP_SUMMARY
echo "- **Frontend Changed**: ${{ needs.check-changes.outputs.frontend-changed }}" >> $GITHUB_STEP_SUMMARY
echo "- **Backend Build**: ${{ needs.build-and-push.result }}" >> $GITHUB_STEP_SUMMARY
echo "- **Frontend Build**: ${{ needs.build-frontend-image.result }}" >> $GITHUB_STEP_SUMMARY
- name: Verify Portainer Connection
run: |
echo "πŸ” Verifying connection to Portainer..."
if curl -f -s --connect-timeout 10 https://portainer.sankalpnarula.com/api/status > /dev/null; then
echo "βœ… Successfully connected to Portainer"
else
echo "❌ Failed to connect to Portainer"
exit 1
fi
- name: Trigger Portainer Stack Redeployment
env:
PORTAINER_WEBHOOK_URL: ${{ secrets.PORTAINER_WEBHOOK_URL }}
BACKEND_CHANGED: ${{ needs.check-changes.outputs.backend-changed }}
FRONTEND_CHANGED: ${{ needs.check-changes.outputs.frontend-changed }}
run: |
echo "πŸš€ Starting deployment process..."
echo "πŸ“‹ Backend changed: $BACKEND_CHANGED"
echo "πŸ“‹ Frontend changed: $FRONTEND_CHANGED"
# Trigger redeployment via webhook
echo "πŸ”„ Triggering stack redeployment via webhook..."
RESPONSE=$(curl -s -w "%{http_code}" -X POST \
-H "Content-Type: application/json" \
-d '{"pullImage": true}' \
"$PORTAINER_WEBHOOK_URL")
HTTP_CODE="${RESPONSE: -3}"
RESPONSE_BODY="${RESPONSE%???}"
case $HTTP_CODE in
200|204)
echo "βœ… Stack redeployment triggered successfully!"
[ -n "$RESPONSE_BODY" ] && echo "πŸ“ Response: $RESPONSE_BODY"
;;
*)
echo "❌ Deployment webhook failed with HTTP $HTTP_CODE"
echo "πŸ“ Response: $RESPONSE_BODY"
echo "πŸ”— Check Portainer for more details"
exit 1
;;
esac
echo "⏳ Deployment initiated via webhook - check Portainer for progress"
echo "πŸ”— Monitor at: https://portainer.sankalpnarula.com"
- name: Deployment Summary
if: always()
run: |
echo "🎯 **Portainer Deployment Summary**" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
if [ "${{ job.status }}" = "success" ]; then
echo "βœ… **Status**: Deployment successful" >> $GITHUB_STEP_SUMMARY
echo "πŸ”— **Portainer**: [View Stack](https://portainer.sankalpnarula.com)" >> $GITHUB_STEP_SUMMARY
if [ "${{ needs.check-changes.outputs.backend-changed }}" = "true" ]; then
echo "πŸ“¦ **Backend Image**: \`ghcr.io/${{ github.repository }}:latest\` (updated)" >> $GITHUB_STEP_SUMMARY
else
echo "πŸ“¦ **Backend Image**: \`ghcr.io/${{ github.repository }}:latest\` (unchanged)" >> $GITHUB_STEP_SUMMARY
fi
if [ "${{ needs.check-changes.outputs.frontend-changed }}" = "true" ]; then
echo "πŸ“¦ **Frontend Image**: \`ghcr.io/${{ github.repository }}-frontend:latest\` (updated)" >> $GITHUB_STEP_SUMMARY
else
echo "πŸ“¦ **Frontend Image**: \`ghcr.io/${{ github.repository }}-frontend:latest\` (unchanged)" >> $GITHUB_STEP_SUMMARY
fi
echo "" >> $GITHUB_STEP_SUMMARY
echo "**What was deployed:**" >> $GITHUB_STEP_SUMMARY
if [ "${{ needs.check-changes.outputs.backend-changed }}" = "true" ]; then
echo "- βœ… Backend: Built and deployed new image" >> $GITHUB_STEP_SUMMARY
else
echo "- ⏭️ Backend: No changes, using existing image" >> $GITHUB_STEP_SUMMARY
fi
if [ "${{ needs.check-changes.outputs.frontend-changed }}" = "true" ]; then
echo "- βœ… Frontend: Built and deployed new image" >> $GITHUB_STEP_SUMMARY
else
echo "- ⏭️ Frontend: No changes, using existing image" >> $GITHUB_STEP_SUMMARY
fi
else
echo "❌ **Status**: Deployment failed" >> $GITHUB_STEP_SUMMARY
echo "πŸ” **Check**: Review job logs for details" >> $GITHUB_STEP_SUMMARY
echo "πŸ”— **Portainer**: [Check Stack Status](https://portainer.sankalpnarula.com)" >> $GITHUB_STEP_SUMMARY
fi