name: Build and Deploy Frontend Learner on: push: tags: - "learner-dev-v[0-9]+.[0-9]+.[0-9]+" - "learner-dev-v[0-9]+.[0-9]+.[0-9]+-*" workflow_dispatch: env: REGISTRY: ${{ vars.CONTAINER_REGISTRY }} REGISTRY_USERNAME: ${{ vars.CONTAINER_REGISTRY_USERNAME }} REGISTRY_PASSWORD: ${{ secrets.CONTAINER_REGISTRY_PASSWORD }} # Docker Image IMAGE_NAME: chamomind/elearning-learner # Notifications DISCORD_WEBHOOK_URL: ${{ vars.DISCORD_WEBHOOK_URL }} jobs: build: name: Build Frontend Learner Docker Image runs-on: ubuntu-latest outputs: version: ${{ steps.version.outputs.version }} steps: - name: Checkout code uses: actions/checkout@v4 - name: Extract version from tag id: version run: | if [[ "${{ github.event_name }}" == "push" ]]; then # Tag: learner-dev-v1.2.3 → Version: 1.2.3 VERSION=$(echo "${{ github.ref_name }}" | sed 's/learner-dev-v//g') echo "version=${VERSION}" >> $GITHUB_OUTPUT else # Manual run: use latest-{run_number} echo "version=latest-${{ github.run_number }}" >> $GITHUB_OUTPUT fi - name: Log in to Container Registry uses: docker/login-action@v3 with: registry: ${{ env.REGISTRY }} username: ${{ env.REGISTRY_USERNAME }} password: ${{ env.REGISTRY_PASSWORD }} - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 with: config-inline: | [registry."${{ env.REGISTRY }}"] http = true insecure = true - name: Extract metadata id: meta uses: docker/metadata-action@v5 with: images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} tags: | type=raw,value=${{ steps.version.outputs.version }} type=raw,value=latest,enable=${{ github.event_name == 'push' }} - name: Build and Push Docker image uses: docker/build-push-action@v5 with: context: ./Frontend-Learner file: ./Frontend-Learner/Dockerfile push: true tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} cache-from: type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:buildcache cache-to: type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:buildcache,mode=max deploy: name: Deploy E-learning Frontend Learner to Dev Server runs-on: ubuntu-latest needs: build steps: - name: Deploy frontend learner on server uses: appleboy/ssh-action@v1.2.1 with: host: ${{ vars.SSH_DEPLOY_HOST }} port: ${{ vars.SSH_DEPLOY_PORT }} username: ${{ secrets.SSH_DEPLOY_USER }} password: ${{ secrets.SSH_DEPLOY_PASSWORD }} script: | cd ~/repo chmod +x ./replace-env.sh ./deploy.sh ./replace-env.sh FRONTEND_TAG "${{ needs.build.outputs.version }}" ./deploy.sh learner notify: name: Notify Deployment Status runs-on: ubuntu-latest needs: [build, deploy] if: always() steps: - name: Send Discord notification - Success if: ${{ needs.deploy.result == 'success' }} run: | curl -H "Content-Type: application/json" \ -d '{ "embeds": [{ "title": "✅ E-learning Frontend Learner Deployment Successful", "description": "E-learning Frontend Learner deployed to dev server", "color": 3066993, "fields": [ { "name": "Environment", "value": "Development", "inline": true }, { "name": "Branch", "value": "${{ github.ref_name }}", "inline": true }, { "name": "Commit", "value": "`${{ github.sha }}`", "inline": false }, { "name": "Image Tag", "value": "`${{ env.IMAGE_TAG }}`", "inline": true }, { "name": "Web URL", "value": "${{ env.NEXT_PUBLIC_APP_URL }}", "inline": false }, { "name": "Deployed By", "value": "${{ github.actor }}", "inline": true } ], "footer": { "text": "CMP CD Pipeline" }, "timestamp": "'"$(date -u +%Y-%m-%dT%H:%M:%S.000Z)"'" }] }' \ ${{ env.DISCORD_WEBHOOK_URL }} - name: Send Discord notification - Failure if: ${{ needs.deploy.result == 'failure' || needs.build.result == 'failure' }} run: | curl -H "Content-Type: application/json" \ -d '{ "embeds": [{ "title": "❌ E-learning Frontend Learner Deployment Failed", "description": "Failed to deploy E-learning Frontend Learner to dev server", "color": 15158332, "fields": [ { "name": "Environment", "value": "Development", "inline": true }, { "name": "Branch", "value": "${{ github.ref_name }}", "inline": true }, { "name": "Commit", "value": "`${{ github.sha }}`", "inline": false }, { "name": "Failed Job", "value": "${{ needs.build.result == 'failure' && 'Build' || 'Deploy' }}", "inline": true }, { "name": "Deployed By", "value": "${{ github.actor }}", "inline": true } ], "footer": { "text": "CMP CD Pipeline" }, "timestamp": "'"$(date -u +%Y-%m-%dT%H:%M:%S.000Z)"'" }] }' \ ${{ env.DISCORD_WEBHOOK_URL }} exit 1