Files
hack/tools/scripts/llm-key-hunter/results/_cache/content/cesi-a4-advanced-web_transvirex.json
T

1 line
302 KiB
JSON

{"repo": "cesi-a4-advanced-web/transvirex", "files": {".github/workflows/deploy.yaml": {"f7e3ad1d024ccf4bfbb213d903b3947f4359acf9": {"t": 1785747046.8400528, "n": 25010, "h": "fefcd2385886b2b3", "c": "name: 🚀 Build & Deploy\n\non:\n push:\n branches:\n - main\n - develop\n pull_request:\n branches:\n - main\n - develop\n\nenv:\n REGISTRY: ghcr.io\n\njobs:\n build-frontend:\n name: 🏗️ Build Frontend Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-frontend\n tags: |\n type=ref,event=branch\n type=ref,event=pr\n type=sha,prefix=sha-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/frontend\n file: ./packages/frontend/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: production\n cache-from: type=gha,scope=frontend\n cache-to: type=gha,scope=frontend,mode=max\n\n build-gateway:\n name: 🏗️ Build Gateway Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-gateway-service\n tags: |\n type=ref,event=branch\n type=ref,event=pr\n type=sha,prefix=sha-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/backend\n file: ./packages/backend/apps/gateway/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: runtime\n cache-from: type=gha,scope=gateway\n cache-to: type=gha,scope=gateway,mode=max\n\n build-authentication:\n name: 🏗️ Build Authentication Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-authentication-service\n tags: |\n type=ref,event=branch\n type=ref,event=pr\n type=sha,prefix=sha-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/backend\n file: ./packages/backend/apps/authentication/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: runtime\n cache-from: type=gha,scope=authentication\n cache-to: type=gha,scope=authentication,mode=max\n\n build-billing:\n name: 🏗️ Build Billing Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-billing-service\n tags: |\n type=ref,event=branch\n type=ref,event=pr\n type=sha,prefix=sha-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/backend\n file: ./packages/backend/apps/billing/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: runtime\n cache-from: type=gha,scope=billing\n cache-to: type=gha,scope=billing,mode=max\n\n build-stock:\n name: 🏗️ Build Stock Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-stock-service\n tags: |\n type=ref,event=branch\n type=ref,event=pr\n type=sha,prefix=sha-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/backend\n file: ./packages/backend/apps/stock/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: runtime\n cache-from: type=gha,scope=stock\n cache-to: type=gha,scope=stock,mode=max\n\n build-delivery:\n name: 🏗️ Build Delivery Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-delivery-service\n tags: |\n type=ref,event=branch\n type=ref,event=pr\n type=sha,prefix=sha-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/backend\n file: ./packages/backend/apps/delivery/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: runtime\n cache-from: type=gha,scope=delivery\n cache-to: type=gha,scope=delivery,mode=max\n\n build-users:\n name: 🏗️ Build Users Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-users-service\n tags: |\n type=ref,event=branch\n type=ref,event=pr\n type=sha,prefix=sha-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/backend\n file: ./packages/backend/apps/users/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: runtime\n cache-from: type=gha,scope=users\n cache-to: type=gha,scope=users,mode=max\n\n build-ai:\n name: 🏗️ Build & Test AI Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-ai-service\n tags: |\n type=ref,event=branch\n type=ref,event=pr\n type=sha,prefix=sha-\n type=raw,value=latest,enable={{is_default_branch}}\n\n # Build locally (load into the runner's Docker) so we can smoke-test\n # the container before pushing a potentially broken image.\n - name: 🏗️ Build AI image (load for test)\n uses: docker/build-push-action@v5\n with:\n context: ./packages/backend/apps/ai\n file: ./packages/backend/apps/ai/Dockerfile\n target: runtime\n load: true\n push: false\n tags: transvirex-ai-service:ci-test\n cache-from: type=gha,scope=ai\n cache-to: type=gha,scope=ai,mode=max\n\n - name: 🧪 Smoke-test AI container (/health)\n run: |\n docker run -d --name ai-test \\\n -e DEEPSEEK_API_KEY=ci-test-key \\\n -p 5000:5000 transvirex-ai-service:ci-test\n ok=0\n for i in $(seq 1 30); do\n if curl -fsS http://localhost:5000/health | grep -q '\"status\":\"ok\"'; then\n echo \"✅ AI service healthy\"; ok=1; break\n fi\n sleep 2\n done\n echo \"----- container logs -----\"\n docker logs ai-test || true\n docker rm -f ai-test\n if [ \"$ok\" != \"1\" ]; then\n echo \"❌ AI container failed its /health check\"; exit 1\n fi\n\n - name: 📤 Push AI image\n if: github.event_name != 'pull_request'\n uses: docker/build-push-action@v5\n with:\n context: ./packages/backend/apps/ai\n file: ./packages/backend/apps/ai/Dockerfile\n target: runtime\n push: true\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n cache-from: type=gha,scope=ai\n cache-to: type=gha,scope=ai,mode=max\n\n deploy:\n name: 🚀 Deploy to Production\n runs-on: ubuntu-latest\n needs:\n [\n build-frontend,\n build-gateway,\n build-authentication,\n build-billing,\n build-stock,\n build-delivery,\n build-users,\n build-ai,\n ]\n if: github.ref == 'refs/heads/main' && github.event_name == 'push'\n\n steps:\n - uses: actions/checkout@v4\n\n - uses: docker/login-action@v3\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n\n - name: 📋 Create production namespace & secrets\n uses: appleboy/ssh-action@v0.1.7\n env:\n GHCR_USERNAME: ${{ github.actor }}\n GHCR_TOKEN: ${{ secrets.GHCR_PAT }}\n JWT_SECRET: ${{ secrets.JWT_SECRET }}\n DEEPSEEK_API_KEY: ${{ secrets.DEEPSEEK_API_KEY }}\n with:\n host: ${{ secrets.VPS_HOST }}\n username: github-actions\n key: ${{ secrets.VPS_SSH_KEY }}\n port: 22\n envs: GHCR_USERNAME,GHCR_TOKEN,JWT_SECRET,DEEPSEEK_API_KEY\n script: |\n kubectl create namespace production --kubeconfig ~/.kube/config 2>/dev/null || true\n\n # ghcr-secret : apply idempotent (pas de delete/create)\n kubectl create secret docker-registry ghcr-secret \\\n --docker-server=ghcr.io \\\n --docker-username=$GHCR_USERNAME \\\n --docker-password=$GHCR_TOKEN \\\n -n production \\\n --kubeconfig ~/.kube/config \\\n --dry-run=client -o yaml | kubectl apply -f - --kubeconfig ~/.kube/config\n\n # Garde-fou : on refuse de déployer un secret vide, ce qui\n # écraserait silencieusement la clé valide (-> crash du service AI / 503).\n if [ -z \"$JWT_SECRET\" ] || [ -z \"$DEEPSEEK_API_KEY\" ]; then\n echo \"❌ JWT_SECRET ou DEEPSEEK_API_KEY vide — abandon pour ne pas écraser le secret existant\"\n exit 1\n fi\n\n # transvirex-secrets : apply idempotent (crée si absent, met à jour\n # sinon, sans fenêtre où le secret n'existe plus).\n kubectl create secret generic transvirex-secrets \\\n --from-literal=JWT_SECRET=\"$JWT_SECRET\" \\\n --from-literal=DEEPSEEK_API_KEY=\"$DEEPSEEK_API_KEY\" \\\n -n production \\\n --kubeconfig ~/.kube/config \\\n --dry-run=client -o yaml | kubectl apply -f - --kubeconfig ~/.kube/config\n\n rm -rf /tmp/k8s-manifests && mkdir -p /tmp/k8s-manifests\n\n - name: 🚀 Transfer K8s manifests\n uses: appleboy/scp-action@v0.1.4\n with:\n host: ${{ secrets.VPS_HOST }}\n username: github-actions\n key: ${{ secrets.VPS_SSH_KEY }}\n port: 22\n source: 'kubernetes/'\n target: '/tmp/k8s-manifests'\n overwrite: true\n\n - name: ⚡ Apply manifests & rollout\n uses: appleboy/ssh-action@v0.1.7\n with:\n host: ${{ secrets.VPS_HOST }}\n username: github-actions\n key: ${{ secrets.VPS_SSH_KEY }}\n port: 22\n command_timeout: 15m\n script: |\n kubectl apply -k /tmp/k8s-manifests/kubernetes --kubeconfig ~/.kube/config\n\n kubectl rollout restart deployment/transvirex-frontend -n production --kubeconfig ~/.kube/config\n kubectl rollout restart deployment/transvirex-gateway -n production --kubeconfig ~/.kube/config\n kubectl rollout restart deployment/transvirex-authentication -n production --kubeconfig ~/.kube/config\n kubectl rollout restart deployment/transvirex-billing -n production --kubeconfig ~/.kube/config\n kubectl rollout restart deployment/transvirex-stock -n production --kubeconfig ~/.kube/config\n kubectl rollout restart deployment/transvirex-delivery -n production --kubeconfig ~/.kube/config\n kubectl rollout restart deployment/transvirex-users -n production --kubeconfig ~/.kube/config\n kubectl rollout restart deployment/transvirex-ai -n production --kubeconfig ~/.kube/config\n\n kubectl rollout status deployment/transvirex-frontend -n production --timeout=10m --kubeconfig ~/.kube/config\n kubectl rollout status deployment/transvirex-gateway -n production --timeout=10m --kubeconfig ~/.kube/config\n kubectl rollout status deployment/transvirex-authentication -n production --timeout=10m --kubeconfig ~/.kube/config\n kubectl rollout status deployment/transvirex-billing -n production --timeout=10m --kubeconfig ~/.kube/config\n kubectl rollout status deployment/transvirex-stock -n production --timeout=10m --kubeconfig ~/.kube/config\n kubectl rollout status deployment/transvirex-delivery -n production --timeout=10m --kubeconfig ~/.kube/config\n kubectl rollout status deployment/transvirex-users -n production --timeout=10m --kubeconfig ~/.kube/config\n kubectl rollout status deployment/transvirex-ai -n production --timeout=10m --kubeconfig ~/.kube/config\n\n kubectl delete job transvirex-seed -n production --kubeconfig ~/.kube/config --ignore-not-found=true\n kubectl apply -f /tmp/k8s-manifests/kubernetes/jobs/seed.yaml --kubeconfig ~/.kube/config\n kubectl wait --for=condition=complete job/transvirex-seed -n production --timeout=2m --kubeconfig ~/.kube/config\n\n rm -rf /tmp/k8s-manifests\n\n notify:\n name: 📢 Notify\n runs-on: ubuntu-latest\n needs:\n [\n build-frontend,\n build-gateway,\n build-authentication,\n build-billing,\n build-stock,\n build-delivery,\n build-users,\n build-ai,\n deploy,\n ]\n if: always()\n\n steps:\n - name: ✅ Notify Discord - Success\n if: ${{ !contains(needs.*.result, 'failure') && !contains(needs.*.result, 'cancelled') }}\n run: |\n curl -H \"Content-Type: application/json\" \\\n -d '{\n \"embeds\": [{\n \"title\": \"✅ Déploiement réussi\",\n \"color\": 3066993,\n \"fields\": [\n {\"name\": \"Repo\", \"value\": \"${{ github.repository }}\", \"inline\": true},\n {\"name\": \"Branche\", \"value\": \"${{ github.ref_name }}\", \"inline\": true},\n {\"name\": \"Commit\", \"value\": \"[`${{ github.sha }}`](${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }})\", \"inline\": false},\n {\"name\": \"Déclenché par\", \"value\": \"${{ github.actor }}\", \"inline\": true}\n ]\n }]\n }' \\\n ${{ secrets.DISCORD_WEBHOOK_URL }}\n\n - name: ❌ Notify Discord - Failure\n if: ${{ contains(needs.*.result, 'failure') && !contains(needs.*.result, 'cancelled') && github.event_name != 'pull_request' }}\n run: |\n curl -H \"Content-Type: application/json\" \\\n -d '{\n \"embeds\": [{\n \"title\": \"❌ Déploiement échoué\",\n \"color\": 15158332,\n \"fields\": [\n {\"name\": \"Repo\", \"value\": \"${{ github.repository }}\", \"inline\": true},\n {\"name\": \"Branche\", \"value\": \"${{ github.ref_name }}\", \"inline\": true},\n {\"name\": \"Commit\", \"value\": \"[`${{ github.sha }}`](${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }})\", \"inline\": false},\n {\"name\": \"Déclenché par\", \"value\": \"${{ github.actor }}\", \"inline\": true},\n {\"name\": \"Logs\", \"value\": \"[${{ github.run_id }}](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})\", \"inline\": false}\n ]\n }]\n }' \\\n ${{ secrets.DISCORD_WEBHOOK_URL }}\n\n - name: ⚠️ Notify Discord - Cancelled\n if: ${{ contains(needs.*.result, 'cancelled') && github.event_name != 'pull_request' }}\n run: |\n curl -H \"Content-Type: application/json\" \\\n -d '{\n \"embeds\": [{\n \"title\": \"⚠️ Déploiement annulé\",\n \"color\": 16776960,\n \"fields\": [\n {\"name\": \"Repo\", \"value\": \"${{ github.repository }}\", \"inline\": true},\n {\"name\": \"Branche\", \"value\": \"${{ github.ref_name }}\", \"inline\": true},\n {\"name\": \"Commit\", \"value\": \"[`${{ github.sha }}`](${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }})\", \"inline\": false},\n {\"name\": \"Déclenché par\", \"value\": \"${{ github.actor }}\", \"inline\": true},\n {\"name\": \"Logs\", \"value\": \"[${{ github.run_id }}](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})\", \"inline\": false}\n ]\n }]\n }' \\\n ${{ secrets.DISCORD_WEBHOOK_URL }}\n\n - name: ⚠️ Notify Discord - PR Build failure\n if: ${{ contains(needs.*.result, 'failure') && !contains(needs.*.result, 'cancelled') && github.event_name == 'pull_request' }}\n run: |\n curl -H \"Content-Type: application/json\" \\\n -d '{\n \"embeds\": [{\n \"title\": \"❌ Build de PR échoué\",\n \"color\": 15158332,\n \"fields\": [\n {\"name\": \"Repo\", \"value\": \"${{ github.repository }}\", \"inline\": true},\n {\"name\": \"PR\", \"value\": \"[#${{ github.event.pull_request.number }}](${{ github.event.pull_request.html_url }})\", \"inline\": true},\n {\"name\": \"Commit\", \"value\": \"[`${{ github.sha }}`](${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }})\", \"inline\": false},\n {\"name\": \"Déclenché par\", \"value\": \"${{ github.actor }}\", \"inline\": true},\n {\"name\": \"Logs\", \"value\": \"[${{ github.run_id }}](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})\", \"inline\": false}\n ]\n }]\n }' \\\n ${{ secrets.DISCORD_WEBHOOK_URL }}\n"}, "dadff5541c6bd4de89ef6ee2a77dbccdbdd7fb86": {"t": 1785770073.198953, "n": 25010, "h": "fefcd2385886b2b3", "c": "name: 🚀 Build & Deploy\n\non:\n push:\n branches:\n - main\n - develop\n pull_request:\n branches:\n - main\n - develop\n\nenv:\n REGISTRY: ghcr.io\n\njobs:\n build-frontend:\n name: 🏗️ Build Frontend Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-frontend\n tags: |\n type=ref,event=branch\n type=ref,event=pr\n type=sha,prefix=sha-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/frontend\n file: ./packages/frontend/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: production\n cache-from: type=gha,scope=frontend\n cache-to: type=gha,scope=frontend,mode=max\n\n build-gateway:\n name: 🏗️ Build Gateway Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-gateway-service\n tags: |\n type=ref,event=branch\n type=ref,event=pr\n type=sha,prefix=sha-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/backend\n file: ./packages/backend/apps/gateway/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: runtime\n cache-from: type=gha,scope=gateway\n cache-to: type=gha,scope=gateway,mode=max\n\n build-authentication:\n name: 🏗️ Build Authentication Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-authentication-service\n tags: |\n type=ref,event=branch\n type=ref,event=pr\n type=sha,prefix=sha-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/backend\n file: ./packages/backend/apps/authentication/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: runtime\n cache-from: type=gha,scope=authentication\n cache-to: type=gha,scope=authentication,mode=max\n\n build-billing:\n name: 🏗️ Build Billing Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-billing-service\n tags: |\n type=ref,event=branch\n type=ref,event=pr\n type=sha,prefix=sha-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/backend\n file: ./packages/backend/apps/billing/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: runtime\n cache-from: type=gha,scope=billing\n cache-to: type=gha,scope=billing,mode=max\n\n build-stock:\n name: 🏗️ Build Stock Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-stock-service\n tags: |\n type=ref,event=branch\n type=ref,event=pr\n type=sha,prefix=sha-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/backend\n file: ./packages/backend/apps/stock/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: runtime\n cache-from: type=gha,scope=stock\n cache-to: type=gha,scope=stock,mode=max\n\n build-delivery:\n name: 🏗️ Build Delivery Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-delivery-service\n tags: |\n type=ref,event=branch\n type=ref,event=pr\n type=sha,prefix=sha-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/backend\n file: ./packages/backend/apps/delivery/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: runtime\n cache-from: type=gha,scope=delivery\n cache-to: type=gha,scope=delivery,mode=max\n\n build-users:\n name: 🏗️ Build Users Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-users-service\n tags: |\n type=ref,event=branch\n type=ref,event=pr\n type=sha,prefix=sha-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/backend\n file: ./packages/backend/apps/users/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: runtime\n cache-from: type=gha,scope=users\n cache-to: type=gha,scope=users,mode=max\n\n build-ai:\n name: 🏗️ Build & Test AI Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-ai-service\n tags: |\n type=ref,event=branch\n type=ref,event=pr\n type=sha,prefix=sha-\n type=raw,value=latest,enable={{is_default_branch}}\n\n # Build locally (load into the runner's Docker) so we can smoke-test\n # the container before pushing a potentially broken image.\n - name: 🏗️ Build AI image (load for test)\n uses: docker/build-push-action@v5\n with:\n context: ./packages/backend/apps/ai\n file: ./packages/backend/apps/ai/Dockerfile\n target: runtime\n load: true\n push: false\n tags: transvirex-ai-service:ci-test\n cache-from: type=gha,scope=ai\n cache-to: type=gha,scope=ai,mode=max\n\n - name: 🧪 Smoke-test AI container (/health)\n run: |\n docker run -d --name ai-test \\\n -e DEEPSEEK_API_KEY=ci-test-key \\\n -p 5000:5000 transvirex-ai-service:ci-test\n ok=0\n for i in $(seq 1 30); do\n if curl -fsS http://localhost:5000/health | grep -q '\"status\":\"ok\"'; then\n echo \"✅ AI service healthy\"; ok=1; break\n fi\n sleep 2\n done\n echo \"----- container logs -----\"\n docker logs ai-test || true\n docker rm -f ai-test\n if [ \"$ok\" != \"1\" ]; then\n echo \"❌ AI container failed its /health check\"; exit 1\n fi\n\n - name: 📤 Push AI image\n if: github.event_name != 'pull_request'\n uses: docker/build-push-action@v5\n with:\n context: ./packages/backend/apps/ai\n file: ./packages/backend/apps/ai/Dockerfile\n target: runtime\n push: true\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n cache-from: type=gha,scope=ai\n cache-to: type=gha,scope=ai,mode=max\n\n deploy:\n name: 🚀 Deploy to Production\n runs-on: ubuntu-latest\n needs:\n [\n build-frontend,\n build-gateway,\n build-authentication,\n build-billing,\n build-stock,\n build-delivery,\n build-users,\n build-ai,\n ]\n if: github.ref == 'refs/heads/main' && github.event_name == 'push'\n\n steps:\n - uses: actions/checkout@v4\n\n - uses: docker/login-action@v3\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n\n - name: 📋 Create production namespace & secrets\n uses: appleboy/ssh-action@v0.1.7\n env:\n GHCR_USERNAME: ${{ github.actor }}\n GHCR_TOKEN: ${{ secrets.GHCR_PAT }}\n JWT_SECRET: ${{ secrets.JWT_SECRET }}\n DEEPSEEK_API_KEY: ${{ secrets.DEEPSEEK_API_KEY }}\n with:\n host: ${{ secrets.VPS_HOST }}\n username: github-actions\n key: ${{ secrets.VPS_SSH_KEY }}\n port: 22\n envs: GHCR_USERNAME,GHCR_TOKEN,JWT_SECRET,DEEPSEEK_API_KEY\n script: |\n kubectl create namespace production --kubeconfig ~/.kube/config 2>/dev/null || true\n\n # ghcr-secret : apply idempotent (pas de delete/create)\n kubectl create secret docker-registry ghcr-secret \\\n --docker-server=ghcr.io \\\n --docker-username=$GHCR_USERNAME \\\n --docker-password=$GHCR_TOKEN \\\n -n production \\\n --kubeconfig ~/.kube/config \\\n --dry-run=client -o yaml | kubectl apply -f - --kubeconfig ~/.kube/config\n\n # Garde-fou : on refuse de déployer un secret vide, ce qui\n # écraserait silencieusement la clé valide (-> crash du service AI / 503).\n if [ -z \"$JWT_SECRET\" ] || [ -z \"$DEEPSEEK_API_KEY\" ]; then\n echo \"❌ JWT_SECRET ou DEEPSEEK_API_KEY vide — abandon pour ne pas écraser le secret existant\"\n exit 1\n fi\n\n # transvirex-secrets : apply idempotent (crée si absent, met à jour\n # sinon, sans fenêtre où le secret n'existe plus).\n kubectl create secret generic transvirex-secrets \\\n --from-literal=JWT_SECRET=\"$JWT_SECRET\" \\\n --from-literal=DEEPSEEK_API_KEY=\"$DEEPSEEK_API_KEY\" \\\n -n production \\\n --kubeconfig ~/.kube/config \\\n --dry-run=client -o yaml | kubectl apply -f - --kubeconfig ~/.kube/config\n\n rm -rf /tmp/k8s-manifests && mkdir -p /tmp/k8s-manifests\n\n - name: 🚀 Transfer K8s manifests\n uses: appleboy/scp-action@v0.1.4\n with:\n host: ${{ secrets.VPS_HOST }}\n username: github-actions\n key: ${{ secrets.VPS_SSH_KEY }}\n port: 22\n source: 'kubernetes/'\n target: '/tmp/k8s-manifests'\n overwrite: true\n\n - name: ⚡ Apply manifests & rollout\n uses: appleboy/ssh-action@v0.1.7\n with:\n host: ${{ secrets.VPS_HOST }}\n username: github-actions\n key: ${{ secrets.VPS_SSH_KEY }}\n port: 22\n command_timeout: 15m\n script: |\n kubectl apply -k /tmp/k8s-manifests/kubernetes --kubeconfig ~/.kube/config\n\n kubectl rollout restart deployment/transvirex-frontend -n production --kubeconfig ~/.kube/config\n kubectl rollout restart deployment/transvirex-gateway -n production --kubeconfig ~/.kube/config\n kubectl rollout restart deployment/transvirex-authentication -n production --kubeconfig ~/.kube/config\n kubectl rollout restart deployment/transvirex-billing -n production --kubeconfig ~/.kube/config\n kubectl rollout restart deployment/transvirex-stock -n production --kubeconfig ~/.kube/config\n kubectl rollout restart deployment/transvirex-delivery -n production --kubeconfig ~/.kube/config\n kubectl rollout restart deployment/transvirex-users -n production --kubeconfig ~/.kube/config\n kubectl rollout restart deployment/transvirex-ai -n production --kubeconfig ~/.kube/config\n\n kubectl rollout status deployment/transvirex-frontend -n production --timeout=10m --kubeconfig ~/.kube/config\n kubectl rollout status deployment/transvirex-gateway -n production --timeout=10m --kubeconfig ~/.kube/config\n kubectl rollout status deployment/transvirex-authentication -n production --timeout=10m --kubeconfig ~/.kube/config\n kubectl rollout status deployment/transvirex-billing -n production --timeout=10m --kubeconfig ~/.kube/config\n kubectl rollout status deployment/transvirex-stock -n production --timeout=10m --kubeconfig ~/.kube/config\n kubectl rollout status deployment/transvirex-delivery -n production --timeout=10m --kubeconfig ~/.kube/config\n kubectl rollout status deployment/transvirex-users -n production --timeout=10m --kubeconfig ~/.kube/config\n kubectl rollout status deployment/transvirex-ai -n production --timeout=10m --kubeconfig ~/.kube/config\n\n kubectl delete job transvirex-seed -n production --kubeconfig ~/.kube/config --ignore-not-found=true\n kubectl apply -f /tmp/k8s-manifests/kubernetes/jobs/seed.yaml --kubeconfig ~/.kube/config\n kubectl wait --for=condition=complete job/transvirex-seed -n production --timeout=2m --kubeconfig ~/.kube/config\n\n rm -rf /tmp/k8s-manifests\n\n notify:\n name: 📢 Notify\n runs-on: ubuntu-latest\n needs:\n [\n build-frontend,\n build-gateway,\n build-authentication,\n build-billing,\n build-stock,\n build-delivery,\n build-users,\n build-ai,\n deploy,\n ]\n if: always()\n\n steps:\n - name: ✅ Notify Discord - Success\n if: ${{ !contains(needs.*.result, 'failure') && !contains(needs.*.result, 'cancelled') }}\n run: |\n curl -H \"Content-Type: application/json\" \\\n -d '{\n \"embeds\": [{\n \"title\": \"✅ Déploiement réussi\",\n \"color\": 3066993,\n \"fields\": [\n {\"name\": \"Repo\", \"value\": \"${{ github.repository }}\", \"inline\": true},\n {\"name\": \"Branche\", \"value\": \"${{ github.ref_name }}\", \"inline\": true},\n {\"name\": \"Commit\", \"value\": \"[`${{ github.sha }}`](${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }})\", \"inline\": false},\n {\"name\": \"Déclenché par\", \"value\": \"${{ github.actor }}\", \"inline\": true}\n ]\n }]\n }' \\\n ${{ secrets.DISCORD_WEBHOOK_URL }}\n\n - name: ❌ Notify Discord - Failure\n if: ${{ contains(needs.*.result, 'failure') && !contains(needs.*.result, 'cancelled') && github.event_name != 'pull_request' }}\n run: |\n curl -H \"Content-Type: application/json\" \\\n -d '{\n \"embeds\": [{\n \"title\": \"❌ Déploiement échoué\",\n \"color\": 15158332,\n \"fields\": [\n {\"name\": \"Repo\", \"value\": \"${{ github.repository }}\", \"inline\": true},\n {\"name\": \"Branche\", \"value\": \"${{ github.ref_name }}\", \"inline\": true},\n {\"name\": \"Commit\", \"value\": \"[`${{ github.sha }}`](${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }})\", \"inline\": false},\n {\"name\": \"Déclenché par\", \"value\": \"${{ github.actor }}\", \"inline\": true},\n {\"name\": \"Logs\", \"value\": \"[${{ github.run_id }}](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})\", \"inline\": false}\n ]\n }]\n }' \\\n ${{ secrets.DISCORD_WEBHOOK_URL }}\n\n - name: ⚠️ Notify Discord - Cancelled\n if: ${{ contains(needs.*.result, 'cancelled') && github.event_name != 'pull_request' }}\n run: |\n curl -H \"Content-Type: application/json\" \\\n -d '{\n \"embeds\": [{\n \"title\": \"⚠️ Déploiement annulé\",\n \"color\": 16776960,\n \"fields\": [\n {\"name\": \"Repo\", \"value\": \"${{ github.repository }}\", \"inline\": true},\n {\"name\": \"Branche\", \"value\": \"${{ github.ref_name }}\", \"inline\": true},\n {\"name\": \"Commit\", \"value\": \"[`${{ github.sha }}`](${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }})\", \"inline\": false},\n {\"name\": \"Déclenché par\", \"value\": \"${{ github.actor }}\", \"inline\": true},\n {\"name\": \"Logs\", \"value\": \"[${{ github.run_id }}](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})\", \"inline\": false}\n ]\n }]\n }' \\\n ${{ secrets.DISCORD_WEBHOOK_URL }}\n\n - name: ⚠️ Notify Discord - PR Build failure\n if: ${{ contains(needs.*.result, 'failure') && !contains(needs.*.result, 'cancelled') && github.event_name == 'pull_request' }}\n run: |\n curl -H \"Content-Type: application/json\" \\\n -d '{\n \"embeds\": [{\n \"title\": \"❌ Build de PR échoué\",\n \"color\": 15158332,\n \"fields\": [\n {\"name\": \"Repo\", \"value\": \"${{ github.repository }}\", \"inline\": true},\n {\"name\": \"PR\", \"value\": \"[#${{ github.event.pull_request.number }}](${{ github.event.pull_request.html_url }})\", \"inline\": true},\n {\"name\": \"Commit\", \"value\": \"[`${{ github.sha }}`](${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }})\", \"inline\": false},\n {\"name\": \"Déclenché par\", \"value\": \"${{ github.actor }}\", \"inline\": true},\n {\"name\": \"Logs\", \"value\": \"[${{ github.run_id }}](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})\", \"inline\": false}\n ]\n }]\n }' \\\n ${{ secrets.DISCORD_WEBHOOK_URL }}\n"}, "763d50be2b756addf55830fc04a5080fbb1552af": {"t": 1785770074.7809148, "n": 24370, "h": "b44437677eb53af2", "c": "name: 🚀 Build & Deploy\n\non:\n push:\n branches:\n - main\n - develop\n pull_request:\n branches:\n - main\n - develop\n\nenv:\n REGISTRY: ghcr.io\n\njobs:\n build-frontend:\n name: 🏗️ Build Frontend Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-frontend\n tags: |\n type=ref,event=branch\n type=ref,event=pr\n type=sha,prefix=sha-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/frontend\n file: ./packages/frontend/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: production\n cache-from: type=gha,scope=frontend\n cache-to: type=gha,scope=frontend,mode=max\n\n build-gateway:\n name: 🏗️ Build Gateway Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-gateway-service\n tags: |\n type=ref,event=branch\n type=ref,event=pr\n type=sha,prefix=sha-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/backend\n file: ./packages/backend/apps/gateway/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: runtime\n cache-from: type=gha,scope=gateway\n cache-to: type=gha,scope=gateway,mode=max\n\n build-authentication:\n name: 🏗️ Build Authentication Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-authentication-service\n tags: |\n type=ref,event=branch\n type=ref,event=pr\n type=sha,prefix=sha-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/backend\n file: ./packages/backend/apps/authentication/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: runtime\n cache-from: type=gha,scope=authentication\n cache-to: type=gha,scope=authentication,mode=max\n\n build-billing:\n name: 🏗️ Build Billing Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-billing-service\n tags: |\n type=ref,event=branch\n type=ref,event=pr\n type=sha,prefix=sha-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/backend\n file: ./packages/backend/apps/billing/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: runtime\n cache-from: type=gha,scope=billing\n cache-to: type=gha,scope=billing,mode=max\n\n build-stock:\n name: 🏗️ Build Stock Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-stock-service\n tags: |\n type=ref,event=branch\n type=ref,event=pr\n type=sha,prefix=sha-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/backend\n file: ./packages/backend/apps/stock/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: runtime\n cache-from: type=gha,scope=stock\n cache-to: type=gha,scope=stock,mode=max\n\n build-delivery:\n name: 🏗️ Build Delivery Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-delivery-service\n tags: |\n type=ref,event=branch\n type=ref,event=pr\n type=sha,prefix=sha-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/backend\n file: ./packages/backend/apps/delivery/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: runtime\n cache-from: type=gha,scope=delivery\n cache-to: type=gha,scope=delivery,mode=max\n\n build-users:\n name: 🏗️ Build Users Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-users-service\n tags: |\n type=ref,event=branch\n type=ref,event=pr\n type=sha,prefix=sha-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/backend\n file: ./packages/backend/apps/users/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: runtime\n cache-from: type=gha,scope=users\n cache-to: type=gha,scope=users,mode=max\n\n build-ai:\n name: 🏗️ Build & Test AI Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-ai-service\n tags: |\n type=ref,event=branch\n type=ref,event=pr\n type=sha,prefix=sha-\n type=raw,value=latest,enable={{is_default_branch}}\n\n # Build locally (load into the runner's Docker) so we can smoke-test\n # the container before pushing a potentially broken image.\n - name: 🏗️ Build AI image (load for test)\n uses: docker/build-push-action@v5\n with:\n context: ./packages/backend/apps/ai\n file: ./packages/backend/apps/ai/Dockerfile\n target: runtime\n load: true\n push: false\n tags: transvirex-ai-service:ci-test\n cache-from: type=gha,scope=ai\n cache-to: type=gha,scope=ai,mode=max\n\n - name: 🧪 Smoke-test AI container (/health)\n run: |\n docker run -d --name ai-test \\\n -e DEEPSEEK_API_KEY=ci-test-key \\\n -p 5000:5000 transvirex-ai-service:ci-test\n ok=0\n for i in $(seq 1 30); do\n if curl -fsS http://localhost:5000/health | grep -q '\"status\":\"ok\"'; then\n echo \"✅ AI service healthy\"; ok=1; break\n fi\n sleep 2\n done\n echo \"----- container logs -----\"\n docker logs ai-test || true\n docker rm -f ai-test\n if [ \"$ok\" != \"1\" ]; then\n echo \"❌ AI container failed its /health check\"; exit 1\n fi\n\n - name: 📤 Push AI image\n if: github.event_name != 'pull_request'\n uses: docker/build-push-action@v5\n with:\n context: ./packages/backend/apps/ai\n file: ./packages/backend/apps/ai/Dockerfile\n target: runtime\n push: true\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n cache-from: type=gha,scope=ai\n cache-to: type=gha,scope=ai,mode=max\n\n deploy:\n name: 🚀 Deploy to Production\n runs-on: ubuntu-latest\n needs:\n [\n build-frontend,\n build-gateway,\n build-authentication,\n build-billing,\n build-stock,\n build-delivery,\n build-users,\n build-ai,\n ]\n if: github.ref == 'refs/heads/main' && github.event_name == 'push'\n\n steps:\n - uses: actions/checkout@v4\n\n - uses: docker/login-action@v3\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n\n - name: 📋 Create production namespace & secrets\n uses: appleboy/ssh-action@v0.1.7\n env:\n GHCR_USERNAME: ${{ github.actor }}\n GHCR_TOKEN: ${{ secrets.GHCR_PAT }}\n JWT_SECRET: ${{ secrets.JWT_SECRET }}\n DEEPSEEK_API_KEY: ${{ secrets.DEEPSEEK_API_KEY }}\n with:\n host: ${{ secrets.VPS_HOST }}\n username: github-actions\n key: ${{ secrets.VPS_SSH_KEY }}\n port: 22\n envs: GHCR_USERNAME,GHCR_TOKEN,JWT_SECRET,DEEPSEEK_API_KEY\n script: |\n kubectl create namespace production --kubeconfig ~/.kube/config 2>/dev/null || true\n kubectl delete secret ghcr-secret -n production --kubeconfig ~/.kube/config 2>/dev/null || true\n kubectl create secret docker-registry ghcr-secret \\\n --docker-server=ghcr.io \\\n --docker-username=$GHCR_USERNAME \\\n --docker-password=$GHCR_TOKEN \\\n -n production \\\n --kubeconfig ~/.kube/config\n kubectl delete secret transvirex-secrets -n production --kubeconfig ~/.kube/config 2>/dev/null || true\n kubectl create secret generic transvirex-secrets \\\n --from-literal=JWT_SECRET=$JWT_SECRET \\\n --from-literal=DEEPSEEK_API_KEY=$DEEPSEEK_API_KEY \\\n -n production \\\n --kubeconfig ~/.kube/config\n rm -rf /tmp/k8s-manifests && mkdir -p /tmp/k8s-manifests\n\n - name: 🚀 Transfer K8s manifests\n uses: appleboy/scp-action@v0.1.4\n with:\n host: ${{ secrets.VPS_HOST }}\n username: github-actions\n key: ${{ secrets.VPS_SSH_KEY }}\n port: 22\n source: 'kubernetes/'\n target: '/tmp/k8s-manifests'\n overwrite: true\n\n - name: ⚡ Apply manifests & rollout\n uses: appleboy/ssh-action@v0.1.7\n with:\n host: ${{ secrets.VPS_HOST }}\n username: github-actions\n key: ${{ secrets.VPS_SSH_KEY }}\n port: 22\n command_timeout: 15m\n script: |\n kubectl apply -k /tmp/k8s-manifests/kubernetes --kubeconfig ~/.kube/config\n\n kubectl rollout restart deployment/transvirex-frontend -n production --kubeconfig ~/.kube/config\n kubectl rollout restart deployment/transvirex-gateway -n production --kubeconfig ~/.kube/config\n kubectl rollout restart deployment/transvirex-authentication -n production --kubeconfig ~/.kube/config\n kubectl rollout restart deployment/transvirex-billing -n production --kubeconfig ~/.kube/config\n kubectl rollout restart deployment/transvirex-stock -n production --kubeconfig ~/.kube/config\n kubectl rollout restart deployment/transvirex-delivery -n production --kubeconfig ~/.kube/config\n kubectl rollout restart deployment/transvirex-users -n production --kubeconfig ~/.kube/config\n kubectl rollout restart deployment/transvirex-ai -n production --kubeconfig ~/.kube/config\n\n kubectl rollout status deployment/transvirex-frontend -n production --timeout=10m --kubeconfig ~/.kube/config\n kubectl rollout status deployment/transvirex-gateway -n production --timeout=10m --kubeconfig ~/.kube/config\n kubectl rollout status deployment/transvirex-authentication -n production --timeout=10m --kubeconfig ~/.kube/config\n kubectl rollout status deployment/transvirex-billing -n production --timeout=10m --kubeconfig ~/.kube/config\n kubectl rollout status deployment/transvirex-stock -n production --timeout=10m --kubeconfig ~/.kube/config\n kubectl rollout status deployment/transvirex-delivery -n production --timeout=10m --kubeconfig ~/.kube/config\n kubectl rollout status deployment/transvirex-users -n production --timeout=10m --kubeconfig ~/.kube/config\n kubectl rollout status deployment/transvirex-ai -n production --timeout=10m --kubeconfig ~/.kube/config\n\n kubectl delete job transvirex-seed -n production --kubeconfig ~/.kube/config --ignore-not-found=true\n kubectl apply -f /tmp/k8s-manifests/kubernetes/jobs/seed.yaml --kubeconfig ~/.kube/config\n kubectl wait --for=condition=complete job/transvirex-seed -n production --timeout=2m --kubeconfig ~/.kube/config\n\n rm -rf /tmp/k8s-manifests\n\n notify:\n name: 📢 Notify\n runs-on: ubuntu-latest\n needs:\n [\n build-frontend,\n build-gateway,\n build-authentication,\n build-billing,\n build-stock,\n build-delivery,\n build-users,\n build-ai,\n deploy,\n ]\n if: always()\n\n steps:\n - name: ✅ Notify Discord - Success\n if: ${{ !contains(needs.*.result, 'failure') && !contains(needs.*.result, 'cancelled') }}\n run: |\n curl -H \"Content-Type: application/json\" \\\n -d '{\n \"embeds\": [{\n \"title\": \"✅ Déploiement réussi\",\n \"color\": 3066993,\n \"fields\": [\n {\"name\": \"Repo\", \"value\": \"${{ github.repository }}\", \"inline\": true},\n {\"name\": \"Branche\", \"value\": \"${{ github.ref_name }}\", \"inline\": true},\n {\"name\": \"Commit\", \"value\": \"[`${{ github.sha }}`](${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }})\", \"inline\": false},\n {\"name\": \"Déclenché par\", \"value\": \"${{ github.actor }}\", \"inline\": true}\n ]\n }]\n }' \\\n ${{ secrets.DISCORD_WEBHOOK_URL }}\n\n - name: ❌ Notify Discord - Failure\n if: ${{ contains(needs.*.result, 'failure') && !contains(needs.*.result, 'cancelled') && github.event_name != 'pull_request' }}\n run: |\n curl -H \"Content-Type: application/json\" \\\n -d '{\n \"embeds\": [{\n \"title\": \"❌ Déploiement échoué\",\n \"color\": 15158332,\n \"fields\": [\n {\"name\": \"Repo\", \"value\": \"${{ github.repository }}\", \"inline\": true},\n {\"name\": \"Branche\", \"value\": \"${{ github.ref_name }}\", \"inline\": true},\n {\"name\": \"Commit\", \"value\": \"[`${{ github.sha }}`](${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }})\", \"inline\": false},\n {\"name\": \"Déclenché par\", \"value\": \"${{ github.actor }}\", \"inline\": true},\n {\"name\": \"Logs\", \"value\": \"[${{ github.run_id }}](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})\", \"inline\": false}\n ]\n }]\n }' \\\n ${{ secrets.DISCORD_WEBHOOK_URL }}\n\n - name: ⚠️ Notify Discord - Cancelled\n if: ${{ contains(needs.*.result, 'cancelled') && github.event_name != 'pull_request' }}\n run: |\n curl -H \"Content-Type: application/json\" \\\n -d '{\n \"embeds\": [{\n \"title\": \"⚠️ Déploiement annulé\",\n \"color\": 16776960,\n \"fields\": [\n {\"name\": \"Repo\", \"value\": \"${{ github.repository }}\", \"inline\": true},\n {\"name\": \"Branche\", \"value\": \"${{ github.ref_name }}\", \"inline\": true},\n {\"name\": \"Commit\", \"value\": \"[`${{ github.sha }}`](${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }})\", \"inline\": false},\n {\"name\": \"Déclenché par\", \"value\": \"${{ github.actor }}\", \"inline\": true},\n {\"name\": \"Logs\", \"value\": \"[${{ github.run_id }}](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})\", \"inline\": false}\n ]\n }]\n }' \\\n ${{ secrets.DISCORD_WEBHOOK_URL }}\n\n - name: ⚠️ Notify Discord - PR Build failure\n if: ${{ contains(needs.*.result, 'failure') && !contains(needs.*.result, 'cancelled') && github.event_name == 'pull_request' }}\n run: |\n curl -H \"Content-Type: application/json\" \\\n -d '{\n \"embeds\": [{\n \"title\": \"❌ Build de PR échoué\",\n \"color\": 15158332,\n \"fields\": [\n {\"name\": \"Repo\", \"value\": \"${{ github.repository }}\", \"inline\": true},\n {\"name\": \"PR\", \"value\": \"[#${{ github.event.pull_request.number }}](${{ github.event.pull_request.html_url }})\", \"inline\": true},\n {\"name\": \"Commit\", \"value\": \"[`${{ github.sha }}`](${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }})\", \"inline\": false},\n {\"name\": \"Déclenché par\", \"value\": \"${{ github.actor }}\", \"inline\": true},\n {\"name\": \"Logs\", \"value\": \"[${{ github.run_id }}](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})\", \"inline\": false}\n ]\n }]\n }' \\\n ${{ secrets.DISCORD_WEBHOOK_URL }}\n"}, "291637efe0b42dd5e18d01705781b40e493fe17f": {"t": 1785770078.0384874, "n": 20955, "h": "db47eea0d5868f6f", "c": "name: 🚀 Build & Deploy\n\non:\n push:\n branches:\n - main\n - develop\n pull_request:\n branches:\n - main\n - develop\n\nenv:\n REGISTRY: ghcr.io\n\njobs:\n build-frontend:\n name: 🏗️ Build Frontend Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-frontend\n tags: |\n type=ref,event=branch\n type=ref,event=pr\n type=sha,prefix=sha-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/frontend\n file: ./packages/frontend/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: production\n cache-from: type=gha,scope=frontend\n cache-to: type=gha,scope=frontend,mode=max\n\n build-gateway:\n name: 🏗️ Build Gateway Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-gateway-service\n tags: |\n type=ref,event=branch\n type=ref,event=pr\n type=sha,prefix=sha-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/backend\n file: ./packages/backend/apps/gateway/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: runtime\n cache-from: type=gha,scope=gateway\n cache-to: type=gha,scope=gateway,mode=max\n\n build-authentication:\n name: 🏗️ Build Authentication Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-authentication-service\n tags: |\n type=ref,event=branch\n type=ref,event=pr\n type=sha,prefix=sha-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/backend\n file: ./packages/backend/apps/authentication/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: runtime\n cache-from: type=gha,scope=authentication\n cache-to: type=gha,scope=authentication,mode=max\n\n build-billing:\n name: 🏗️ Build Billing Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-billing-service\n tags: |\n type=ref,event=branch\n type=ref,event=pr\n type=sha,prefix=sha-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/backend\n file: ./packages/backend/apps/billing/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: runtime\n cache-from: type=gha,scope=billing\n cache-to: type=gha,scope=billing,mode=max\n\n build-stock:\n name: 🏗️ Build Stock Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-stock-service\n tags: |\n type=ref,event=branch\n type=ref,event=pr\n type=sha,prefix=sha-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/backend\n file: ./packages/backend/apps/stock/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: runtime\n cache-from: type=gha,scope=stock\n cache-to: type=gha,scope=stock,mode=max\n\n build-delivery:\n name: 🏗️ Build Delivery Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-delivery-service\n tags: |\n type=ref,event=branch\n type=ref,event=pr\n type=sha,prefix=sha-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/backend\n file: ./packages/backend/apps/delivery/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: runtime\n cache-from: type=gha,scope=delivery\n cache-to: type=gha,scope=delivery,mode=max\n\n build-users:\n name: 🏗️ Build Users Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-users-service\n tags: |\n type=ref,event=branch\n type=ref,event=pr\n type=sha,prefix=sha-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/backend\n file: ./packages/backend/apps/users/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: runtime\n cache-from: type=gha,scope=users\n cache-to: type=gha,scope=users,mode=max\n\n deploy:\n name: 🚀 Deploy to Production\n runs-on: ubuntu-latest\n needs:\n [\n build-frontend,\n build-gateway,\n build-authentication,\n build-billing,\n build-stock,\n build-delivery,\n build-users,\n ]\n if: github.ref == 'refs/heads/main' && github.event_name == 'push'\n\n steps:\n - uses: actions/checkout@v4\n\n - uses: docker/login-action@v3\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n\n - name: 📋 Create production namespace & secrets\n uses: appleboy/ssh-action@v0.1.7\n env:\n GHCR_USERNAME: ${{ github.actor }}\n GHCR_TOKEN: ${{ secrets.GHCR_PAT }}\n JWT_SECRET: ${{ secrets.JWT_SECRET }}\n with:\n host: ${{ secrets.VPS_HOST }}\n username: github-actions\n key: ${{ secrets.VPS_SSH_KEY }}\n port: 22\n envs: GHCR_USERNAME,GHCR_TOKEN,JWT_SECRET\n script: |\n kubectl create namespace production --kubeconfig ~/.kube/config 2>/dev/null || true\n kubectl delete secret ghcr-secret -n production --kubeconfig ~/.kube/config 2>/dev/null || true\n kubectl create secret docker-registry ghcr-secret \\\n --docker-server=ghcr.io \\\n --docker-username=$GHCR_USERNAME \\\n --docker-password=$GHCR_TOKEN \\\n -n production \\\n --kubeconfig ~/.kube/config\n kubectl delete secret transvirex-secrets -n production --kubeconfig ~/.kube/config 2>/dev/null || true\n kubectl create secret generic transvirex-secrets \\\n --from-literal=JWT_SECRET=$JWT_SECRET \\\n -n production \\\n --kubeconfig ~/.kube/config\n rm -rf /tmp/k8s-manifests && mkdir -p /tmp/k8s-manifests\n\n - name: 🚀 Transfer K8s manifests\n uses: appleboy/scp-action@v0.1.4\n with:\n host: ${{ secrets.VPS_HOST }}\n username: github-actions\n key: ${{ secrets.VPS_SSH_KEY }}\n port: 22\n source: 'kubernetes/'\n target: '/tmp/k8s-manifests'\n overwrite: true\n\n - name: ⚡ Apply manifests & rollout\n uses: appleboy/ssh-action@v0.1.7\n with:\n host: ${{ secrets.VPS_HOST }}\n username: github-actions\n key: ${{ secrets.VPS_SSH_KEY }}\n port: 22\n command_timeout: 15m\n script: |\n kubectl apply -k /tmp/k8s-manifests/kubernetes --kubeconfig ~/.kube/config\n\n kubectl rollout restart deployment/transvirex-frontend -n production --kubeconfig ~/.kube/config\n kubectl rollout restart deployment/transvirex-gateway -n production --kubeconfig ~/.kube/config\n kubectl rollout restart deployment/transvirex-authentication -n production --kubeconfig ~/.kube/config\n kubectl rollout restart deployment/transvirex-billing -n production --kubeconfig ~/.kube/config\n kubectl rollout restart deployment/transvirex-stock -n production --kubeconfig ~/.kube/config\n kubectl rollout restart deployment/transvirex-delivery -n production --kubeconfig ~/.kube/config\n kubectl rollout restart deployment/transvirex-users -n production --kubeconfig ~/.kube/config\n\n kubectl rollout status deployment/transvirex-frontend -n production --timeout=10m --kubeconfig ~/.kube/config\n kubectl rollout status deployment/transvirex-gateway -n production --timeout=10m --kubeconfig ~/.kube/config\n kubectl rollout status deployment/transvirex-authentication -n production --timeout=10m --kubeconfig ~/.kube/config\n kubectl rollout status deployment/transvirex-billing -n production --timeout=10m --kubeconfig ~/.kube/config\n kubectl rollout status deployment/transvirex-stock -n production --timeout=10m --kubeconfig ~/.kube/config\n kubectl rollout status deployment/transvirex-delivery -n production --timeout=10m --kubeconfig ~/.kube/config\n kubectl rollout status deployment/transvirex-users -n production --timeout=10m --kubeconfig ~/.kube/config\n\n kubectl delete job transvirex-seed -n production --kubeconfig ~/.kube/config --ignore-not-found=true\n kubectl apply -f /tmp/k8s-manifests/kubernetes/jobs/seed.yaml --kubeconfig ~/.kube/config\n kubectl wait --for=condition=complete job/transvirex-seed -n production --timeout=2m --kubeconfig ~/.kube/config\n\n rm -rf /tmp/k8s-manifests\n\n notify:\n name: 📢 Notify\n runs-on: ubuntu-latest\n needs:\n [\n build-frontend,\n build-gateway,\n build-authentication,\n build-billing,\n build-stock,\n build-delivery,\n build-users,\n deploy,\n ]\n if: always()\n\n steps:\n - name: ✅ Notify Discord - Success\n if: ${{ !contains(needs.*.result, 'failure') && !contains(needs.*.result, 'cancelled') }}\n run: |\n curl -H \"Content-Type: application/json\" \\\n -d '{\n \"embeds\": [{\n \"title\": \"✅ Déploiement réussi\",\n \"color\": 3066993,\n \"fields\": [\n {\"name\": \"Repo\", \"value\": \"${{ github.repository }}\", \"inline\": true},\n {\"name\": \"Branche\", \"value\": \"${{ github.ref_name }}\", \"inline\": true},\n {\"name\": \"Commit\", \"value\": \"[`${{ github.sha }}`](${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }})\", \"inline\": false},\n {\"name\": \"Déclenché par\", \"value\": \"${{ github.actor }}\", \"inline\": true}\n ]\n }]\n }' \\\n ${{ secrets.DISCORD_WEBHOOK_URL }}\n\n - name: ❌ Notify Discord - Failure\n if: ${{ contains(needs.*.result, 'failure') && !contains(needs.*.result, 'cancelled') && github.event_name != 'pull_request' }}\n run: |\n curl -H \"Content-Type: application/json\" \\\n -d '{\n \"embeds\": [{\n \"title\": \"❌ Déploiement échoué\",\n \"color\": 15158332,\n \"fields\": [\n {\"name\": \"Repo\", \"value\": \"${{ github.repository }}\", \"inline\": true},\n {\"name\": \"Branche\", \"value\": \"${{ github.ref_name }}\", \"inline\": true},\n {\"name\": \"Commit\", \"value\": \"[`${{ github.sha }}`](${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }})\", \"inline\": false},\n {\"name\": \"Déclenché par\", \"value\": \"${{ github.actor }}\", \"inline\": true},\n {\"name\": \"Logs\", \"value\": \"[${{ github.run_id }}](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})\", \"inline\": false}\n ]\n }]\n }' \\\n ${{ secrets.DISCORD_WEBHOOK_URL }}\n\n - name: ⚠️ Notify Discord - Cancelled\n if: ${{ contains(needs.*.result, 'cancelled') && github.event_name != 'pull_request' }}\n run: |\n curl -H \"Content-Type: application/json\" \\\n -d '{\n \"embeds\": [{\n \"title\": \"⚠️ Déploiement annulé\",\n \"color\": 16776960,\n \"fields\": [\n {\"name\": \"Repo\", \"value\": \"${{ github.repository }}\", \"inline\": true},\n {\"name\": \"Branche\", \"value\": \"${{ github.ref_name }}\", \"inline\": true},\n {\"name\": \"Commit\", \"value\": \"[`${{ github.sha }}`](${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }})\", \"inline\": false},\n {\"name\": \"Déclenché par\", \"value\": \"${{ github.actor }}\", \"inline\": true},\n {\"name\": \"Logs\", \"value\": \"[${{ github.run_id }}](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})\", \"inline\": false}\n ]\n }]\n }' \\\n ${{ secrets.DISCORD_WEBHOOK_URL }}\n\n - name: ⚠️ Notify Discord - PR Build failure\n if: ${{ contains(needs.*.result, 'failure') && !contains(needs.*.result, 'cancelled') && github.event_name == 'pull_request' }}\n run: |\n curl -H \"Content-Type: application/json\" \\\n -d '{\n \"embeds\": [{\n \"title\": \"❌ Build de PR échoué\",\n \"color\": 15158332,\n \"fields\": [\n {\"name\": \"Repo\", \"value\": \"${{ github.repository }}\", \"inline\": true},\n {\"name\": \"PR\", \"value\": \"[#${{ github.event.pull_request.number }}](${{ github.event.pull_request.html_url }})\", \"inline\": true},\n {\"name\": \"Commit\", \"value\": \"[`${{ github.sha }}`](${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }})\", \"inline\": false},\n {\"name\": \"Déclenché par\", \"value\": \"${{ github.actor }}\", \"inline\": true},\n {\"name\": \"Logs\", \"value\": \"[${{ github.run_id }}](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})\", \"inline\": false}\n ]\n }]\n }' \\\n ${{ secrets.DISCORD_WEBHOOK_URL }}\n"}, "c1fafdda6555721568fa9c971e52f812013da236": {"t": 1785770079.322891, "n": 20542, "h": "fe9aeb7396a9ee94", "c": "name: 🚀 Build & Deploy\n\non:\n push:\n branches:\n - main\n - develop\n pull_request:\n branches:\n - main\n - develop\n\nenv:\n REGISTRY: ghcr.io\n\njobs:\n build-frontend:\n name: 🏗️ Build Frontend Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-frontend\n tags: |\n type=ref,event=branch\n type=ref,event=pr\n type=sha,prefix=sha-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/frontend\n file: ./packages/frontend/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: production\n cache-from: type=gha,scope=frontend\n cache-to: type=gha,scope=frontend,mode=max\n\n build-gateway:\n name: 🏗️ Build Gateway Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-gateway-service\n tags: |\n type=ref,event=branch\n type=ref,event=pr\n type=sha,prefix=sha-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/backend\n file: ./packages/backend/apps/gateway/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: runtime\n cache-from: type=gha,scope=gateway\n cache-to: type=gha,scope=gateway,mode=max\n\n build-authentication:\n name: 🏗️ Build Authentication Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-authentication-service\n tags: |\n type=ref,event=branch\n type=ref,event=pr\n type=sha,prefix=sha-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/backend\n file: ./packages/backend/apps/authentication/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: runtime\n cache-from: type=gha,scope=authentication\n cache-to: type=gha,scope=authentication,mode=max\n\n build-billing:\n name: 🏗️ Build Billing Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-billing-service\n tags: |\n type=ref,event=branch\n type=ref,event=pr\n type=sha,prefix=sha-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/backend\n file: ./packages/backend/apps/billing/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: runtime\n cache-from: type=gha,scope=billing\n cache-to: type=gha,scope=billing,mode=max\n\n build-stock:\n name: 🏗️ Build Stock Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-stock-service\n tags: |\n type=ref,event=branch\n type=ref,event=pr\n type=sha,prefix=sha-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/backend\n file: ./packages/backend/apps/stock/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: runtime\n cache-from: type=gha,scope=stock\n cache-to: type=gha,scope=stock,mode=max\n\n build-delivery:\n name: 🏗️ Build Delivery Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-delivery-service\n tags: |\n type=ref,event=branch\n type=ref,event=pr\n type=sha,prefix=sha-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/backend\n file: ./packages/backend/apps/delivery/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: runtime\n cache-from: type=gha,scope=delivery\n cache-to: type=gha,scope=delivery,mode=max\n\n build-users:\n name: 🏗️ Build Users Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-users-service\n tags: |\n type=ref,event=branch\n type=ref,event=pr\n type=sha,prefix=sha-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/backend\n file: ./packages/backend/apps/users/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: runtime\n cache-from: type=gha,scope=users\n cache-to: type=gha,scope=users,mode=max\n\n deploy:\n name: 🚀 Deploy to Production\n runs-on: ubuntu-latest\n needs:\n [\n build-frontend,\n build-gateway,\n build-authentication,\n build-billing,\n build-stock,\n build-delivery,\n build-users,\n ]\n if: github.ref == 'refs/heads/main' && github.event_name == 'push'\n\n steps:\n - uses: actions/checkout@v4\n\n - uses: docker/login-action@v3\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n\n - name: 📋 Create production namespace & registry secret\n uses: appleboy/ssh-action@v0.1.7\n env:\n GHCR_USERNAME: ${{ github.actor }}\n GHCR_TOKEN: ${{ secrets.GHCR_PAT }}\n with:\n host: ${{ secrets.VPS_HOST }}\n username: github-actions\n key: ${{ secrets.VPS_SSH_KEY }}\n port: 22\n envs: GHCR_USERNAME,GHCR_TOKEN\n script: |\n kubectl create namespace production --kubeconfig ~/.kube/config 2>/dev/null || true\n kubectl delete secret ghcr-secret -n production --kubeconfig ~/.kube/config 2>/dev/null || true\n kubectl create secret docker-registry ghcr-secret \\\n --docker-server=ghcr.io \\\n --docker-username=$GHCR_USERNAME \\\n --docker-password=$GHCR_TOKEN \\\n -n production \\\n --kubeconfig ~/.kube/config\n rm -rf /tmp/k8s-manifests && mkdir -p /tmp/k8s-manifests\n\n - name: 🚀 Transfer K8s manifests\n uses: appleboy/scp-action@v0.1.4\n with:\n host: ${{ secrets.VPS_HOST }}\n username: github-actions\n key: ${{ secrets.VPS_SSH_KEY }}\n port: 22\n source: 'kubernetes/'\n target: '/tmp/k8s-manifests'\n overwrite: true\n\n - name: ⚡ Apply manifests & rollout\n uses: appleboy/ssh-action@v0.1.7\n with:\n host: ${{ secrets.VPS_HOST }}\n username: github-actions\n key: ${{ secrets.VPS_SSH_KEY }}\n port: 22\n command_timeout: 15m\n script: |\n kubectl apply -k /tmp/k8s-manifests/kubernetes --kubeconfig ~/.kube/config\n\n kubectl rollout restart deployment/transvirex-frontend -n production --kubeconfig ~/.kube/config\n kubectl rollout restart deployment/transvirex-gateway -n production --kubeconfig ~/.kube/config\n kubectl rollout restart deployment/transvirex-authentication -n production --kubeconfig ~/.kube/config\n kubectl rollout restart deployment/transvirex-billing -n production --kubeconfig ~/.kube/config\n kubectl rollout restart deployment/transvirex-stock -n production --kubeconfig ~/.kube/config\n kubectl rollout restart deployment/transvirex-delivery -n production --kubeconfig ~/.kube/config\n kubectl rollout restart deployment/transvirex-users -n production --kubeconfig ~/.kube/config\n\n kubectl rollout status deployment/transvirex-frontend -n production --timeout=10m --kubeconfig ~/.kube/config\n kubectl rollout status deployment/transvirex-gateway -n production --timeout=10m --kubeconfig ~/.kube/config\n kubectl rollout status deployment/transvirex-authentication -n production --timeout=10m --kubeconfig ~/.kube/config\n kubectl rollout status deployment/transvirex-billing -n production --timeout=10m --kubeconfig ~/.kube/config\n kubectl rollout status deployment/transvirex-stock -n production --timeout=10m --kubeconfig ~/.kube/config\n kubectl rollout status deployment/transvirex-delivery -n production --timeout=10m --kubeconfig ~/.kube/config\n kubectl rollout status deployment/transvirex-users -n production --timeout=10m --kubeconfig ~/.kube/config\n\n kubectl delete job transvirex-seed -n production --kubeconfig ~/.kube/config --ignore-not-found=true\n kubectl apply -f /tmp/k8s-manifests/kubernetes/jobs/seed.yaml --kubeconfig ~/.kube/config\n kubectl wait --for=condition=complete job/transvirex-seed -n production --timeout=2m --kubeconfig ~/.kube/config\n\n rm -rf /tmp/k8s-manifests\n\n notify:\n name: 📢 Notify\n runs-on: ubuntu-latest\n needs:\n [\n build-frontend,\n build-gateway,\n build-authentication,\n build-billing,\n build-stock,\n build-delivery,\n build-users,\n deploy,\n ]\n if: always()\n\n steps:\n - name: ✅ Notify Discord - Success\n if: ${{ !contains(needs.*.result, 'failure') && !contains(needs.*.result, 'cancelled') }}\n run: |\n curl -H \"Content-Type: application/json\" \\\n -d '{\n \"embeds\": [{\n \"title\": \"✅ Déploiement réussi\",\n \"color\": 3066993,\n \"fields\": [\n {\"name\": \"Repo\", \"value\": \"${{ github.repository }}\", \"inline\": true},\n {\"name\": \"Branche\", \"value\": \"${{ github.ref_name }}\", \"inline\": true},\n {\"name\": \"Commit\", \"value\": \"[`${{ github.sha }}`](${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }})\", \"inline\": false},\n {\"name\": \"Déclenché par\", \"value\": \"${{ github.actor }}\", \"inline\": true}\n ]\n }]\n }' \\\n ${{ secrets.DISCORD_WEBHOOK_URL }}\n\n - name: ❌ Notify Discord - Failure\n if: ${{ contains(needs.*.result, 'failure') && !contains(needs.*.result, 'cancelled') && github.event_name != 'pull_request' }}\n run: |\n curl -H \"Content-Type: application/json\" \\\n -d '{\n \"embeds\": [{\n \"title\": \"❌ Déploiement échoué\",\n \"color\": 15158332,\n \"fields\": [\n {\"name\": \"Repo\", \"value\": \"${{ github.repository }}\", \"inline\": true},\n {\"name\": \"Branche\", \"value\": \"${{ github.ref_name }}\", \"inline\": true},\n {\"name\": \"Commit\", \"value\": \"[`${{ github.sha }}`](${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }})\", \"inline\": false},\n {\"name\": \"Déclenché par\", \"value\": \"${{ github.actor }}\", \"inline\": true},\n {\"name\": \"Logs\", \"value\": \"[${{ github.run_id }}](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})\", \"inline\": false}\n ]\n }]\n }' \\\n ${{ secrets.DISCORD_WEBHOOK_URL }}\n\n - name: ⚠️ Notify Discord - Cancelled\n if: ${{ contains(needs.*.result, 'cancelled') && github.event_name != 'pull_request' }}\n run: |\n curl -H \"Content-Type: application/json\" \\\n -d '{\n \"embeds\": [{\n \"title\": \"⚠️ Déploiement annulé\",\n \"color\": 16776960,\n \"fields\": [\n {\"name\": \"Repo\", \"value\": \"${{ github.repository }}\", \"inline\": true},\n {\"name\": \"Branche\", \"value\": \"${{ github.ref_name }}\", \"inline\": true},\n {\"name\": \"Commit\", \"value\": \"[`${{ github.sha }}`](${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }})\", \"inline\": false},\n {\"name\": \"Déclenché par\", \"value\": \"${{ github.actor }}\", \"inline\": true},\n {\"name\": \"Logs\", \"value\": \"[${{ github.run_id }}](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})\", \"inline\": false}\n ]\n }]\n }' \\\n ${{ secrets.DISCORD_WEBHOOK_URL }}\n\n - name: ⚠️ Notify Discord - PR Build failure\n if: ${{ contains(needs.*.result, 'failure') && !contains(needs.*.result, 'cancelled') && github.event_name == 'pull_request' }}\n run: |\n curl -H \"Content-Type: application/json\" \\\n -d '{\n \"embeds\": [{\n \"title\": \"❌ Build de PR échoué\",\n \"color\": 15158332,\n \"fields\": [\n {\"name\": \"Repo\", \"value\": \"${{ github.repository }}\", \"inline\": true},\n {\"name\": \"PR\", \"value\": \"[#${{ github.event.pull_request.number }}](${{ github.event.pull_request.html_url }})\", \"inline\": true},\n {\"name\": \"Commit\", \"value\": \"[`${{ github.sha }}`](${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }})\", \"inline\": false},\n {\"name\": \"Déclenché par\", \"value\": \"${{ github.actor }}\", \"inline\": true},\n {\"name\": \"Logs\", \"value\": \"[${{ github.run_id }}](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})\", \"inline\": false}\n ]\n }]\n }' \\\n ${{ secrets.DISCORD_WEBHOOK_URL }}\n"}, "1410fc6733bfc209ec9fc5dcde3e4fcd382efc68": {"t": 1785770081.2211921, "n": 20171, "h": "8f964c4a952a2aaa", "c": "name: 🚀 Build & Deploy\n\non:\n push:\n branches:\n - main\n - develop\n pull_request:\n branches:\n - main\n - develop\n\nenv:\n REGISTRY: ghcr.io\n\njobs:\n build-frontend:\n name: 🏗️ Build Frontend Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-frontend\n tags: |\n type=ref,event=branch\n type=ref,event=pr\n type=sha,prefix=sha-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/frontend\n file: ./packages/frontend/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: production\n cache-from: type=gha,scope=frontend\n cache-to: type=gha,scope=frontend,mode=max\n\n build-gateway:\n name: 🏗️ Build Gateway Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-gateway-service\n tags: |\n type=ref,event=branch\n type=ref,event=pr\n type=sha,prefix=sha-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/backend\n file: ./packages/backend/apps/gateway/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: runtime\n cache-from: type=gha,scope=gateway\n cache-to: type=gha,scope=gateway,mode=max\n\n build-authentication:\n name: 🏗️ Build Authentication Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-authentication-service\n tags: |\n type=ref,event=branch\n type=ref,event=pr\n type=sha,prefix=sha-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/backend\n file: ./packages/backend/apps/authentication/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: runtime\n cache-from: type=gha,scope=authentication\n cache-to: type=gha,scope=authentication,mode=max\n\n build-billing:\n name: 🏗️ Build Billing Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-billing-service\n tags: |\n type=ref,event=branch\n type=ref,event=pr\n type=sha,prefix=sha-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/backend\n file: ./packages/backend/apps/billing/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: runtime\n cache-from: type=gha,scope=billing\n cache-to: type=gha,scope=billing,mode=max\n\n build-stock:\n name: 🏗️ Build Stock Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-stock-service\n tags: |\n type=ref,event=branch\n type=ref,event=pr\n type=sha,prefix=sha-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/backend\n file: ./packages/backend/apps/stock/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: runtime\n cache-from: type=gha,scope=stock\n cache-to: type=gha,scope=stock,mode=max\n\n build-delivery:\n name: 🏗️ Build Delivery Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-delivery-service\n tags: |\n type=ref,event=branch\n type=ref,event=pr\n type=sha,prefix=sha-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/backend\n file: ./packages/backend/apps/delivery/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: runtime\n cache-from: type=gha,scope=delivery\n cache-to: type=gha,scope=delivery,mode=max\n\n build-users:\n name: 🏗️ Build Users Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-users-service\n tags: |\n type=ref,event=branch\n type=ref,event=pr\n type=sha,prefix=sha-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/backend\n file: ./packages/backend/apps/users/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: runtime\n cache-from: type=gha,scope=users\n cache-to: type=gha,scope=users,mode=max\n\n deploy:\n name: 🚀 Deploy to Production\n runs-on: ubuntu-latest\n needs:\n [\n build-frontend,\n build-gateway,\n build-authentication,\n build-billing,\n build-stock,\n build-delivery,\n build-users,\n ]\n if: github.ref == 'refs/heads/main' && github.event_name == 'push'\n\n steps:\n - uses: actions/checkout@v4\n\n - uses: docker/login-action@v3\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n\n - name: 📋 Create production namespace & registry secret\n uses: appleboy/ssh-action@v0.1.7\n env:\n GHCR_USERNAME: ${{ github.actor }}\n GHCR_TOKEN: ${{ secrets.GHCR_PAT }}\n with:\n host: ${{ secrets.VPS_HOST }}\n username: github-actions\n key: ${{ secrets.VPS_SSH_KEY }}\n port: 22\n envs: GHCR_USERNAME,GHCR_TOKEN\n script: |\n kubectl create namespace production --kubeconfig ~/.kube/config 2>/dev/null || true\n kubectl delete secret ghcr-secret -n production --kubeconfig ~/.kube/config 2>/dev/null || true\n kubectl create secret docker-registry ghcr-secret \\\n --docker-server=ghcr.io \\\n --docker-username=$GHCR_USERNAME \\\n --docker-password=$GHCR_TOKEN \\\n -n production \\\n --kubeconfig ~/.kube/config\n rm -rf /tmp/k8s-manifests && mkdir -p /tmp/k8s-manifests\n\n - name: 🚀 Transfer K8s manifests\n uses: appleboy/scp-action@v0.1.4\n with:\n host: ${{ secrets.VPS_HOST }}\n username: github-actions\n key: ${{ secrets.VPS_SSH_KEY }}\n port: 22\n source: 'kubernetes/'\n target: '/tmp/k8s-manifests'\n overwrite: true\n\n - name: ⚡ Apply manifests & rollout\n uses: appleboy/ssh-action@v0.1.7\n with:\n host: ${{ secrets.VPS_HOST }}\n username: github-actions\n key: ${{ secrets.VPS_SSH_KEY }}\n port: 22\n command_timeout: 15m\n script: |\n kubectl apply -k /tmp/k8s-manifests/kubernetes --kubeconfig ~/.kube/config\n\n kubectl rollout restart deployment/transvirex-frontend -n production --kubeconfig ~/.kube/config\n kubectl rollout restart deployment/transvirex-gateway -n production --kubeconfig ~/.kube/config\n kubectl rollout restart deployment/transvirex-authentication -n production --kubeconfig ~/.kube/config\n kubectl rollout restart deployment/transvirex-billing -n production --kubeconfig ~/.kube/config\n kubectl rollout restart deployment/transvirex-stock -n production --kubeconfig ~/.kube/config\n kubectl rollout restart deployment/transvirex-delivery -n production --kubeconfig ~/.kube/config\n kubectl rollout restart deployment/transvirex-users -n production --kubeconfig ~/.kube/config\n\n kubectl rollout status deployment/transvirex-frontend -n production --timeout=10m --kubeconfig ~/.kube/config\n kubectl rollout status deployment/transvirex-gateway -n production --timeout=10m --kubeconfig ~/.kube/config\n kubectl rollout status deployment/transvirex-authentication -n production --timeout=10m --kubeconfig ~/.kube/config\n kubectl rollout status deployment/transvirex-billing -n production --timeout=10m --kubeconfig ~/.kube/config\n kubectl rollout status deployment/transvirex-stock -n production --timeout=10m --kubeconfig ~/.kube/config\n kubectl rollout status deployment/transvirex-delivery -n production --timeout=10m --kubeconfig ~/.kube/config\n kubectl rollout status deployment/transvirex-users -n production --timeout=10m --kubeconfig ~/.kube/config\n\n rm -rf /tmp/k8s-manifests\n\n notify:\n name: 📢 Notify\n runs-on: ubuntu-latest\n needs:\n [\n build-frontend,\n build-gateway,\n build-authentication,\n build-billing,\n build-stock,\n build-delivery,\n build-users,\n deploy,\n ]\n if: always()\n\n steps:\n - name: ✅ Notify Discord - Success\n if: ${{ !contains(needs.*.result, 'failure') && !contains(needs.*.result, 'cancelled') }}\n run: |\n curl -H \"Content-Type: application/json\" \\\n -d '{\n \"embeds\": [{\n \"title\": \"✅ Déploiement réussi\",\n \"color\": 3066993,\n \"fields\": [\n {\"name\": \"Repo\", \"value\": \"${{ github.repository }}\", \"inline\": true},\n {\"name\": \"Branche\", \"value\": \"${{ github.ref_name }}\", \"inline\": true},\n {\"name\": \"Commit\", \"value\": \"[`${{ github.sha }}`](${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }})\", \"inline\": false},\n {\"name\": \"Déclenché par\", \"value\": \"${{ github.actor }}\", \"inline\": true}\n ]\n }]\n }' \\\n ${{ secrets.DISCORD_WEBHOOK_URL }}\n\n - name: ❌ Notify Discord - Failure\n if: ${{ contains(needs.*.result, 'failure') && !contains(needs.*.result, 'cancelled') && github.event_name != 'pull_request' }}\n run: |\n curl -H \"Content-Type: application/json\" \\\n -d '{\n \"embeds\": [{\n \"title\": \"❌ Déploiement échoué\",\n \"color\": 15158332,\n \"fields\": [\n {\"name\": \"Repo\", \"value\": \"${{ github.repository }}\", \"inline\": true},\n {\"name\": \"Branche\", \"value\": \"${{ github.ref_name }}\", \"inline\": true},\n {\"name\": \"Commit\", \"value\": \"[`${{ github.sha }}`](${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }})\", \"inline\": false},\n {\"name\": \"Déclenché par\", \"value\": \"${{ github.actor }}\", \"inline\": true},\n {\"name\": \"Logs\", \"value\": \"[${{ github.run_id }}](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})\", \"inline\": false}\n ]\n }]\n }' \\\n ${{ secrets.DISCORD_WEBHOOK_URL }}\n\n - name: ⚠️ Notify Discord - Cancelled\n if: ${{ contains(needs.*.result, 'cancelled') && github.event_name != 'pull_request' }}\n run: |\n curl -H \"Content-Type: application/json\" \\\n -d '{\n \"embeds\": [{\n \"title\": \"⚠️ Déploiement annulé\",\n \"color\": 16776960,\n \"fields\": [\n {\"name\": \"Repo\", \"value\": \"${{ github.repository }}\", \"inline\": true},\n {\"name\": \"Branche\", \"value\": \"${{ github.ref_name }}\", \"inline\": true},\n {\"name\": \"Commit\", \"value\": \"[`${{ github.sha }}`](${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }})\", \"inline\": false},\n {\"name\": \"Déclenché par\", \"value\": \"${{ github.actor }}\", \"inline\": true},\n {\"name\": \"Logs\", \"value\": \"[${{ github.run_id }}](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})\", \"inline\": false}\n ]\n }]\n }' \\\n ${{ secrets.DISCORD_WEBHOOK_URL }}\n\n - name: ⚠️ Notify Discord - PR Build failure\n if: ${{ contains(needs.*.result, 'failure') && !contains(needs.*.result, 'cancelled') && github.event_name == 'pull_request' }}\n run: |\n curl -H \"Content-Type: application/json\" \\\n -d '{\n \"embeds\": [{\n \"title\": \"❌ Build de PR échoué\",\n \"color\": 15158332,\n \"fields\": [\n {\"name\": \"Repo\", \"value\": \"${{ github.repository }}\", \"inline\": true},\n {\"name\": \"PR\", \"value\": \"[#${{ github.event.pull_request.number }}](${{ github.event.pull_request.html_url }})\", \"inline\": true},\n {\"name\": \"Commit\", \"value\": \"[`${{ github.sha }}`](${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }})\", \"inline\": false},\n {\"name\": \"Déclenché par\", \"value\": \"${{ github.actor }}\", \"inline\": true},\n {\"name\": \"Logs\", \"value\": \"[${{ github.run_id }}](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})\", \"inline\": false}\n ]\n }]\n }' \\\n ${{ secrets.DISCORD_WEBHOOK_URL }}\n"}, "b5db05bbfa6f39431a7a8119eea7c80d84c47e7f": {"t": 1785770082.7503567, "n": 17560, "h": "f38d4bc2ed70b356", "c": "name: 🚀 Build & Deploy\n\non:\n push:\n branches:\n - main\n - develop\n pull_request:\n branches:\n - main\n - develop\n\nenv:\n REGISTRY: ghcr.io\n\njobs:\n build-frontend:\n name: 🏗️ Build Frontend Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-frontend\n tags: |\n type=ref,event=branch\n type=ref,event=pr\n type=sha,prefix=sha-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/frontend\n file: ./packages/frontend/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: production\n cache-from: type=gha,scope=frontend\n cache-to: type=gha,scope=frontend,mode=max\n\n build-gateway:\n name: 🏗️ Build Gateway Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-gateway-service\n tags: |\n type=ref,event=branch\n type=ref,event=pr\n type=sha,prefix=sha-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/backend\n file: ./packages/backend/apps/gateway/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: runtime\n cache-from: type=gha,scope=gateway\n cache-to: type=gha,scope=gateway,mode=max\n\n build-authentication:\n name: 🏗️ Build Authentication Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-authentication-service\n tags: |\n type=ref,event=branch\n type=ref,event=pr\n type=sha,prefix=sha-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/backend\n file: ./packages/backend/apps/authentication/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: runtime\n cache-from: type=gha,scope=authentication\n cache-to: type=gha,scope=authentication,mode=max\n\n build-billing:\n name: 🏗️ Build Billing Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-billing-service\n tags: |\n type=ref,event=branch\n type=ref,event=pr\n type=sha,prefix=sha-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/backend\n file: ./packages/backend/apps/billing/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: runtime\n cache-from: type=gha,scope=billing\n cache-to: type=gha,scope=billing,mode=max\n\n build-stock:\n name: 🏗️ Build Stock Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-stock-service\n tags: |\n type=ref,event=branch\n type=ref,event=pr\n type=sha,prefix=sha-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/backend\n file: ./packages/backend/apps/stock/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: runtime\n cache-from: type=gha,scope=stock\n cache-to: type=gha,scope=stock,mode=max\n\n build-delivery:\n name: 🏗️ Build Delivery Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-delivery-service\n tags: |\n type=ref,event=branch\n type=ref,event=pr\n type=sha,prefix=sha-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/backend\n file: ./packages/backend/apps/delivery/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: runtime\n cache-from: type=gha,scope=delivery\n cache-to: type=gha,scope=delivery,mode=max\n\n build-users:\n name: 🏗️ Build Users Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-users-service\n tags: |\n type=ref,event=branch\n type=ref,event=pr\n type=sha,prefix=sha-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/backend\n file: ./packages/backend/apps/users/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: runtime\n cache-from: type=gha,scope=users\n cache-to: type=gha,scope=users,mode=max\n\n deploy:\n name: 🚀 Deploy to Production\n runs-on: ubuntu-latest\n needs:\n [\n build-frontend,\n build-gateway,\n build-authentication,\n build-billing,\n build-stock,\n build-delivery,\n build-users,\n ]\n if: github.ref == 'refs/heads/main' && github.event_name == 'push'\n\n steps:\n - uses: actions/checkout@v4\n\n - uses: docker/login-action@v3\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n\n - name: 📋 Create production namespace & registry secret\n uses: appleboy/ssh-action@v0.1.7\n env:\n GHCR_USERNAME: ${{ github.actor }}\n GHCR_TOKEN: ${{ secrets.GHCR_PAT }}\n with:\n host: ${{ secrets.VPS_HOST }}\n username: github-actions\n key: ${{ secrets.VPS_SSH_KEY }}\n port: 22\n envs: GHCR_USERNAME,GHCR_TOKEN\n script: |\n kubectl create namespace production --kubeconfig ~/.kube/config 2>/dev/null || true\n kubectl delete secret ghcr-secret -n production --kubeconfig ~/.kube/config 2>/dev/null || true\n kubectl create secret docker-registry ghcr-secret \\\n --docker-server=ghcr.io \\\n --docker-username=$GHCR_USERNAME \\\n --docker-password=$GHCR_TOKEN \\\n -n production \\\n --kubeconfig ~/.kube/config\n rm -rf /tmp/k8s-manifests && mkdir -p /tmp/k8s-manifests\n\n - name: 🚀 Transfer K8s manifests\n uses: appleboy/scp-action@v0.1.4\n with:\n host: ${{ secrets.VPS_HOST }}\n username: github-actions\n key: ${{ secrets.VPS_SSH_KEY }}\n port: 22\n source: 'kubernetes/'\n target: '/tmp/k8s-manifests'\n overwrite: true\n\n - name: ⚡ Apply manifests & rollout\n uses: appleboy/ssh-action@v0.1.7\n with:\n host: ${{ secrets.VPS_HOST }}\n username: github-actions\n key: ${{ secrets.VPS_SSH_KEY }}\n port: 22\n command_timeout: 15m\n script: |\n kubectl apply -k /tmp/k8s-manifests/kubernetes --kubeconfig ~/.kube/config\n\n kubectl rollout restart deployment/transvirex-frontend -n production --kubeconfig ~/.kube/config\n kubectl rollout restart deployment/transvirex-gateway -n production --kubeconfig ~/.kube/config\n kubectl rollout restart deployment/transvirex-authentication -n production --kubeconfig ~/.kube/config\n kubectl rollout restart deployment/transvirex-billing -n production --kubeconfig ~/.kube/config\n kubectl rollout restart deployment/transvirex-stock -n production --kubeconfig ~/.kube/config\n kubectl rollout restart deployment/transvirex-delivery -n production --kubeconfig ~/.kube/config\n kubectl rollout restart deployment/transvirex-users -n production --kubeconfig ~/.kube/config\n\n kubectl rollout status deployment/transvirex-frontend -n production --timeout=10m --kubeconfig ~/.kube/config\n kubectl rollout status deployment/transvirex-gateway -n production --timeout=10m --kubeconfig ~/.kube/config\n kubectl rollout status deployment/transvirex-authentication -n production --timeout=10m --kubeconfig ~/.kube/config\n kubectl rollout status deployment/transvirex-billing -n production --timeout=10m --kubeconfig ~/.kube/config\n kubectl rollout status deployment/transvirex-stock -n production --timeout=10m --kubeconfig ~/.kube/config\n kubectl rollout status deployment/transvirex-delivery -n production --timeout=10m --kubeconfig ~/.kube/config\n kubectl rollout status deployment/transvirex-users -n production --timeout=10m --kubeconfig ~/.kube/config\n\n rm -rf /tmp/k8s-manifests\n\n notify:\n name: 📢 Notify\n runs-on: ubuntu-latest\n needs:\n [\n build-frontend,\n build-gateway,\n build-authentication,\n build-billing,\n build-stock,\n build-delivery,\n build-users,\n deploy,\n ]\n if: always()\n\n steps:\n - name: ✅ Notify Discord - Success\n if: ${{ !contains(needs.*.result, 'failure') && !contains(needs.*.result, 'cancelled') }}\n run: |\n curl -H \"Content-Type: application/json\" \\\n -d '{\n \"embeds\": [{\n \"title\": \"✅ Déploiement réussi\",\n \"color\": 3066993,\n \"fields\": [\n {\"name\": \"Repo\", \"value\": \"${{ github.repository }}\", \"inline\": true},\n {\"name\": \"Branche\", \"value\": \"${{ github.ref_name }}\", \"inline\": true},\n {\"name\": \"Commit\", \"value\": \"[`${{ github.sha }}`](${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }})\", \"inline\": false},\n {\"name\": \"Déclenché par\", \"value\": \"${{ github.actor }}\", \"inline\": true}\n ]\n }]\n }' \\\n ${{ secrets.DISCORD_WEBHOOK_URL }}\n\n - name: ❌ Notify Discord - Failure\n if: ${{ contains(needs.*.result, 'failure') }}\n run: |\n curl -H \"Content-Type: application/json\" \\\n -d '{\n \"embeds\": [{\n \"title\": \"❌ Déploiement échoué\",\n \"color\": 15158332,\n \"fields\": [\n {\"name\": \"Repo\", \"value\": \"${{ github.repository }}\", \"inline\": true},\n {\"name\": \"Branche\", \"value\": \"${{ github.ref_name }}\", \"inline\": true},\n {\"name\": \"Commit\", \"value\": \"[`${{ github.sha }}`](${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }})\", \"inline\": false},\n {\"name\": \"Déclenché par\", \"value\": \"${{ github.actor }}\", \"inline\": true},\n {\"name\": \"Logs\", \"value\": \"[${{ github.run_id }}](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})\", \"inline\": false}\n ]\n }]\n }' \\\n ${{ secrets.DISCORD_WEBHOOK_URL }}\n"}, "9d38ee6d3d36cdfecba10e5595d1d0a1ad962865": {"t": 1785770084.058349, "n": 17035, "h": "909b4c82e3f4ebbc", "c": "name: 🚀 Build & Deploy\n\non:\n push:\n branches:\n - main\n - develop\n pull_request:\n branches:\n - main\n - develop\n\nenv:\n REGISTRY: ghcr.io\n\njobs:\n build-frontend:\n name: 🏗️ Build Frontend Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-frontend\n tags: |\n type=ref,event=branch\n type=sha,prefix={{branch}}-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/frontend\n file: ./packages/frontend/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: production\n cache-from: type=gha,scope=frontend\n cache-to: type=gha,scope=frontend,mode=max\n\n build-gateway:\n name: 🏗️ Build Gateway Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-gateway-service\n tags: |\n type=ref,event=branch\n type=sha,prefix={{branch}}-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/backend\n file: ./packages/backend/apps/gateway/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: runtime\n cache-from: type=gha,scope=gateway\n cache-to: type=gha,scope=gateway,mode=max\n\n build-authentication:\n name: 🏗️ Build Authentication Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-authentication-service\n tags: |\n type=ref,event=branch\n type=sha,prefix={{branch}}-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/backend\n file: ./packages/backend/apps/authentication/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: runtime\n cache-from: type=gha,scope=authentication\n cache-to: type=gha,scope=authentication,mode=max\n\n build-billing:\n name: 🏗️ Build Billing Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-billing-service\n tags: |\n type=ref,event=branch\n type=sha,prefix={{branch}}-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/backend\n file: ./packages/backend/apps/billing/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: runtime\n cache-from: type=gha,scope=billing\n cache-to: type=gha,scope=billing,mode=max\n\n build-stock:\n name: 🏗️ Build Stock Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-stock-service\n tags: |\n type=ref,event=branch\n type=sha,prefix={{branch}}-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/backend\n file: ./packages/backend/apps/stock/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: runtime\n cache-from: type=gha,scope=stock\n cache-to: type=gha,scope=stock,mode=max\n\n build-delivery:\n name: 🏗️ Build Delivery Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-delivery-service\n tags: |\n type=ref,event=branch\n type=sha,prefix={{branch}}-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/backend\n file: ./packages/backend/apps/delivery/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: runtime\n cache-from: type=gha,scope=delivery\n cache-to: type=gha,scope=delivery,mode=max\n\n build-users:\n name: 🏗️ Build Users Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-users-service\n tags: |\n type=ref,event=branch\n type=sha,prefix={{branch}}-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/backend\n file: ./packages/backend/apps/users/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: runtime\n cache-from: type=gha,scope=users\n cache-to: type=gha,scope=users,mode=max\n\n deploy:\n name: 🚀 Deploy to Production\n runs-on: ubuntu-latest\n needs: [build-frontend, build-gateway, build-authentication, build-billing, build-stock, build-delivery, build-users]\n if: github.ref == 'refs/heads/main' && github.event_name == 'push'\n\n steps:\n - uses: actions/checkout@v4\n\n - uses: docker/login-action@v3\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n\n - name: 📋 Create production namespace & registry secret\n uses: appleboy/ssh-action@v0.1.7\n env:\n GHCR_USERNAME: ${{ github.actor }}\n GHCR_TOKEN: ${{ secrets.GHCR_PAT }}\n with:\n host: ${{ secrets.VPS_HOST }}\n username: github-actions\n key: ${{ secrets.VPS_SSH_KEY }}\n port: 22\n envs: GHCR_USERNAME,GHCR_TOKEN\n script: |\n kubectl create namespace production --kubeconfig ~/.kube/config 2>/dev/null || true\n kubectl delete secret ghcr-secret -n production --kubeconfig ~/.kube/config 2>/dev/null || true\n kubectl create secret docker-registry ghcr-secret \\\n --docker-server=ghcr.io \\\n --docker-username=$GHCR_USERNAME \\\n --docker-password=$GHCR_TOKEN \\\n -n production \\\n --kubeconfig ~/.kube/config\n rm -rf /tmp/k8s-manifests && mkdir -p /tmp/k8s-manifests\n\n - name: 🚀 Transfer K8s manifests\n uses: appleboy/scp-action@v0.1.4\n with:\n host: ${{ secrets.VPS_HOST }}\n username: github-actions\n key: ${{ secrets.VPS_SSH_KEY }}\n port: 22\n source: 'kubernetes/'\n target: '/tmp/k8s-manifests'\n overwrite: true\n\n - name: ⚡ Apply manifests & rollout\n uses: appleboy/ssh-action@v0.1.7\n with:\n host: ${{ secrets.VPS_HOST }}\n username: github-actions\n key: ${{ secrets.VPS_SSH_KEY }}\n port: 22\n command_timeout: 15m\n script: |\n kubectl apply -k /tmp/k8s-manifests/kubernetes --kubeconfig ~/.kube/config\n\n kubectl rollout restart deployment/transvirex-frontend -n production --kubeconfig ~/.kube/config\n kubectl rollout restart deployment/transvirex-gateway -n production --kubeconfig ~/.kube/config\n kubectl rollout restart deployment/transvirex-authentication -n production --kubeconfig ~/.kube/config\n kubectl rollout restart deployment/transvirex-billing -n production --kubeconfig ~/.kube/config\n kubectl rollout restart deployment/transvirex-stock -n production --kubeconfig ~/.kube/config\n kubectl rollout restart deployment/transvirex-delivery -n production --kubeconfig ~/.kube/config\n kubectl rollout restart deployment/transvirex-users -n production --kubeconfig ~/.kube/config\n\n kubectl rollout status deployment/transvirex-frontend -n production --timeout=10m --kubeconfig ~/.kube/config\n kubectl rollout status deployment/transvirex-gateway -n production --timeout=10m --kubeconfig ~/.kube/config\n kubectl rollout status deployment/transvirex-authentication -n production --timeout=10m --kubeconfig ~/.kube/config\n kubectl rollout status deployment/transvirex-billing -n production --timeout=10m --kubeconfig ~/.kube/config\n kubectl rollout status deployment/transvirex-stock -n production --timeout=10m --kubeconfig ~/.kube/config\n kubectl rollout status deployment/transvirex-delivery -n production --timeout=10m --kubeconfig ~/.kube/config\n kubectl rollout status deployment/transvirex-users -n production --timeout=10m --kubeconfig ~/.kube/config\n\n rm -rf /tmp/k8s-manifests\n\n notify:\n name: 📢 Notify\n runs-on: ubuntu-latest\n needs: [build-frontend, build-gateway, build-authentication, build-billing, build-stock, build-delivery, build-users, deploy]\n if: always()\n\n steps:\n - name: ✅ Notify Discord - Success\n if: ${{ !contains(needs.*.result, 'failure') && !contains(needs.*.result, 'cancelled') }}\n run: |\n curl -H \"Content-Type: application/json\" \\\n -d '{\n \"embeds\": [{\n \"title\": \"✅ Déploiement réussi\",\n \"color\": 3066993,\n \"fields\": [\n {\"name\": \"Repo\", \"value\": \"${{ github.repository }}\", \"inline\": true},\n {\"name\": \"Branche\", \"value\": \"${{ github.ref_name }}\", \"inline\": true},\n {\"name\": \"Commit\", \"value\": \"[`${{ github.sha }}`](${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }})\", \"inline\": false},\n {\"name\": \"Déclenché par\", \"value\": \"${{ github.actor }}\", \"inline\": true}\n ]\n }]\n }' \\\n ${{ secrets.DISCORD_WEBHOOK_URL }}\n\n - name: ❌ Notify Discord - Failure\n if: ${{ contains(needs.*.result, 'failure') }}\n run: |\n curl -H \"Content-Type: application/json\" \\\n -d '{\n \"embeds\": [{\n \"title\": \"❌ Déploiement échoué\",\n \"color\": 15158332,\n \"fields\": [\n {\"name\": \"Repo\", \"value\": \"${{ github.repository }}\", \"inline\": true},\n {\"name\": \"Branche\", \"value\": \"${{ github.ref_name }}\", \"inline\": true},\n {\"name\": \"Commit\", \"value\": \"[`${{ github.sha }}`](${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }})\", \"inline\": false},\n {\"name\": \"Déclenché par\", \"value\": \"${{ github.actor }}\", \"inline\": true},\n {\"name\": \"Logs\", \"value\": \"[${{ github.run_id }}](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})\", \"inline\": false}\n ]\n }]\n }' \\\n ${{ secrets.DISCORD_WEBHOOK_URL }}\n"}, "fd1c3845d3c49e1d8e0413a384971949440c2d75": {"t": 1785770085.6159365, "n": 17031, "h": "bec00d8d284b6589", "c": "name: 🚀 Build & Deploy\n\non:\n push:\n branches:\n - main\n - develop\n pull_request:\n branches:\n - main\n - develop\n\nenv:\n REGISTRY: ghcr.io\n\njobs:\n build-frontend:\n name: 🏗️ Build Frontend Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-frontend\n tags: |\n type=ref,event=branch\n type=sha,prefix={{branch}}-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/frontend\n file: ./packages/frontend/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: production\n cache-from: type=gha,scope=frontend\n cache-to: type=gha,scope=frontend,mode=max\n\n build-gateway:\n name: 🏗️ Build Gateway Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-gateway-service\n tags: |\n type=ref,event=branch\n type=sha,prefix={{branch}}-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/backend\n file: ./packages/backend/apps/gateway/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: runtime\n cache-from: type=gha,scope=gateway\n cache-to: type=gha,scope=gateway,mode=max\n\n build-authentication:\n name: 🏗️ Build Authentication Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-authentication-service\n tags: |\n type=ref,event=branch\n type=sha,prefix={{branch}}-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/backend\n file: ./packages/backend/apps/authentication/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: runtime\n cache-from: type=gha,scope=authentication\n cache-to: type=gha,scope=authentication,mode=max\n\n build-billing:\n name: 🏗️ Build Billing Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-billing-service\n tags: |\n type=ref,event=branch\n type=sha,prefix={{branch}}-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/backend\n file: ./packages/backend/apps/billing/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: runtime\n cache-from: type=gha,scope=billing\n cache-to: type=gha,scope=billing,mode=max\n\n build-stock:\n name: 🏗️ Build Stock Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-stock-service\n tags: |\n type=ref,event=branch\n type=sha,prefix={{branch}}-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/backend\n file: ./packages/backend/apps/stock/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: runtime\n cache-from: type=gha,scope=stock\n cache-to: type=gha,scope=stock,mode=max\n\n build-delivery:\n name: 🏗️ Build Delivery Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-delivery-service\n tags: |\n type=ref,event=branch\n type=sha,prefix={{branch}}-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/backend\n file: ./packages/backend/apps/delivery/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: runtime\n cache-from: type=gha,scope=delivery\n cache-to: type=gha,scope=delivery,mode=max\n\n build-users:\n name: 🏗️ Build Users Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-users-service\n tags: |\n type=ref,event=branch\n type=sha,prefix={{branch}}-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/backend\n file: ./packages/backend/apps/users/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: runtime\n cache-from: type=gha,scope=users\n cache-to: type=gha,scope=users,mode=max\n\n deploy:\n name: 🚀 Deploy to Production\n runs-on: ubuntu-latest\n needs: [build-frontend, build-gateway, build-authentication, build-billing, build-stock, build-delivery, build-users]\n if: github.ref == 'refs/heads/main' && github.event_name == 'push'\n\n steps:\n - uses: actions/checkout@v4\n\n - uses: docker/login-action@v3\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n\n - name: 📋 Create production namespace & registry secret\n uses: appleboy/ssh-action@v0.1.7\n env:\n GHCR_USERNAME: ${{ github.actor }}\n GHCR_TOKEN: ${{ github.token }}\n with:\n host: ${{ secrets.VPS_HOST }}\n username: github-actions\n key: ${{ secrets.VPS_SSH_KEY }}\n port: 22\n envs: GHCR_USERNAME,GHCR_TOKEN\n script: |\n kubectl create namespace production --kubeconfig ~/.kube/config 2>/dev/null || true\n kubectl delete secret ghcr-secret -n production --kubeconfig ~/.kube/config 2>/dev/null || true\n kubectl create secret docker-registry ghcr-secret \\\n --docker-server=ghcr.io \\\n --docker-username=$GHCR_USERNAME \\\n --docker-password=$GHCR_TOKEN \\\n -n production \\\n --kubeconfig ~/.kube/config\n rm -rf /tmp/k8s-manifests && mkdir -p /tmp/k8s-manifests\n\n - name: 🚀 Transfer K8s manifests\n uses: appleboy/scp-action@v0.1.4\n with:\n host: ${{ secrets.VPS_HOST }}\n username: github-actions\n key: ${{ secrets.VPS_SSH_KEY }}\n port: 22\n source: 'kubernetes/'\n target: '/tmp/k8s-manifests'\n overwrite: true\n\n - name: ⚡ Apply manifests & rollout\n uses: appleboy/ssh-action@v0.1.7\n with:\n host: ${{ secrets.VPS_HOST }}\n username: github-actions\n key: ${{ secrets.VPS_SSH_KEY }}\n port: 22\n command_timeout: 15m\n script: |\n kubectl apply -k /tmp/k8s-manifests/kubernetes --kubeconfig ~/.kube/config\n\n kubectl rollout restart deployment/transvirex-frontend -n production --kubeconfig ~/.kube/config\n kubectl rollout restart deployment/transvirex-gateway -n production --kubeconfig ~/.kube/config\n kubectl rollout restart deployment/transvirex-authentication -n production --kubeconfig ~/.kube/config\n kubectl rollout restart deployment/transvirex-billing -n production --kubeconfig ~/.kube/config\n kubectl rollout restart deployment/transvirex-stock -n production --kubeconfig ~/.kube/config\n kubectl rollout restart deployment/transvirex-delivery -n production --kubeconfig ~/.kube/config\n kubectl rollout restart deployment/transvirex-users -n production --kubeconfig ~/.kube/config\n\n kubectl rollout status deployment/transvirex-frontend -n production --timeout=10m --kubeconfig ~/.kube/config\n kubectl rollout status deployment/transvirex-gateway -n production --timeout=10m --kubeconfig ~/.kube/config\n kubectl rollout status deployment/transvirex-authentication -n production --timeout=10m --kubeconfig ~/.kube/config\n kubectl rollout status deployment/transvirex-billing -n production --timeout=10m --kubeconfig ~/.kube/config\n kubectl rollout status deployment/transvirex-stock -n production --timeout=10m --kubeconfig ~/.kube/config\n kubectl rollout status deployment/transvirex-delivery -n production --timeout=10m --kubeconfig ~/.kube/config\n kubectl rollout status deployment/transvirex-users -n production --timeout=10m --kubeconfig ~/.kube/config\n\n rm -rf /tmp/k8s-manifests\n\n notify:\n name: 📢 Notify\n runs-on: ubuntu-latest\n needs: [build-frontend, build-gateway, build-authentication, build-billing, build-stock, build-delivery, build-users, deploy]\n if: always()\n\n steps:\n - name: ✅ Notify Discord - Success\n if: ${{ !contains(needs.*.result, 'failure') && !contains(needs.*.result, 'cancelled') }}\n run: |\n curl -H \"Content-Type: application/json\" \\\n -d '{\n \"embeds\": [{\n \"title\": \"✅ Déploiement réussi\",\n \"color\": 3066993,\n \"fields\": [\n {\"name\": \"Repo\", \"value\": \"${{ github.repository }}\", \"inline\": true},\n {\"name\": \"Branche\", \"value\": \"${{ github.ref_name }}\", \"inline\": true},\n {\"name\": \"Commit\", \"value\": \"[`${{ github.sha }}`](${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }})\", \"inline\": false},\n {\"name\": \"Déclenché par\", \"value\": \"${{ github.actor }}\", \"inline\": true}\n ]\n }]\n }' \\\n ${{ secrets.DISCORD_WEBHOOK_URL }}\n\n - name: ❌ Notify Discord - Failure\n if: ${{ contains(needs.*.result, 'failure') }}\n run: |\n curl -H \"Content-Type: application/json\" \\\n -d '{\n \"embeds\": [{\n \"title\": \"❌ Déploiement échoué\",\n \"color\": 15158332,\n \"fields\": [\n {\"name\": \"Repo\", \"value\": \"${{ github.repository }}\", \"inline\": true},\n {\"name\": \"Branche\", \"value\": \"${{ github.ref_name }}\", \"inline\": true},\n {\"name\": \"Commit\", \"value\": \"[`${{ github.sha }}`](${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }})\", \"inline\": false},\n {\"name\": \"Déclenché par\", \"value\": \"${{ github.actor }}\", \"inline\": true},\n {\"name\": \"Logs\", \"value\": \"[${{ github.run_id }}](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})\", \"inline\": false}\n ]\n }]\n }' \\\n ${{ secrets.DISCORD_WEBHOOK_URL }}\n"}, "bc5b54de8e9e55be0839c94408fc4ca9350789a5": {"t": 1785770087.099259, "n": 16952, "h": "e423da5aeca76c44", "c": "name: 🚀 Build & Deploy\n\non:\n push:\n branches:\n - main\n - develop\n pull_request:\n branches:\n - main\n - develop\n\nenv:\n REGISTRY: ghcr.io\n\njobs:\n build-frontend:\n name: 🏗️ Build Frontend Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-frontend\n tags: |\n type=ref,event=branch\n type=sha,prefix={{branch}}-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/frontend\n file: ./packages/frontend/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: production\n cache-from: type=gha,scope=frontend\n cache-to: type=gha,scope=frontend,mode=max\n\n build-gateway:\n name: 🏗️ Build Gateway Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-gateway-service\n tags: |\n type=ref,event=branch\n type=sha,prefix={{branch}}-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/backend\n file: ./packages/backend/apps/gateway/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: runtime\n cache-from: type=gha,scope=gateway\n cache-to: type=gha,scope=gateway,mode=max\n\n build-authentication:\n name: 🏗️ Build Authentication Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-authentication-service\n tags: |\n type=ref,event=branch\n type=sha,prefix={{branch}}-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/backend\n file: ./packages/backend/apps/authentication/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: runtime\n cache-from: type=gha,scope=authentication\n cache-to: type=gha,scope=authentication,mode=max\n\n build-billing:\n name: 🏗️ Build Billing Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-billing-service\n tags: |\n type=ref,event=branch\n type=sha,prefix={{branch}}-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/backend\n file: ./packages/backend/apps/billing/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: runtime\n cache-from: type=gha,scope=billing\n cache-to: type=gha,scope=billing,mode=max\n\n build-stock:\n name: 🏗️ Build Stock Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-stock-service\n tags: |\n type=ref,event=branch\n type=sha,prefix={{branch}}-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/backend\n file: ./packages/backend/apps/stock/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: runtime\n cache-from: type=gha,scope=stock\n cache-to: type=gha,scope=stock,mode=max\n\n build-delivery:\n name: 🏗️ Build Delivery Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-delivery-service\n tags: |\n type=ref,event=branch\n type=sha,prefix={{branch}}-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/backend\n file: ./packages/backend/apps/delivery/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: runtime\n cache-from: type=gha,scope=delivery\n cache-to: type=gha,scope=delivery,mode=max\n\n build-users:\n name: 🏗️ Build Users Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-users-service\n tags: |\n type=ref,event=branch\n type=sha,prefix={{branch}}-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/backend\n file: ./packages/backend/apps/users/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: runtime\n cache-from: type=gha,scope=users\n cache-to: type=gha,scope=users,mode=max\n\n deploy:\n name: 🚀 Deploy to Production\n runs-on: ubuntu-latest\n needs: [build-frontend, build-gateway, build-authentication, build-billing, build-stock, build-delivery, build-users]\n if: github.ref == 'refs/heads/main' && github.event_name == 'push'\n\n steps:\n - uses: actions/checkout@v4\n\n - uses: docker/login-action@v3\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n\n - name: 📋 Create production namespace & registry secret\n uses: appleboy/ssh-action@v0.1.7\n env:\n GHCR_USERNAME: ${{ github.actor }}\n GHCR_TOKEN: ${{ github.token }}\n with:\n host: ${{ secrets.VPS_HOST }}\n username: github-actions\n key: ${{ secrets.VPS_SSH_KEY }}\n port: 22\n envs: GHCR_USERNAME,GHCR_TOKEN\n script: |\n kubectl create namespace production --kubeconfig ~/.kube/config 2>/dev/null || true\n kubectl delete secret ghcr-secret -n production --kubeconfig ~/.kube/config 2>/dev/null || true\n kubectl create secret docker-registry ghcr-secret \\\n --docker-server=ghcr.io \\\n --docker-username=$GHCR_USERNAME \\\n --docker-password=$GHCR_TOKEN \\\n -n production \\\n --kubeconfig ~/.kube/config\n\n - name: 🚀 Transfer K8s manifests\n uses: appleboy/scp-action@v0.1.4\n with:\n host: ${{ secrets.VPS_HOST }}\n username: github-actions\n key: ${{ secrets.VPS_SSH_KEY }}\n port: 22\n source: 'kubernetes/'\n target: '/tmp/k8s-manifests'\n overwrite: true\n\n - name: ⚡ Apply manifests & rollout\n uses: appleboy/ssh-action@v0.1.7\n with:\n host: ${{ secrets.VPS_HOST }}\n username: github-actions\n key: ${{ secrets.VPS_SSH_KEY }}\n port: 22\n command_timeout: 15m\n script: |\n kubectl apply -k /tmp/k8s-manifests/kubernetes --kubeconfig ~/.kube/config\n\n kubectl rollout restart deployment/transvirex-frontend -n production --kubeconfig ~/.kube/config\n kubectl rollout restart deployment/transvirex-gateway -n production --kubeconfig ~/.kube/config\n kubectl rollout restart deployment/transvirex-authentication -n production --kubeconfig ~/.kube/config\n kubectl rollout restart deployment/transvirex-billing -n production --kubeconfig ~/.kube/config\n kubectl rollout restart deployment/transvirex-stock -n production --kubeconfig ~/.kube/config\n kubectl rollout restart deployment/transvirex-delivery -n production --kubeconfig ~/.kube/config\n kubectl rollout restart deployment/transvirex-users -n production --kubeconfig ~/.kube/config\n\n kubectl rollout status deployment/transvirex-frontend -n production --timeout=10m --kubeconfig ~/.kube/config\n kubectl rollout status deployment/transvirex-gateway -n production --timeout=10m --kubeconfig ~/.kube/config\n kubectl rollout status deployment/transvirex-authentication -n production --timeout=10m --kubeconfig ~/.kube/config\n kubectl rollout status deployment/transvirex-billing -n production --timeout=10m --kubeconfig ~/.kube/config\n kubectl rollout status deployment/transvirex-stock -n production --timeout=10m --kubeconfig ~/.kube/config\n kubectl rollout status deployment/transvirex-delivery -n production --timeout=10m --kubeconfig ~/.kube/config\n kubectl rollout status deployment/transvirex-users -n production --timeout=10m --kubeconfig ~/.kube/config\n\n rm -rf /tmp/k8s-manifests\n\n notify:\n name: 📢 Notify\n runs-on: ubuntu-latest\n needs: [build-frontend, build-gateway, build-authentication, build-billing, build-stock, build-delivery, build-users, deploy]\n if: always()\n\n steps:\n - name: ✅ Notify Discord - Success\n if: ${{ !contains(needs.*.result, 'failure') && !contains(needs.*.result, 'cancelled') }}\n run: |\n curl -H \"Content-Type: application/json\" \\\n -d '{\n \"embeds\": [{\n \"title\": \"✅ Déploiement réussi\",\n \"color\": 3066993,\n \"fields\": [\n {\"name\": \"Repo\", \"value\": \"${{ github.repository }}\", \"inline\": true},\n {\"name\": \"Branche\", \"value\": \"${{ github.ref_name }}\", \"inline\": true},\n {\"name\": \"Commit\", \"value\": \"[`${{ github.sha }}`](${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }})\", \"inline\": false},\n {\"name\": \"Déclenché par\", \"value\": \"${{ github.actor }}\", \"inline\": true}\n ]\n }]\n }' \\\n ${{ secrets.DISCORD_WEBHOOK_URL }}\n\n - name: ❌ Notify Discord - Failure\n if: ${{ contains(needs.*.result, 'failure') }}\n run: |\n curl -H \"Content-Type: application/json\" \\\n -d '{\n \"embeds\": [{\n \"title\": \"❌ Déploiement échoué\",\n \"color\": 15158332,\n \"fields\": [\n {\"name\": \"Repo\", \"value\": \"${{ github.repository }}\", \"inline\": true},\n {\"name\": \"Branche\", \"value\": \"${{ github.ref_name }}\", \"inline\": true},\n {\"name\": \"Commit\", \"value\": \"[`${{ github.sha }}`](${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }})\", \"inline\": false},\n {\"name\": \"Déclenché par\", \"value\": \"${{ github.actor }}\", \"inline\": true},\n {\"name\": \"Logs\", \"value\": \"[${{ github.run_id }}](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})\", \"inline\": false}\n ]\n }]\n }' \\\n ${{ secrets.DISCORD_WEBHOOK_URL }}\n"}, "9b8afabb8426b4affc636042f84bf89abf462ffb": {"t": 1785770088.4545608, "n": 16906, "h": "afeb622c139606f9", "c": "name: 🚀 Build & Deploy\n\non:\n push:\n branches:\n - main\n - develop\n pull_request:\n branches:\n - main\n - develop\n\nenv:\n REGISTRY: ghcr.io\n\njobs:\n build-frontend:\n name: 🏗️ Build Frontend Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-frontend\n tags: |\n type=ref,event=branch\n type=sha,prefix={{branch}}-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/frontend\n file: ./packages/frontend/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: production\n cache-from: type=gha,scope=frontend\n cache-to: type=gha,scope=frontend,mode=max\n\n build-gateway:\n name: 🏗️ Build Gateway Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-gateway-service\n tags: |\n type=ref,event=branch\n type=sha,prefix={{branch}}-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/backend\n file: ./packages/backend/apps/gateway/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: runtime\n cache-from: type=gha,scope=gateway\n cache-to: type=gha,scope=gateway,mode=max\n\n build-authentication:\n name: 🏗️ Build Authentication Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-authentication-service\n tags: |\n type=ref,event=branch\n type=sha,prefix={{branch}}-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/backend\n file: ./packages/backend/apps/authentication/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: runtime\n cache-from: type=gha,scope=authentication\n cache-to: type=gha,scope=authentication,mode=max\n\n build-billing:\n name: 🏗️ Build Billing Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-billing-service\n tags: |\n type=ref,event=branch\n type=sha,prefix={{branch}}-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/backend\n file: ./packages/backend/apps/billing/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: runtime\n cache-from: type=gha,scope=billing\n cache-to: type=gha,scope=billing,mode=max\n\n build-stock:\n name: 🏗️ Build Stock Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-stock-service\n tags: |\n type=ref,event=branch\n type=sha,prefix={{branch}}-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/backend\n file: ./packages/backend/apps/stock/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: runtime\n cache-from: type=gha,scope=stock\n cache-to: type=gha,scope=stock,mode=max\n\n build-delivery:\n name: 🏗️ Build Delivery Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-delivery-service\n tags: |\n type=ref,event=branch\n type=sha,prefix={{branch}}-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/backend\n file: ./packages/backend/apps/delivery/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: runtime\n cache-from: type=gha,scope=delivery\n cache-to: type=gha,scope=delivery,mode=max\n\n build-users:\n name: 🏗️ Build Users Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-users-service\n tags: |\n type=ref,event=branch\n type=sha,prefix={{branch}}-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/backend\n file: ./packages/backend/apps/users/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: runtime\n cache-from: type=gha,scope=users\n cache-to: type=gha,scope=users,mode=max\n\n deploy:\n name: 🚀 Deploy to Production\n runs-on: ubuntu-latest\n needs: [build-frontend, build-gateway, build-authentication, build-billing, build-stock, build-delivery, build-users]\n if: github.ref == 'refs/heads/main' && github.event_name == 'push'\n\n steps:\n - uses: actions/checkout@v4\n\n - uses: docker/login-action@v3\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n\n - name: 📋 Create production namespace & registry secret\n uses: appleboy/ssh-action@v0.1.7\n env:\n GHCR_USERNAME: ${{ github.actor }}\n GHCR_TOKEN: ${{ github.token }}\n with:\n host: ${{ secrets.VPS_HOST }}\n username: github-actions\n key: ${{ secrets.VPS_SSH_KEY }}\n port: 22\n envs: GHCR_USERNAME,GHCR_TOKEN\n script: |\n kubectl create namespace production --kubeconfig ~/.kube/config 2>/dev/null || true\n kubectl delete secret ghcr-secret -n production --kubeconfig ~/.kube/config 2>/dev/null || true\n kubectl create secret docker-registry ghcr-secret \\\n --docker-server=ghcr.io \\\n --docker-username=$GHCR_USERNAME \\\n --docker-password=$GHCR_TOKEN \\\n -n production \\\n --kubeconfig ~/.kube/config\n\n - name: 🚀 Transfer K8s manifests\n uses: appleboy/scp-action@v0.1.4\n with:\n host: ${{ secrets.VPS_HOST }}\n username: github-actions\n key: ${{ secrets.VPS_SSH_KEY }}\n port: 22\n source: 'kubernetes/'\n target: '/tmp/k8s-manifests'\n overwrite: true\n\n - name: ⚡ Apply manifests & rollout\n uses: appleboy/ssh-action@v0.1.7\n with:\n host: ${{ secrets.VPS_HOST }}\n username: github-actions\n key: ${{ secrets.VPS_SSH_KEY }}\n port: 22\n script: |\n kubectl apply -k /tmp/k8s-manifests/kubernetes --kubeconfig ~/.kube/config\n\n kubectl rollout restart deployment/transvirex-frontend -n production --kubeconfig ~/.kube/config\n kubectl rollout restart deployment/transvirex-gateway -n production --kubeconfig ~/.kube/config\n kubectl rollout restart deployment/transvirex-authentication -n production --kubeconfig ~/.kube/config\n kubectl rollout restart deployment/transvirex-billing -n production --kubeconfig ~/.kube/config\n kubectl rollout restart deployment/transvirex-stock -n production --kubeconfig ~/.kube/config\n kubectl rollout restart deployment/transvirex-delivery -n production --kubeconfig ~/.kube/config\n kubectl rollout restart deployment/transvirex-users -n production --kubeconfig ~/.kube/config\n\n kubectl rollout status deployment/transvirex-frontend -n production --timeout=5m --kubeconfig ~/.kube/config\n kubectl rollout status deployment/transvirex-gateway -n production --timeout=5m --kubeconfig ~/.kube/config\n kubectl rollout status deployment/transvirex-authentication -n production --timeout=5m --kubeconfig ~/.kube/config\n kubectl rollout status deployment/transvirex-billing -n production --timeout=5m --kubeconfig ~/.kube/config\n kubectl rollout status deployment/transvirex-stock -n production --timeout=5m --kubeconfig ~/.kube/config\n kubectl rollout status deployment/transvirex-delivery -n production --timeout=5m --kubeconfig ~/.kube/config\n kubectl rollout status deployment/transvirex-users -n production --timeout=5m --kubeconfig ~/.kube/config\n\n rm -rf /tmp/k8s-manifests\n\n notify:\n name: 📢 Notify\n runs-on: ubuntu-latest\n needs: [build-frontend, build-gateway, build-authentication, build-billing, build-stock, build-delivery, build-users, deploy]\n if: always()\n\n steps:\n - name: ✅ Notify Discord - Success\n if: ${{ !contains(needs.*.result, 'failure') && !contains(needs.*.result, 'cancelled') }}\n run: |\n curl -H \"Content-Type: application/json\" \\\n -d '{\n \"embeds\": [{\n \"title\": \"✅ Déploiement réussi\",\n \"color\": 3066993,\n \"fields\": [\n {\"name\": \"Repo\", \"value\": \"${{ github.repository }}\", \"inline\": true},\n {\"name\": \"Branche\", \"value\": \"${{ github.ref_name }}\", \"inline\": true},\n {\"name\": \"Commit\", \"value\": \"[`${{ github.sha }}`](${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }})\", \"inline\": false},\n {\"name\": \"Déclenché par\", \"value\": \"${{ github.actor }}\", \"inline\": true}\n ]\n }]\n }' \\\n ${{ secrets.DISCORD_WEBHOOK_URL }}\n\n - name: ❌ Notify Discord - Failure\n if: ${{ contains(needs.*.result, 'failure') }}\n run: |\n curl -H \"Content-Type: application/json\" \\\n -d '{\n \"embeds\": [{\n \"title\": \"❌ Déploiement échoué\",\n \"color\": 15158332,\n \"fields\": [\n {\"name\": \"Repo\", \"value\": \"${{ github.repository }}\", \"inline\": true},\n {\"name\": \"Branche\", \"value\": \"${{ github.ref_name }}\", \"inline\": true},\n {\"name\": \"Commit\", \"value\": \"[`${{ github.sha }}`](${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }})\", \"inline\": false},\n {\"name\": \"Déclenché par\", \"value\": \"${{ github.actor }}\", \"inline\": true},\n {\"name\": \"Logs\", \"value\": \"[${{ github.run_id }}](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})\", \"inline\": false}\n ]\n }]\n }' \\\n ${{ secrets.DISCORD_WEBHOOK_URL }}\n"}, "c4f4815a31f9f80be0d223e70be2835e4ef96728": {"t": 1785770089.7634997, "n": 16786, "h": "917b9e6caa020d27", "c": "name: 🚀 Build & Deploy\n\non:\n push:\n branches:\n - main\n - develop\n pull_request:\n branches:\n - main\n - develop\n\nenv:\n REGISTRY: ghcr.io\n\njobs:\n build-frontend:\n name: 🏗️ Build Frontend Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-frontend\n tags: |\n type=ref,event=branch\n type=sha,prefix={{branch}}-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/frontend\n file: ./packages/frontend/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: production\n cache-from: type=gha,scope=frontend\n cache-to: type=gha,scope=frontend,mode=max\n\n build-gateway:\n name: 🏗️ Build Gateway Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-gateway-service\n tags: |\n type=ref,event=branch\n type=sha,prefix={{branch}}-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/backend\n file: ./packages/backend/apps/gateway/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: runtime\n cache-from: type=gha,scope=gateway\n cache-to: type=gha,scope=gateway,mode=max\n\n build-authentication:\n name: 🏗️ Build Authentication Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-authentication-service\n tags: |\n type=ref,event=branch\n type=sha,prefix={{branch}}-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/backend\n file: ./packages/backend/apps/authentication/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: runtime\n cache-from: type=gha,scope=authentication\n cache-to: type=gha,scope=authentication,mode=max\n\n build-billing:\n name: 🏗️ Build Billing Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-billing-service\n tags: |\n type=ref,event=branch\n type=sha,prefix={{branch}}-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/backend\n file: ./packages/backend/apps/billing/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: runtime\n cache-from: type=gha,scope=billing\n cache-to: type=gha,scope=billing,mode=max\n\n build-stock:\n name: 🏗️ Build Stock Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-stock-service\n tags: |\n type=ref,event=branch\n type=sha,prefix={{branch}}-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/backend\n file: ./packages/backend/apps/stock/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: runtime\n cache-from: type=gha,scope=stock\n cache-to: type=gha,scope=stock,mode=max\n\n build-delivery:\n name: 🏗️ Build Delivery Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-delivery-service\n tags: |\n type=ref,event=branch\n type=sha,prefix={{branch}}-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/backend\n file: ./packages/backend/apps/delivery/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: runtime\n cache-from: type=gha,scope=delivery\n cache-to: type=gha,scope=delivery,mode=max\n\n build-users:\n name: 🏗️ Build Users Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-users-service\n tags: |\n type=ref,event=branch\n type=sha,prefix={{branch}}-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/backend\n file: ./packages/backend/apps/users/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: runtime\n cache-from: type=gha,scope=users\n cache-to: type=gha,scope=users,mode=max\n\n deploy:\n name: 🚀 Deploy to Production\n runs-on: ubuntu-latest\n needs: [build-frontend, build-gateway, build-authentication, build-billing, build-stock, build-delivery, build-users]\n if: github.ref == 'refs/heads/main' && github.event_name == 'push'\n\n steps:\n - uses: actions/checkout@v4\n\n - uses: docker/login-action@v3\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n\n - name: 📋 Create production namespace & registry secret\n uses: appleboy/ssh-action@v0.1.7\n with:\n host: ${{ secrets.VPS_HOST }}\n username: github-actions\n key: ${{ secrets.VPS_SSH_KEY }}\n port: 22\n envs: GITHUB_ACTOR,GITHUB_TOKEN\n script: |\n kubectl create namespace production --kubeconfig ~/.kube/config 2>/dev/null || true\n kubectl delete secret ghcr-secret -n production --kubeconfig ~/.kube/config 2>/dev/null || true\n kubectl create secret docker-registry ghcr-secret \\\n --docker-server=ghcr.io \\\n --docker-username=$GITHUB_ACTOR \\\n --docker-password=$GITHUB_TOKEN \\\n -n production \\\n --kubeconfig ~/.kube/config\n\n - name: 🚀 Transfer K8s manifests\n uses: appleboy/scp-action@v0.1.4\n with:\n host: ${{ secrets.VPS_HOST }}\n username: github-actions\n key: ${{ secrets.VPS_SSH_KEY }}\n port: 22\n source: 'kubernetes/'\n target: '/tmp/k8s-manifests'\n overwrite: true\n\n - name: ⚡ Apply manifests & rollout\n uses: appleboy/ssh-action@v0.1.7\n with:\n host: ${{ secrets.VPS_HOST }}\n username: github-actions\n key: ${{ secrets.VPS_SSH_KEY }}\n port: 22\n script: |\n kubectl apply -k /tmp/k8s-manifests/kubernetes --kubeconfig ~/.kube/config\n\n kubectl rollout restart deployment/transvirex-frontend -n production --kubeconfig ~/.kube/config\n kubectl rollout restart deployment/transvirex-gateway -n production --kubeconfig ~/.kube/config\n kubectl rollout restart deployment/transvirex-authentication -n production --kubeconfig ~/.kube/config\n kubectl rollout restart deployment/transvirex-billing -n production --kubeconfig ~/.kube/config\n kubectl rollout restart deployment/transvirex-stock -n production --kubeconfig ~/.kube/config\n kubectl rollout restart deployment/transvirex-delivery -n production --kubeconfig ~/.kube/config\n kubectl rollout restart deployment/transvirex-users -n production --kubeconfig ~/.kube/config\n\n kubectl rollout status deployment/transvirex-frontend -n production --timeout=5m --kubeconfig ~/.kube/config\n kubectl rollout status deployment/transvirex-gateway -n production --timeout=5m --kubeconfig ~/.kube/config\n kubectl rollout status deployment/transvirex-authentication -n production --timeout=5m --kubeconfig ~/.kube/config\n kubectl rollout status deployment/transvirex-billing -n production --timeout=5m --kubeconfig ~/.kube/config\n kubectl rollout status deployment/transvirex-stock -n production --timeout=5m --kubeconfig ~/.kube/config\n kubectl rollout status deployment/transvirex-delivery -n production --timeout=5m --kubeconfig ~/.kube/config\n kubectl rollout status deployment/transvirex-users -n production --timeout=5m --kubeconfig ~/.kube/config\n\n rm -rf /tmp/k8s-manifests\n\n notify:\n name: 📢 Notify\n runs-on: ubuntu-latest\n needs: [build-frontend, build-gateway, build-authentication, build-billing, build-stock, build-delivery, build-users, deploy]\n if: always()\n\n steps:\n - name: ✅ Notify Discord - Success\n if: ${{ !contains(needs.*.result, 'failure') && !contains(needs.*.result, 'cancelled') }}\n run: |\n curl -H \"Content-Type: application/json\" \\\n -d '{\n \"embeds\": [{\n \"title\": \"✅ Déploiement réussi\",\n \"color\": 3066993,\n \"fields\": [\n {\"name\": \"Repo\", \"value\": \"${{ github.repository }}\", \"inline\": true},\n {\"name\": \"Branche\", \"value\": \"${{ github.ref_name }}\", \"inline\": true},\n {\"name\": \"Commit\", \"value\": \"[`${{ github.sha }}`](${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }})\", \"inline\": false},\n {\"name\": \"Déclenché par\", \"value\": \"${{ github.actor }}\", \"inline\": true}\n ]\n }]\n }' \\\n ${{ secrets.DISCORD_WEBHOOK_URL }}\n\n - name: ❌ Notify Discord - Failure\n if: ${{ contains(needs.*.result, 'failure') }}\n run: |\n curl -H \"Content-Type: application/json\" \\\n -d '{\n \"embeds\": [{\n \"title\": \"❌ Déploiement échoué\",\n \"color\": 15158332,\n \"fields\": [\n {\"name\": \"Repo\", \"value\": \"${{ github.repository }}\", \"inline\": true},\n {\"name\": \"Branche\", \"value\": \"${{ github.ref_name }}\", \"inline\": true},\n {\"name\": \"Commit\", \"value\": \"[`${{ github.sha }}`](${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }})\", \"inline\": false},\n {\"name\": \"Déclenché par\", \"value\": \"${{ github.actor }}\", \"inline\": true},\n {\"name\": \"Logs\", \"value\": \"[${{ github.run_id }}](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})\", \"inline\": false}\n ]\n }]\n }' \\\n ${{ secrets.DISCORD_WEBHOOK_URL }}\n"}, "28965540bb61b85d5fe6f6025eb894f30ab8159f": {"t": 1785770091.1750884, "n": 16268, "h": "945104b51be76e4e", "c": "name: 🚀 Build & Deploy\n\non:\n push:\n branches:\n - main\n - develop\n pull_request:\n branches:\n - main\n - develop\n\nenv:\n REGISTRY: ghcr.io\n\njobs:\n build-frontend:\n name: 🏗️ Build Frontend Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-frontend\n tags: |\n type=ref,event=branch\n type=sha,prefix={{branch}}-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/frontend\n file: ./packages/frontend/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: production\n cache-from: type=gha,scope=frontend\n cache-to: type=gha,scope=frontend,mode=max\n\n build-gateway:\n name: 🏗️ Build Gateway Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-gateway-service\n tags: |\n type=ref,event=branch\n type=sha,prefix={{branch}}-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/backend\n file: ./packages/backend/apps/gateway/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: runtime\n cache-from: type=gha,scope=gateway\n cache-to: type=gha,scope=gateway,mode=max\n\n build-authentication:\n name: 🏗️ Build Authentication Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-authentication-service\n tags: |\n type=ref,event=branch\n type=sha,prefix={{branch}}-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/backend\n file: ./packages/backend/apps/authentication/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: runtime\n cache-from: type=gha,scope=authentication\n cache-to: type=gha,scope=authentication,mode=max\n\n build-billing:\n name: 🏗️ Build Billing Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-billing-service\n tags: |\n type=ref,event=branch\n type=sha,prefix={{branch}}-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/backend\n file: ./packages/backend/apps/billing/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: runtime\n cache-from: type=gha,scope=billing\n cache-to: type=gha,scope=billing,mode=max\n\n build-stock:\n name: 🏗️ Build Stock Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-stock-service\n tags: |\n type=ref,event=branch\n type=sha,prefix={{branch}}-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/backend\n file: ./packages/backend/apps/stock/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: runtime\n cache-from: type=gha,scope=stock\n cache-to: type=gha,scope=stock,mode=max\n\n build-delivery:\n name: 🏗️ Build Delivery Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-delivery-service\n tags: |\n type=ref,event=branch\n type=sha,prefix={{branch}}-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/backend\n file: ./packages/backend/apps/delivery/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: runtime\n cache-from: type=gha,scope=delivery\n cache-to: type=gha,scope=delivery,mode=max\n\n build-users:\n name: 🏗️ Build Users Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-users-service\n tags: |\n type=ref,event=branch\n type=sha,prefix={{branch}}-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/backend\n file: ./packages/backend/apps/users/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: runtime\n cache-from: type=gha,scope=users\n cache-to: type=gha,scope=users,mode=max\n\n deploy:\n name: 🚀 Deploy to Production\n runs-on: ubuntu-latest\n needs: [build-frontend, build-gateway, build-authentication, build-billing, build-stock, build-delivery, build-users]\n if: github.ref == 'refs/heads/main' && github.event_name == 'push'\n\n steps:\n - uses: actions/checkout@v4\n\n - uses: docker/login-action@v3\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n\n - name: 📋 Create production namespace\n uses: appleboy/ssh-action@v0.1.7\n with:\n host: ${{ secrets.VPS_HOST }}\n username: github-actions\n key: ${{ secrets.VPS_SSH_KEY }}\n port: 22\n script: |\n kubectl create namespace production --kubeconfig ~/.kube/config 2>/dev/null || true\n\n - name: 🚀 Transfer K8s manifests\n uses: appleboy/scp-action@v0.1.4\n with:\n host: ${{ secrets.VPS_HOST }}\n username: github-actions\n key: ${{ secrets.VPS_SSH_KEY }}\n port: 22\n source: 'kubernetes/'\n target: '/tmp/k8s-manifests'\n overwrite: true\n\n - name: ⚡ Apply manifests & rollout\n uses: appleboy/ssh-action@v0.1.7\n with:\n host: ${{ secrets.VPS_HOST }}\n username: github-actions\n key: ${{ secrets.VPS_SSH_KEY }}\n port: 22\n script: |\n kubectl apply -k /tmp/k8s-manifests/kubernetes --kubeconfig ~/.kube/config\n\n kubectl rollout restart deployment/transvirex-frontend -n production --kubeconfig ~/.kube/config\n kubectl rollout restart deployment/transvirex-gateway -n production --kubeconfig ~/.kube/config\n kubectl rollout restart deployment/transvirex-authentication -n production --kubeconfig ~/.kube/config\n kubectl rollout restart deployment/transvirex-billing -n production --kubeconfig ~/.kube/config\n kubectl rollout restart deployment/transvirex-stock -n production --kubeconfig ~/.kube/config\n kubectl rollout restart deployment/transvirex-delivery -n production --kubeconfig ~/.kube/config\n kubectl rollout restart deployment/transvirex-users -n production --kubeconfig ~/.kube/config\n\n kubectl rollout status deployment/transvirex-frontend -n production --timeout=5m --kubeconfig ~/.kube/config\n kubectl rollout status deployment/transvirex-gateway -n production --timeout=5m --kubeconfig ~/.kube/config\n kubectl rollout status deployment/transvirex-authentication -n production --timeout=5m --kubeconfig ~/.kube/config\n kubectl rollout status deployment/transvirex-billing -n production --timeout=5m --kubeconfig ~/.kube/config\n kubectl rollout status deployment/transvirex-stock -n production --timeout=5m --kubeconfig ~/.kube/config\n kubectl rollout status deployment/transvirex-delivery -n production --timeout=5m --kubeconfig ~/.kube/config\n kubectl rollout status deployment/transvirex-users -n production --timeout=5m --kubeconfig ~/.kube/config\n\n rm -rf /tmp/k8s-manifests\n\n notify:\n name: 📢 Notify\n runs-on: ubuntu-latest\n needs: [build-frontend, build-gateway, build-authentication, build-billing, build-stock, build-delivery, build-users, deploy]\n if: always()\n\n steps:\n - name: ✅ Notify Discord - Success\n if: ${{ !contains(needs.*.result, 'failure') && !contains(needs.*.result, 'cancelled') }}\n run: |\n curl -H \"Content-Type: application/json\" \\\n -d '{\n \"embeds\": [{\n \"title\": \"✅ Déploiement réussi\",\n \"color\": 3066993,\n \"fields\": [\n {\"name\": \"Repo\", \"value\": \"${{ github.repository }}\", \"inline\": true},\n {\"name\": \"Branche\", \"value\": \"${{ github.ref_name }}\", \"inline\": true},\n {\"name\": \"Commit\", \"value\": \"[`${{ github.sha }}`](${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }})\", \"inline\": false},\n {\"name\": \"Déclenché par\", \"value\": \"${{ github.actor }}\", \"inline\": true}\n ]\n }]\n }' \\\n ${{ secrets.DISCORD_WEBHOOK_URL }}\n\n - name: ❌ Notify Discord - Failure\n if: ${{ contains(needs.*.result, 'failure') }}\n run: |\n curl -H \"Content-Type: application/json\" \\\n -d '{\n \"embeds\": [{\n \"title\": \"❌ Déploiement échoué\",\n \"color\": 15158332,\n \"fields\": [\n {\"name\": \"Repo\", \"value\": \"${{ github.repository }}\", \"inline\": true},\n {\"name\": \"Branche\", \"value\": \"${{ github.ref_name }}\", \"inline\": true},\n {\"name\": \"Commit\", \"value\": \"[`${{ github.sha }}`](${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }})\", \"inline\": false},\n {\"name\": \"Déclenché par\", \"value\": \"${{ github.actor }}\", \"inline\": true},\n {\"name\": \"Logs\", \"value\": \"[${{ github.run_id }}](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})\", \"inline\": false}\n ]\n }]\n }' \\\n ${{ secrets.DISCORD_WEBHOOK_URL }}\n"}, "42f2801305539b3429e87eadc4a9481570c4d4d3": {"t": 1785770092.6156876, "n": 14340, "h": "ad8458094247dae0", "c": "name: 🚀 Build & Deploy\n\non:\n push:\n branches:\n - main\n - develop\n pull_request:\n branches:\n - main\n - develop\n\nenv:\n REGISTRY: ghcr.io\n\njobs:\n build-frontend:\n name: 🏗️ Build Frontend Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-frontend\n tags: |\n type=ref,event=branch\n type=sha,prefix={{branch}}-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/frontend\n file: ./packages/frontend/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: production\n cache-from: type=gha,scope=frontend\n cache-to: type=gha,scope=frontend,mode=max\n\n build-gateway:\n name: 🏗️ Build Gateway Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-gateway-service\n tags: |\n type=ref,event=branch\n type=sha,prefix={{branch}}-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/backend\n file: ./packages/backend/apps/gateway/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: runtime\n cache-from: type=gha,scope=gateway\n cache-to: type=gha,scope=gateway,mode=max\n\n build-authentication:\n name: 🏗️ Build Authentication Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-authentication-service\n tags: |\n type=ref,event=branch\n type=sha,prefix={{branch}}-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/backend\n file: ./packages/backend/apps/authentication/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: runtime\n cache-from: type=gha,scope=authentication\n cache-to: type=gha,scope=authentication,mode=max\n\n build-billing:\n name: 🏗️ Build Billing Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-billing-service\n tags: |\n type=ref,event=branch\n type=sha,prefix={{branch}}-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/backend\n file: ./packages/backend/apps/billing/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: runtime\n cache-from: type=gha,scope=billing\n cache-to: type=gha,scope=billing,mode=max\n\n build-stock:\n name: 🏗️ Build Stock Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-stock-service\n tags: |\n type=ref,event=branch\n type=sha,prefix={{branch}}-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/backend\n file: ./packages/backend/apps/stock/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: runtime\n cache-from: type=gha,scope=stock\n cache-to: type=gha,scope=stock,mode=max\n\n build-delivery:\n name: 🏗️ Build Delivery Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-delivery-service\n tags: |\n type=ref,event=branch\n type=sha,prefix={{branch}}-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/backend\n file: ./packages/backend/apps/delivery/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: runtime\n cache-from: type=gha,scope=delivery\n cache-to: type=gha,scope=delivery,mode=max\n\n build-users:\n name: 🏗️ Build Users Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n steps:\n - uses: actions/checkout@v4\n - uses: docker/setup-buildx-action@v3\n - uses: docker/login-action@v3\n if: github.event_name != 'pull_request'\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n - id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-users-service\n tags: |\n type=ref,event=branch\n type=sha,prefix={{branch}}-\n type=raw,value=latest,enable={{is_default_branch}}\n - uses: docker/build-push-action@v5\n with:\n context: ./packages/backend\n file: ./packages/backend/apps/users/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: runtime\n cache-from: type=gha,scope=users\n cache-to: type=gha,scope=users,mode=max\n\n deploy:\n name: 🚀 Deploy to Production\n runs-on: ubuntu-latest\n needs: [build-frontend, build-gateway, build-authentication, build-billing, build-stock, build-delivery, build-users]\n if: github.ref == 'refs/heads/main' && github.event_name == 'push'\n\n steps:\n - uses: actions/checkout@v4\n\n - uses: docker/login-action@v3\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n\n - name: 📋 Create production namespace\n uses: appleboy/ssh-action@v0.1.7\n with:\n host: ${{ secrets.VPS_HOST }}\n username: github-actions\n key: ${{ secrets.VPS_SSH_KEY }}\n port: 22\n script: |\n kubectl create namespace production --kubeconfig ~/.kube/config 2>/dev/null || true\n\n - name: 🚀 Transfer K8s manifests\n uses: appleboy/scp-action@v0.1.4\n with:\n host: ${{ secrets.VPS_HOST }}\n username: github-actions\n key: ${{ secrets.VPS_SSH_KEY }}\n port: 22\n source: 'kubernetes/'\n target: '/tmp/k8s-manifests'\n overwrite: true\n\n - name: ⚡ Apply manifests & rollout\n uses: appleboy/ssh-action@v0.1.7\n with:\n host: ${{ secrets.VPS_HOST }}\n username: github-actions\n key: ${{ secrets.VPS_SSH_KEY }}\n port: 22\n script: |\n kubectl apply -k /tmp/k8s-manifests/kubernetes --kubeconfig ~/.kube/config\n\n kubectl rollout restart deployment/transvirex-frontend -n production --kubeconfig ~/.kube/config\n kubectl rollout restart deployment/transvirex-gateway -n production --kubeconfig ~/.kube/config\n kubectl rollout restart deployment/transvirex-authentication -n production --kubeconfig ~/.kube/config\n kubectl rollout restart deployment/transvirex-billing -n production --kubeconfig ~/.kube/config\n kubectl rollout restart deployment/transvirex-stock -n production --kubeconfig ~/.kube/config\n kubectl rollout restart deployment/transvirex-delivery -n production --kubeconfig ~/.kube/config\n kubectl rollout restart deployment/transvirex-users -n production --kubeconfig ~/.kube/config\n\n kubectl rollout status deployment/transvirex-frontend -n production --timeout=5m --kubeconfig ~/.kube/config\n kubectl rollout status deployment/transvirex-gateway -n production --timeout=5m --kubeconfig ~/.kube/config\n kubectl rollout status deployment/transvirex-authentication -n production --timeout=5m --kubeconfig ~/.kube/config\n kubectl rollout status deployment/transvirex-billing -n production --timeout=5m --kubeconfig ~/.kube/config\n kubectl rollout status deployment/transvirex-stock -n production --timeout=5m --kubeconfig ~/.kube/config\n kubectl rollout status deployment/transvirex-delivery -n production --timeout=5m --kubeconfig ~/.kube/config\n kubectl rollout status deployment/transvirex-users -n production --timeout=5m --kubeconfig ~/.kube/config\n\n rm -rf /tmp/k8s-manifests\n\n notify:\n name: 📢 Notify\n runs-on: ubuntu-latest\n needs: [build-frontend, build-gateway, build-authentication, build-billing, build-stock, build-delivery, build-users, deploy]\n if: always()\n\n steps:\n - name: ✅ Success\n if: success()\n run: echo \"✅ Pipeline completed successfully!\"\n\n - name: ❌ Failure\n if: failure()\n run: |\n echo \"❌ Pipeline failed!\"\n exit 1\n"}, "c80be60f57a86c3c00b8a4e3e4f1fa840aefcce3": {"t": 1785770094.0598216, "n": 6691, "h": "458bdc968df3b702", "c": "name: 🚀 Build & Deploy\n\non:\n push:\n branches:\n - main\n - develop\n pull_request:\n branches:\n - main\n - develop\n\nenv:\n REGISTRY: ghcr.io\n\njobs:\n build-frontend:\n name: 🏗️ Build Frontend Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n\n steps:\n - name: 📥 Checkout code\n uses: actions/checkout@v4\n\n - name: 🐳 Set up Docker Buildx\n uses: docker/setup-buildx-action@v3\n\n - name: 🔐 Log in to Container Registry\n if: github.event_name != 'pull_request'\n uses: docker/login-action@v3\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n\n - name: 📝 Extract metadata\n id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-frontend\n tags: |\n type=ref,event=branch\n type=semver,pattern={{version}}\n type=semver,pattern={{major}}.{{minor}}\n type=sha,prefix={{branch}}-\n type=raw,value=latest,enable={{is_default_branch}}\n labels: |\n org.opencontainers.image.source=${{ github.server_url }}/${{ github.repository }}\n\n - name: 🏗️ Build and push image\n uses: docker/build-push-action@v5\n with:\n context: ./packages/frontend\n file: ./packages/frontend/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: production\n cache-from: type=gha\n cache-to: type=gha,mode=max\n\n build-gateway:\n name: 🏗️ Build Gateway Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n\n steps:\n - name: 📥 Checkout code\n uses: actions/checkout@v4\n\n - name: 🐳 Set up Docker Buildx\n uses: docker/setup-buildx-action@v3\n\n - name: 🔐 Log in to Container Registry\n if: github.event_name != 'pull_request'\n uses: docker/login-action@v3\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n\n - name: 📝 Extract metadata\n id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-gateway-service\n tags: |\n type=ref,event=branch\n type=semver,pattern={{version}}\n type=semver,pattern={{major}}.{{minor}}\n type=sha,prefix={{branch}}-\n type=raw,value=latest,enable={{is_default_branch}}\n labels: |\n org.opencontainers.image.source=${{ github.server_url }}/${{ github.repository }}\n\n - name: 🏗️ Build and push image\n uses: docker/build-push-action@v5\n with:\n context: ./packages/backend\n file: ./packages/backend/apps/gateway/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: runtime\n cache-from: type=gha\n cache-to: type=gha,mode=max\n\n deploy:\n name: 🚀 Deploy to Production\n runs-on: ubuntu-latest\n needs: [build-frontend, build-gateway]\n if: github.ref == 'refs/heads/main' && github.event_name == 'push'\n\n steps:\n - name: 📥 Checkout code\n uses: actions/checkout@v4\n\n - name: 🔑 Login to GHCR\n uses: docker/login-action@v3\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n\n - name: 📋 Create production namespace\n uses: appleboy/ssh-action@v0.1.7\n with:\n host: ${{ secrets.VPS_HOST }}\n username: github-actions\n key: ${{ secrets.VPS_SSH_KEY }}\n port: 22\n script: |\n kubectl create namespace production --kubeconfig ~/.kube/config 2>/dev/null || true\n\n - name: 🚀 Transfer K8s manifests\n uses: appleboy/scp-action@v0.1.4\n with:\n host: ${{ secrets.VPS_HOST }}\n username: github-actions\n key: ${{ secrets.VPS_SSH_KEY }}\n port: 22\n source: 'kubernetes/'\n target: '/tmp/k8s-manifests'\n overwrite: true\n\n - name: ⚡ Apply manifests & rollout\n uses: appleboy/ssh-action@v0.1.7\n with:\n host: ${{ secrets.VPS_HOST }}\n username: github-actions\n key: ${{ secrets.VPS_SSH_KEY }}\n port: 22\n script: |\n kubectl apply -k /tmp/k8s-manifests/kubernetes --kubeconfig ~/.kube/config\n\n kubectl rollout restart deployment/transvirex-frontend -n production --kubeconfig ~/.kube/config\n kubectl rollout restart deployment/transvirex-gateway -n production --kubeconfig ~/.kube/config\n\n kubectl rollout status deployment/transvirex-frontend -n production --timeout=5m --kubeconfig ~/.kube/config\n kubectl rollout status deployment/transvirex-gateway -n production --timeout=5m --kubeconfig ~/.kube/config\n\n rm -rf /tmp/k8s-manifests\n\n notify:\n name: 📢 Notify\n runs-on: ubuntu-latest\n needs: [build-frontend, build-gateway, deploy]\n if: always()\n\n steps:\n - name: ✅ Success\n if: success()\n run: echo \"✅ Pipeline completed successfully!\"\n\n - name: ❌ Failure\n if: failure()\n run: |\n echo \"❌ Pipeline failed!\"\n exit 1\n"}, "8efc02aef7e9993818de38a9843587654cd72191": {"t": 1785770095.450111, "n": 6694, "h": "32891abe5e631f2e", "c": "name: 🚀 Build & Deploy\n\non:\n push:\n branches:\n - main\n - develop\n pull_request:\n branches:\n - main\n - develop\n\nenv:\n REGISTRY: ghcr.io\n\njobs:\n build-frontend:\n name: 🏗️ Build Frontend Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n\n steps:\n - name: 📥 Checkout code\n uses: actions/checkout@v4\n\n - name: 🐳 Set up Docker Buildx\n uses: docker/setup-buildx-action@v3\n\n - name: 🔐 Log in to Container Registry\n if: github.event_name != 'pull_request'\n uses: docker/login-action@v3\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n\n - name: 📝 Extract metadata\n id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-frontend\n tags: |\n type=ref,event=branch\n type=semver,pattern={{version}}\n type=semver,pattern={{major}}.{{minor}}\n type=sha,prefix={{branch}}-\n type=raw,value=latest,enable={{is_default_branch}}\n labels: |\n org.opencontainers.image.source=${{ github.server_url }}/${{ github.repository }}\n\n - name: 🏗️ Build and push image\n uses: docker/build-push-action@v5\n with:\n context: ./packages/frontend\n file: ./packages/frontend/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: production\n cache-from: type=gha\n cache-to: type=gha,mode=max\n\n build-gateway:\n name: 🏗️ Build Gateway Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n\n steps:\n - name: 📥 Checkout code\n uses: actions/checkout@v4\n\n - name: 🐳 Set up Docker Buildx\n uses: docker/setup-buildx-action@v3\n\n - name: 🔐 Log in to Container Registry\n if: github.event_name != 'pull_request'\n uses: docker/login-action@v3\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n\n - name: 📝 Extract metadata\n id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/transvirex-gateway-service\n tags: |\n type=ref,event=branch\n type=semver,pattern={{version}}\n type=semver,pattern={{major}}.{{minor}}\n type=sha,prefix={{branch}}-\n type=raw,value=latest,enable={{is_default_branch}}\n labels: |\n org.opencontainers.image.source=${{ github.server_url }}/${{ github.repository }}\n\n - name: 🏗️ Build and push image\n uses: docker/build-push-action@v5\n with:\n context: ./packages/backend\n file: ./packages/backend/apps/gateway/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: production\n cache-from: type=gha\n cache-to: type=gha,mode=max\n\n deploy:\n name: 🚀 Deploy to Production\n runs-on: ubuntu-latest\n needs: [build-frontend, build-gateway]\n if: github.ref == 'refs/heads/main' && github.event_name == 'push'\n\n steps:\n - name: 📥 Checkout code\n uses: actions/checkout@v4\n\n - name: 🔑 Login to GHCR\n uses: docker/login-action@v3\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n\n - name: 📋 Create production namespace\n uses: appleboy/ssh-action@v0.1.7\n with:\n host: ${{ secrets.VPS_HOST }}\n username: github-actions\n key: ${{ secrets.VPS_SSH_KEY }}\n port: 22\n script: |\n kubectl create namespace production --kubeconfig ~/.kube/config 2>/dev/null || true\n\n - name: 🚀 Transfer K8s manifests\n uses: appleboy/scp-action@v0.1.4\n with:\n host: ${{ secrets.VPS_HOST }}\n username: github-actions\n key: ${{ secrets.VPS_SSH_KEY }}\n port: 22\n source: 'kubernetes/'\n target: '/tmp/k8s-manifests'\n overwrite: true\n\n - name: ⚡ Apply manifests & rollout\n uses: appleboy/ssh-action@v0.1.7\n with:\n host: ${{ secrets.VPS_HOST }}\n username: github-actions\n key: ${{ secrets.VPS_SSH_KEY }}\n port: 22\n script: |\n kubectl apply -k /tmp/k8s-manifests/kubernetes --kubeconfig ~/.kube/config\n\n kubectl rollout restart deployment/transvirex-frontend -n production --kubeconfig ~/.kube/config\n kubectl rollout restart deployment/transvirex-gateway -n production --kubeconfig ~/.kube/config\n\n kubectl rollout status deployment/transvirex-frontend -n production --timeout=5m --kubeconfig ~/.kube/config\n kubectl rollout status deployment/transvirex-gateway -n production --timeout=5m --kubeconfig ~/.kube/config\n\n rm -rf /tmp/k8s-manifests\n\n notify:\n name: 📢 Notify\n runs-on: ubuntu-latest\n needs: [build-frontend, build-gateway, deploy]\n if: always()\n\n steps:\n - name: ✅ Success\n if: success()\n run: echo \"✅ Pipeline completed successfully!\"\n\n - name: ❌ Failure\n if: failure()\n run: |\n echo \"❌ Pipeline failed!\"\n exit 1\n"}, "645800b982bfebc37fc7382b43b8458bfe3ba43c": {"t": 1785770096.8779361, "n": 4644, "h": "d44e744a723d13b1", "c": "name: 🚀 Build & Deploy\n\non:\n push:\n branches:\n - main\n - develop\n pull_request:\n branches:\n - main\n - develop\n\nenv:\n REGISTRY: ghcr.io\n IMAGE_NAME: ${{ github.repository_owner }}/transvirex-frontend\n\njobs:\n build:\n name: 🏗️ Build Docker Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n\n steps:\n - name: 📥 Checkout code\n uses: actions/checkout@v4\n\n - name: 🐳 Set up Docker Buildx\n uses: docker/setup-buildx-action@v3\n\n - name: 🔐 Log in to Container Registry\n if: github.event_name != 'pull_request'\n uses: docker/login-action@v3\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n\n - name: 📝 Extract metadata\n id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}\n tags: |\n type=ref,event=branch\n type=semver,pattern={{version}}\n type=semver,pattern={{major}}.{{minor}}\n type=sha,prefix={{branch}}-\n type=raw,value=latest,enable={{is_default_branch}}\n labels: |\n org.opencontainers.image.source=${{ github.server_url }}/${{ github.repository }}\n\n - name: 🏗️ Build and push image\n uses: docker/build-push-action@v5\n with:\n context: ./packages/frontend\n file: ./packages/frontend/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n target: production\n cache-from: type=gha\n cache-to: type=gha,mode=max\n\n deploy:\n name: 🚀 Deploy to Production\n runs-on: ubuntu-latest\n needs: [build]\n if: github.ref == 'refs/heads/main' && github.event_name == 'push'\n\n steps:\n - name: 📥 Checkout code\n uses: actions/checkout@v4\n\n - name: 🔑 Login to GHCR\n uses: docker/login-action@v3\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n\n - name: 📋 Create production namespace\n uses: appleboy/ssh-action@v0.1.7\n with:\n host: ${{ secrets.VPS_HOST }}\n username: github-actions\n key: ${{ secrets.VPS_SSH_KEY }}\n port: 22\n script: |\n kubectl create namespace production --kubeconfig ~/.kube/config 2>/dev/null || true\n\n - name: 🚀 Transfer K8s manifests\n uses: appleboy/scp-action@v0.1.4\n with:\n host: ${{ secrets.VPS_HOST }}\n username: github-actions\n key: ${{ secrets.VPS_SSH_KEY }}\n port: 22\n source: 'kubernetes/'\n target: '/tmp/k8s-manifests'\n overwrite: true\n\n - name: ⚡ Apply manifests & rollout\n uses: appleboy/ssh-action@v0.1.7\n with:\n host: ${{ secrets.VPS_HOST }}\n username: github-actions\n key: ${{ secrets.VPS_SSH_KEY }}\n port: 22\n script: |\n kubectl apply -k /tmp/k8s-manifests/kubernetes --kubeconfig ~/.kube/config\n\n # ✅ Fix 4 : force le pull de la nouvelle image même avec le tag latest\n kubectl rollout restart deployment/transvirex-frontend -n production --kubeconfig ~/.kube/config\n\n kubectl rollout status deployment/transvirex-frontend -n production --timeout=5m --kubeconfig ~/.kube/config\n\n rm -rf /tmp/k8s-manifests\n\n notify:\n name: 📢 Notify\n runs-on: ubuntu-latest\n needs: [build, deploy]\n if: always()\n\n steps:\n - name: ✅ Success\n if: success()\n run: echo \"✅ Pipeline completed successfully!\"\n\n - name: ❌ Failure\n if: failure()\n run: |\n echo \"❌ Pipeline failed!\"\n exit 1\n"}, "47d4a07f5ecb99d44bb80dbe0b1b53b3059441fb": {"t": 1785770098.185007, "n": 4607, "h": "4b7ddbd00d039087", "c": "name: 🚀 Build & Deploy\n\non:\n push:\n branches:\n - main\n - develop\n pull_request:\n branches:\n - main\n - develop\n\nenv:\n REGISTRY: ghcr.io\n IMAGE_NAME: ${{ github.repository_owner }}/transvirex-frontend\n\njobs:\n build:\n name: 🏗️ Build Docker Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n\n steps:\n - name: 📥 Checkout code\n uses: actions/checkout@v4\n\n - name: 🐳 Set up Docker Buildx\n uses: docker/setup-buildx-action@v3\n\n - name: 🔐 Log in to Container Registry\n if: github.event_name != 'pull_request'\n uses: docker/login-action@v3\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n\n - name: 📝 Extract metadata\n id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}\n tags: |\n type=ref,event=branch\n type=semver,pattern={{version}}\n type=semver,pattern={{major}}.{{minor}}\n type=sha,prefix={{branch}}-\n type=raw,value=latest,enable={{is_default_branch}}\n labels: |\n org.opencontainers.image.source=${{ github.server_url }}/${{ github.repository }}\n\n - name: 🏗️ Build and push image\n uses: docker/build-push-action@v5\n with:\n context: ./packages/frontend\n file: ./packages/frontend/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n cache-from: type=gha\n cache-to: type=gha,mode=max\n\n deploy:\n name: 🚀 Deploy to Production\n runs-on: ubuntu-latest\n needs: [build]\n if: github.ref == 'refs/heads/main' && github.event_name == 'push'\n\n steps:\n - name: 📥 Checkout code\n uses: actions/checkout@v4\n\n - name: 🔑 Login to GHCR\n uses: docker/login-action@v3\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n\n - name: 📋 Create production namespace\n uses: appleboy/ssh-action@v0.1.7\n with:\n host: ${{ secrets.VPS_HOST }}\n username: github-actions\n key: ${{ secrets.VPS_SSH_KEY }}\n port: 22\n script: |\n kubectl create namespace production --kubeconfig ~/.kube/config 2>/dev/null || true\n\n - name: 🚀 Transfer K8s manifests\n uses: appleboy/scp-action@v0.1.4\n with:\n host: ${{ secrets.VPS_HOST }}\n username: github-actions\n key: ${{ secrets.VPS_SSH_KEY }}\n port: 22\n source: 'kubernetes/'\n target: '/tmp/k8s-manifests'\n overwrite: true\n\n - name: ⚡ Apply manifests & rollout\n uses: appleboy/ssh-action@v0.1.7\n with:\n host: ${{ secrets.VPS_HOST }}\n username: github-actions\n key: ${{ secrets.VPS_SSH_KEY }}\n port: 22\n script: |\n kubectl apply -k /tmp/k8s-manifests/kubernetes --kubeconfig ~/.kube/config\n\n # ✅ Fix 4 : force le pull de la nouvelle image même avec le tag latest\n kubectl rollout restart deployment/transvirex-frontend -n production --kubeconfig ~/.kube/config\n\n kubectl rollout status deployment/transvirex-frontend -n production --timeout=5m --kubeconfig ~/.kube/config\n\n rm -rf /tmp/k8s-manifests\n\n notify:\n name: 📢 Notify\n runs-on: ubuntu-latest\n needs: [build, deploy]\n if: always()\n\n steps:\n - name: ✅ Success\n if: success()\n run: echo \"✅ Pipeline completed successfully!\"\n\n - name: ❌ Failure\n if: failure()\n run: |\n echo \"❌ Pipeline failed!\"\n exit 1\n"}, "8a8a573757c131d34aed4ca9da13c5c0d91a5eae": {"t": 1785770099.7932878, "n": 4597, "h": "865ce31593a37701", "c": "name: 🚀 Build & Deploy\n\non:\n push:\n branches:\n - main\n - develop\n pull_request:\n branches:\n - main\n - develop\n\nenv:\n REGISTRY: ghcr.io\n IMAGE_NAME: ${{ github.repository_owner }}/transvirex-frontend\n\njobs:\n build:\n name: 🏗️ Build Docker Image\n runs-on: ubuntu-latest\n permissions:\n contents: read\n packages: write\n\n steps:\n - name: 📥 Checkout code\n uses: actions/checkout@v4\n\n - name: 🐳 Set up Docker Buildx\n uses: docker/setup-buildx-action@v3\n\n - name: 🔐 Log in to Container Registry\n if: github.event_name != 'pull_request'\n uses: docker/login-action@v3\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n\n - name: 📝 Extract metadata\n id: meta\n uses: docker/metadata-action@v5\n with:\n images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}\n tags: |\n type=ref,event=branch\n type=semver,pattern={{version}}\n type=semver,pattern={{major}}.{{minor}}\n type=sha,prefix={{branch}}-\n type=raw,value=latest,enable={{is_default_branch}}\n labels: |\n org.opencontainers.image.source=${{ github.server_url }}/${{ github.repository }}\n\n - name: 🏗️ Build and push image\n uses: docker/build-push-action@v5\n with:\n context: ./src/frontend\n file: ./src/frontend/Dockerfile\n push: ${{ github.event_name != 'pull_request' }}\n tags: ${{ steps.meta.outputs.tags }}\n labels: ${{ steps.meta.outputs.labels }}\n cache-from: type=gha\n cache-to: type=gha,mode=max\n\n deploy:\n name: 🚀 Deploy to Production\n runs-on: ubuntu-latest\n needs: [build]\n if: github.ref == 'refs/heads/main' && github.event_name == 'push'\n\n steps:\n - name: 📥 Checkout code\n uses: actions/checkout@v4\n\n - name: 🔑 Login to GHCR\n uses: docker/login-action@v3\n with:\n registry: ${{ env.REGISTRY }}\n username: ${{ github.actor }}\n password: ${{ secrets.GITHUB_TOKEN }}\n\n - name: 📋 Create production namespace\n uses: appleboy/ssh-action@v0.1.7\n with:\n host: ${{ secrets.VPS_HOST }}\n username: github-actions\n key: ${{ secrets.VPS_SSH_KEY }}\n port: 22\n script: |\n kubectl create namespace production --kubeconfig ~/.kube/config 2>/dev/null || true\n\n - name: 🚀 Transfer K8s manifests\n uses: appleboy/scp-action@v0.1.4\n with:\n host: ${{ secrets.VPS_HOST }}\n username: github-actions\n key: ${{ secrets.VPS_SSH_KEY }}\n port: 22\n source: 'kubernetes/'\n target: '/tmp/k8s-manifests'\n overwrite: true\n\n - name: ⚡ Apply manifests & rollout\n uses: appleboy/ssh-action@v0.1.7\n with:\n host: ${{ secrets.VPS_HOST }}\n username: github-actions\n key: ${{ secrets.VPS_SSH_KEY }}\n port: 22\n script: |\n kubectl apply -k /tmp/k8s-manifests/kubernetes --kubeconfig ~/.kube/config\n\n # ✅ Fix 4 : force le pull de la nouvelle image même avec le tag latest\n kubectl rollout restart deployment/transvirex-frontend -n production --kubeconfig ~/.kube/config\n\n kubectl rollout status deployment/transvirex-frontend -n production --timeout=5m --kubeconfig ~/.kube/config\n\n rm -rf /tmp/k8s-manifests\n\n notify:\n name: 📢 Notify\n runs-on: ubuntu-latest\n needs: [build, deploy]\n if: always()\n\n steps:\n - name: ✅ Success\n if: success()\n run: echo \"✅ Pipeline completed successfully!\"\n\n - name: ❌ Failure\n if: failure()\n run: |\n echo \"❌ Pipeline failed!\"\n exit 1\n"}}}}