name: CI/CD - Build, Push, Deploy (Ghaymah) # يعمل تلقائيًا عند الدفع لفرع main، أو يدويًا لأي فرع/بيئة عبر workflow_dispatch on: push: branches: ["main"] workflow_dispatch: inputs: image_tag: description: "وسم اختياري إضافي للصورة (افتراضيًا: git SHA)" required: false default: "" # صلاحيات أقل ما يمكن (least privilege) permissions: contents: read packages: write env: # عنوان سجل الحاويات الخاص بغيمة - عدّله حسب مشروعك GHAYMAH_REGISTRY: registry.ghaymah.systems GHAYMAH_NAMESPACE: my-team IMAGE_NAME: sample-api jobs: # --------------------------------------------------------------------- # 1) بناء الصورة واختبارها ورفعها إلى Ghaymah Container Registry # --------------------------------------------------------------------- build-and-push: name: Build & Push Image runs-on: ubuntu-latest outputs: image_ref: ${{ steps.vars.outputs.image_ref }} steps: - name: Checkout code uses: actions/checkout@v4 - name: Set image tag variables id: vars run: | SHORT_SHA=$(echo "${GITHUB_SHA}" | cut -c1-7) TAG="${{ github.event.inputs.image_tag }}" if [ -z "$TAG" ]; then TAG="$SHORT_SHA"; fi IMAGE_REF="${GHAYMAH_REGISTRY}/${GHAYMAH_NAMESPACE}/${IMAGE_NAME}:${TAG}" echo "image_ref=${IMAGE_REF}" >> "$GITHUB_OUTPUT" echo "Building: ${IMAGE_REF}" - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 # تسجيل الدخول إلى سجل حاويات غيمة عبر بيانات اعتماد مخزّنة كـ GitHub Secrets - name: Log in to Ghaymah Container Registry uses: docker/login-action@v3 with: registry: ${{ env.GHAYMAH_REGISTRY }} username: ${{ secrets.GHAYMAH_REGISTRY_USER }} password: ${{ secrets.GHAYMAH_REGISTRY_TOKEN }} - name: Build image uses: docker/build-push-action@v6 with: context: . push: false load: true tags: | ${{ steps.vars.outputs.image_ref }} ${{ env.GHAYMAH_REGISTRY }}/${{ env.GHAYMAH_NAMESPACE }}/${{ env.IMAGE_NAME }}:latest cache-from: type=gha cache-to: type=gha,mode=max # اختبار سريع للتأكد أن /health يستجيب قبل الرفع للسجل (بوابة جودة أساسية) - name: Smoke test the built image run: | docker run -d --name smoke -p 8080:8080 ${{ steps.vars.outputs.image_ref }} for i in $(seq 1 10); do if curl -sf http://localhost:8080/health; then echo "Health check passed"; break; fi echo "Waiting for app to start... ($i/10)"; sleep 2 done curl -sf http://localhost:8080/health || (docker logs smoke && exit 1) docker stop smoke - name: Push image to Ghaymah Registry uses: docker/build-push-action@v6 with: context: . push: true tags: | ${{ steps.vars.outputs.image_ref }} ${{ env.GHAYMAH_REGISTRY }}/${{ env.GHAYMAH_NAMESPACE }}/${{ env.IMAGE_NAME }}:latest # --------------------------------------------------------------------- # 2) نشر تلقائي على STAGING فور نجاح البناء - بدون موافقة يدوية # --------------------------------------------------------------------- deploy-staging: name: Deploy to Staging needs: build-and-push runs-on: ubuntu-latest environment: name: staging url: https://sample-api-staging.ghaymah.systems steps: - name: Install Ghaymah CLI run: | curl -fsSL https://cli.ghaymah.systems/install.sh | sh ghaymah --version - name: Authenticate Ghaymah CLI run: ghaymah auth login --token "${{ secrets.GHAYMAH_API_TOKEN }}" - name: Deploy image to staging service run: | ghaymah deploy \ --service sample-api-staging \ --image "${{ needs.build-and-push.outputs.image_ref }}" \ --env staging \ --wait - name: Verify staging health run: | curl -sf https://sample-api-staging.ghaymah.systems/health # --------------------------------------------------------------------- # 3) نشر على PRODUCTION - يتطلب موافقة يدوية (Manual Approval) # الموافقة تُنفَّذ عبر GitHub Environment "production" المحمي بمراجعين # مطلوبين (Required Reviewers) من إعدادات المستودع، وليس بكود مخصص. # --------------------------------------------------------------------- deploy-production: name: Deploy to Production (Manual Approval Required) needs: [build-and-push, deploy-staging] runs-on: ubuntu-latest environment: name: production # <-- هذا السطر يفعّل بوابة الموافقة اليدوية المضبوطة في إعدادات المستودع url: https://sample-api.ghaymah.systems steps: - name: Install Ghaymah CLI run: | curl -fsSL https://cli.ghaymah.systems/install.sh | sh ghaymah --version - name: Authenticate Ghaymah CLI run: ghaymah auth login --token "${{ secrets.GHAYMAH_API_TOKEN }}" - name: Deploy image to production service run: | ghaymah deploy \ --service sample-api-production \ --image "${{ needs.build-and-push.outputs.image_ref }}" \ --env production \ --strategy rolling \ --wait - name: Verify production health run: | curl -sf https://sample-api.ghaymah.systems/health - name: Post-deploy smoke check on /metrics run: | curl -sf https://sample-api.ghaymah.systems/metrics