name: Deploy eCourt Note Web to Server on: push: tags: - "v*.*.*" workflow_dispatch: env: # Container Registry REGISTRY_URL: ${{ vars.CONTAINER_REGISTRY }} REGISTRY_USERNAME: ${{ vars.CONTAINER_REGISTRY_USERNAME }} REGISTRY_PASSWORD: ${{ secrets.CONTAINER_REGISTRY_PASSWORD }} # Docker Image WEB_IMAGE_NAME: chamomind/ecourt-note IMAGE_TAG: ${{ github.ref_name }} # SSH Deployment DEPLOY_HOST: ${{ vars.SSH_DEPLOY_HOST }} DEPLOY_USER: ${{ vars.SSH_DEPLOY_USER }} # Notifications DISCORD_WEBHOOK_URL: ${{ vars.DISCORD_WEBHOOK_URL }} NEXT_PUBLIC_APP_URL: ${{ vars.NEXT_PUBLIC_APP_URL }} jobs: validate-schema: name: Validate Database Schema (Drizzle) runs-on: ubuntu-latest if: startsWith(github.ref, 'refs/tags/') steps: - name: Checkout code uses: actions/checkout@v4 with: fetch-depth: 0 - name: Verify tag is on dev branch run: | echo "======================================================" echo "Verifying tag is pushed to dev branch" echo "======================================================" echo "Tag: ${{ github.ref_name }}" echo "Commit: ${{ github.sha }}" # Fetch dev branch git fetch origin dev # Check if the tag's commit is on dev branch if git branch -r --contains ${{ github.sha }} | grep -q "origin/dev"; then echo "✅ Tag is on dev branch" echo "test_branch=true" >> $GITHUB_ENV else echo "❌ Tag is NOT on dev branch" echo "This workflow only triggers for tags pushed to dev branch" echo "" echo "Current branches containing this commit:" git branch -r --contains ${{ github.sha }} exit 1 fi - name: Check for schema changes id: schema-check run: | # โปรเจกต์นี้ใช้ Drizzle (drizzle-kit push) ไม่มีโฟลเดอร์ migrations — ดูการเปลี่ยนแปลงที่ db/schema.ts if git diff --name-only origin/dev...HEAD | grep -qE "^db/schema\.ts$"; then echo "has_schema_changes=true" >> $GITHUB_OUTPUT echo "✅ Schema changes detected" else echo "has_schema_changes=false" >> $GITHUB_OUTPUT echo "ℹ️ No schema changes" fi - name: Schema change summary if: steps.schema-check.outputs.has_schema_changes == 'true' run: | echo "=== Schema Change Summary ===" echo "" echo "Database schema (db/schema.ts) has been modified in this deployment." echo "This project uses Drizzle push (no migration files)." echo "" echo "⚠️ REMINDERS:" echo " 1. Run 'npx drizzle-kit push' on the target database (staging first)" echo " 2. Monitor logs after deployment" echo "" echo "📚 Reference: README.md / docs/PLAN.md §3" build: name: Build Web Docker Image runs-on: ubuntu-latest needs: validate-schema if: startsWith(github.ref, 'refs/tags/') steps: - name: Checkout code uses: actions/checkout@v4 - name: Log in to Container Registry uses: docker/login-action@v3 with: registry: ${{ env.REGISTRY_URL }} username: ${{ env.REGISTRY_USERNAME }} password: ${{ env.REGISTRY_PASSWORD }} - name: Build Docker image (no buildx) run: | # Build using standard docker build (not buildx) git reset --hard HEAD cd ${{ github.workspace }} docker build \ --no-cache \ --pull \ --file ./docker/web.Dockerfile \ --tag ${{ env.REGISTRY_URL }}/${{ env.WEB_IMAGE_NAME }}:${{ env.IMAGE_TAG }} \ --tag ${{ env.REGISTRY_URL }}/${{ env.WEB_IMAGE_NAME }}:latest \ . echo "✅ Build successful!" docker images | grep ${{ env.WEB_IMAGE_NAME }} - name: Push Docker image run: | docker push ${{ env.REGISTRY_URL }}/${{ env.WEB_IMAGE_NAME }}:${{ env.IMAGE_TAG }} docker push ${{ env.REGISTRY_URL }}/${{ env.WEB_IMAGE_NAME }}:latest echo "✅ Image pushed to registry" - name: Test image can run run: | # Quick test that image can start docker run --rm ${{ env.REGISTRY_URL }}/${{ env.WEB_IMAGE_NAME }}:${{ env.IMAGE_TAG }} node --version deploy: name: Deploy eCourt Note Web to Server runs-on: ubuntu-latest needs: build if: startsWith(github.ref, 'refs/tags/') steps: - name: Deploy web on server uses: appleboy/ssh-action@v1.2.1 with: host: ${{ env.DEPLOY_HOST }} port: ${{ vars.SSH_DEPLOY_PORT }} username: ${{ env.DEPLOY_USER }} password: ${{ secrets.SSH_DEPLOY_PASSWORD }} script: | cd ~/repo chmod +x ./replace-env.sh ./deploy.sh ./replace-env.sh ECOURT_NOTE_TAG "${{ env.IMAGE_TAG }}" ./deploy.sh 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": "✅ eCourt Note Deployment Successful", "description": "eCourt Note Web deployed to server", "color": 3066993, "fields": [ { "name": "Environment", "value": "Test", "inline": true }, { "name": "Tag", "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": "eCourt Note 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": "❌ eCourt Note Deployment Failed", "description": "Failed to deploy eCourt Note Web to server", "color": 15158332, "fields": [ { "name": "Environment", "value": "Test", "inline": true }, { "name": "Tag", "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": "eCourt Note CD Pipeline" }, "timestamp": "'"$(date -u +%Y-%m-%dT%H:%M:%S.000Z)"'" }] }' \ ${{ env.DISCORD_WEBHOOK_URL }} exit 1