From 62531c6bb98461305f63fa3ad72563ac6e3b6d99 Mon Sep 17 00:00:00 2001 From: ahmedgamalyousef Date: Tue, 7 Oct 2025 23:44:38 +0300 Subject: [PATCH] vv --- .github/workflows/cicd.yaml | 288 +++++++++++++++++------------------- 1 file changed, 139 insertions(+), 149 deletions(-) diff --git a/.github/workflows/cicd.yaml b/.github/workflows/cicd.yaml index 29d10da..a998fda 100644 --- a/.github/workflows/cicd.yaml +++ b/.github/workflows/cicd.yaml @@ -1,132 +1,152 @@ +name: Deploy to Ghaymah Cloud + on: push: - pull_request: - + branches: [ main, master ] + workflow_dispatch: # Allow manual triggers + inputs: + project_name: + description: 'Ghaymah Project Name' + required: true + default: '' + app_name: + description: 'App Name' + required: true + default: '' + +env: + DOCKER_USERNAME: 'ahmedgamalyousef' + jobs: - build_and_push_image: - steps: - - name: checkout code - uses: actions/checkout@v5.0.0 - - - name: login to dockerhub - uses: docker/login-action@v3.6.0 - with: - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_TOKEN }} - - - name: Build and push - uses: docker/build-push-action@v6 - with: - context: . - push: true - tags: ahmedgamalyousef/weatherapp:latest - - deploy: - needs: build_and_push_image - env: - PROJECT_NAME: ${{ github.event.repository.name }}-project - APP_NAME: ${{ github.event.repository.name }} - DOCKER_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }} - IMAGE_NAME: ${{ github.event.repository.name }} - IMAGE_TAG: latest - APP_PORT: 5000 - - steps: - - name: Checkout code - uses: actions/checkout@v5.0.0 + build-and-deploy: + name: Build and Deploy to Ghaymah + # runs-on: ubuntu-latest + steps: + # Step 1: Checkout code + - name: Checkout repository + uses: actions/checkout@v4 + + # Step 2: Get project and app names + - name: Get deployment names + id: names + run: | + # Use manual input or generate from repository name + if [ -n "${{ github.event.inputs.project_name }}" ]; then + PROJECT_NAME="${{ github.event.inputs.project_name }}" + APP_NAME="${{ github.event.inputs.app_name }}" + else + PROJECT_NAME="${{ github.event.repository.name }}-project" + APP_NAME="${{ github.event.repository.name }}-app" + fi + + echo "🔧 Using:" + echo " Project: $PROJECT_NAME" + echo " App: $APP_NAME" + echo "PROJECT_NAME=$PROJECT_NAME" >> $GITHUB_OUTPUT + echo "APP_NAME=$APP_NAME" >> $GITHUB_OUTPUT + echo "IMAGENAME=$APP_NAME" >> $GITHUB_OUTPUT + + # Step 3: Set up Docker Buildx + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + # Step 4: Login to Docker Hub + - name: Login to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ env.DOCKER_USERNAME }} + password: ${{ secrets.DOCKERHUB_PASSWORD }} + + # Step 5: Calculate new version + - name: Calculate new version + id: version + run: | + echo "📊 Calculating version..." + # Get short commit SHA and timestamp for unique version + SHORT_SHA=$(git rev-parse --short HEAD) + TIMESTAMP=$(date +%Y%m%d%H%M%S) + NEW_VERSION="${SHORT_SHA}-${TIMESTAMP}" + + echo "🆕 New version: $NEW_VERSION" + echo "NEW_VERSION=$NEW_VERSION" >> $GITHUB_OUTPUT + echo "IMAGE_TAG=${{ env.DOCKER_USERNAME }}/${{ steps.names.outputs.IMAGENAME }}:$NEW_VERSION" >> $GITHUB_OUTPUT + + # Step 6: Build Docker image + - name: Build Docker image + run: | + echo "🏗️ Building Docker image..." + docker build -t ${{ steps.version.outputs.IMAGE_TAG }} . + + # Step 7: Push versioned image to Docker Hub + - name: Push versioned image + run: | + echo "📤 Pushing versioned image to Docker Hub..." + docker push ${{ steps.version.outputs.IMAGE_TAG }} + echo "✅ Image pushed: ${{ steps.version.outputs.IMAGE_TAG }}" + + # Step 8: Push latest tag + - name: Push latest tag + run: | + echo "📤 Tagging and pushing as latest..." + docker tag ${{ steps.version.outputs.IMAGE_TAG }} ${{ env.DOCKER_USERNAME }}/${{ steps.names.outputs.IMAGENAME }}:latest + docker push ${{ env.DOCKER_USERNAME }}/${{ steps.names.outputs.IMAGENAME }}:latest + echo "✅ Latest tag pushed" + + # Step 9: Install Ghaymah CLI - name: Install Ghaymah CLI run: | echo "📥 Installing Ghaymah CLI..." curl -sSL https://cli.ghaymah.systems/install.sh | bash echo "✅ Ghaymah CLI installed" - - # Verify installation - $HOME/ghaymah/bin/gy --version - + + # Step 10: Login to Ghaymah - name: Login to Ghaymah run: | - echo "🔐 Authenticating with Ghaymah..." + echo "🔐 Logging into Ghaymah..." $HOME/ghaymah/bin/gy auth login --email "${{ secrets.GHAYMAH_EMAIL }}" --password "${{ secrets.GHAYMAH_PASSWORD }}" - echo "✅ Successfully logged in to Ghaymah" - - # Verify authentication - $HOME/ghaymah/bin/gy auth status - - - name: Debug - List existing projects - run: | - echo "🔍 Checking existing projects..." - $HOME/ghaymah/bin/gy resource project list || echo "No projects found or command failed" - - - name: Create or get project + echo "✅ Logged into Ghaymah" + + # Step 11: Create Ghaymah project + - name: Create Ghaymah project id: project run: | - echo "🏗️ Setting up project: $PROJECT_NAME" + echo "🔧 Creating project: ${{ steps.names.outputs.PROJECT_NAME }}" - # Try to get existing project first - echo "🔍 Looking for existing project..." - EXISTING_PROJECT=$($HOME/ghaymah/bin/gy resource project get --name "$PROJECT_NAME" 2>/dev/null | grep -oP 'ID:\s*\K[^\s]+' || echo "") + # Create project and capture output + PROJECT_OUTPUT=$($HOME/ghaymah/bin/gy resource project create --set .name="${{ steps.names.outputs.PROJECT_NAME }}" 2>&1) + echo "Project creation output: $PROJECT_OUTPUT" - if [ -n "$EXISTING_PROJECT" ]; then - echo "✅ Using existing project: $PROJECT_NAME" - PROJECT_ID="$EXISTING_PROJECT" - else - echo "📝 Creating new project: $PROJECT_NAME" - CREATE_OUTPUT=$($HOME/ghaymah/bin/gy resource project create --set .name="$PROJECT_NAME") - echo "Create output: $CREATE_OUTPUT" - - # Extract project ID using multiple methods - PROJECT_ID=$(echo "$CREATE_OUTPUT" | grep -oP 'ID:\s*\K[^\s]+') - - # Alternative extraction method - if [ -z "$PROJECT_ID" ]; then - PROJECT_ID=$(echo "$CREATE_OUTPUT" | awk '/ID:/ {print $NF}') - fi - fi + # Extract project ID + PROJECT_ID=$(echo "$PROJECT_OUTPUT" | awk '/ID:/ {print $NF}') if [ -z "$PROJECT_ID" ]; then - echo "❌ Failed to get project ID" - echo "Debug info:" - echo "PROJECT_NAME: $PROJECT_NAME" - echo "CREATE_OUTPUT: $CREATE_OUTPUT" + echo "❌ Failed to extract project ID" exit 1 fi - # Validate project ID format (should not be the default/null ID) - if [ "$PROJECT_ID" = "00000000-0000-0000-0000-000000000000" ]; then - echo "❌ Invalid project ID received: $PROJECT_ID" - exit 1 - fi - - echo "✅ Project ID: $PROJECT_ID" + echo "✅ Project created with ID: $PROJECT_ID" echo "PROJECT_ID=$PROJECT_ID" >> $GITHUB_OUTPUT - + + # Step 12: Create Ghaymah configuration - name: Create Ghaymah configuration run: | - echo "⚙️ Creating deployment configuration..." - - PROJECT_ID="${{ steps.project.outputs.PROJECT_ID }}" - - # Verify we have a valid project ID - if [ -z "$PROJECT_ID" ] || [ "$PROJECT_ID" = "00000000-0000-0000-0000-000000000000" ]; then - echo "❌ Invalid project ID, cannot create configuration" - exit 1 - fi + echo "⚙️ Creating Ghaymah configuration..." cat > .ghaymah.json << EOF { "container": { - "image": "docker.io/${DOCKER_USERNAME}/${IMAGE_NAME}:${IMAGE_TAG}", + "image": "${{ steps.version.outputs.IMAGE_TAG }}", "pullSecretName": "" }, - "name": "${APP_NAME}", + "name": "${{ steps.names.outputs.APP_NAME }}", "ports": [ { "expose": true, - "number": ${APP_PORT} + "number": 5000 } ], - "projectId": "${PROJECT_ID}", + "projectId": "${{ steps.project.outputs.PROJECT_ID }}", "publicAccess": { "baseDomain": "hosted.ghaymah.systems", "domain": "auto", @@ -136,65 +156,35 @@ jobs: } EOF - echo "✅ Configuration file created" - echo "📋 Configuration details:" - echo " Project: $PROJECT_NAME (ID: $PROJECT_ID)" - echo " App: $APP_NAME" - echo " Image: $DOCKER_USERNAME/$IMAGE_NAME:$IMAGE_TAG" - echo " Port: $APP_PORT" - - # Verify the file was created correctly - echo "🔍 Verifying configuration file:" - cat .ghaymah.json - echo "" - - # Check if project ID in file matches - CONFIG_PROJECT_ID=$(cat .ghaymah.json | jq -r '.projectId' 2>/dev/null || echo "jq not available") - echo "Project ID in config: $CONFIG_PROJECT_ID" - - - name: Initialize app (optional but recommended) - run: | - echo "🔧 Initializing app in project..." - $HOME/ghaymah/bin/gy resource app init --project-id "${{ steps.project.outputs.PROJECT_ID }}" || echo "⚠️ App initialization had issues, continuing..." - + echo "✅ Configuration file created:" + echo " - Project: ${{ steps.names.outputs.PROJECT_NAME }} (ID: ${{ steps.project.outputs.PROJECT_ID }})" + echo " - App: ${{ steps.names.outputs.APP_NAME }}" + echo " - Image: ${{ steps.version.outputs.IMAGE_TAG }}" + + # Step 13: Deploy to Ghaymah - name: Deploy to Ghaymah run: | echo "🚀 Deploying to Ghaymah..." - - # Verify .ghaymah.json exists and has valid content - if [ ! -f .ghaymah.json ]; then - echo "❌ .ghaymah.json file not found" - exit 1 - fi - - # Check project ID in config file - if command -v jq > /dev/null; then - CONFIG_PROJECT_ID=$(jq -r '.projectId' .ghaymah.json) - if [ "$CONFIG_PROJECT_ID" = "00000000-0000-0000-0000-000000000000" ] || [ -z "$CONFIG_PROJECT_ID" ]; then - echo "❌ Invalid project ID in configuration: $CONFIG_PROJECT_ID" - exit 1 - fi - echo "✅ Valid project ID in config: $CONFIG_PROJECT_ID" - fi - - # Deploy the application $HOME/ghaymah/bin/gy resource app launch - - if [ $? -eq 0 ]; then - echo "✅ Deployment successful!" - else - echo "❌ Deployment failed" - exit 1 - fi - + echo "✅ Deployment initiated" + + # Step 14: Wait for deployment + - name: Wait for deployment + run: | + echo "⏳ Waiting for deployment to complete..." + sleep 30 + + # Step 15: Show deployment summary - name: Show deployment summary run: | echo "" - echo "🎉 DEPLOYMENT COMPLETE!" - echo "========================" - echo "📱 Application: $APP_NAME" - echo "🏗️ Project: $PROJECT_NAME" - echo "🔗 Project ID: ${{ steps.project.outputs.PROJECT_ID }}" - echo "🐳 Image: $DOCKER_USERNAME/$IMAGE_NAME:$IMAGE_TAG" - echo "🌐 URL: https://${APP_NAME}.hosted.ghaymah.systems" - echo "========================" \ No newline at end of file + echo "🎉 DEPLOYMENT SUCCESSFUL!" + echo "================================" + echo "📱 Application: ${{ steps.names.outputs.APP_NAME }}" + echo "🏗️ Project: ${{ steps.names.outputs.PROJECT_NAME }}" + echo "🐳 Image: ${{ steps.version.outputs.IMAGE_TAG }}" + echo "🌐 URL: https://${{ steps.names.outputs.APP_NAME }}.hosted.ghaymah.systems" + echo "🔗 Commit: ${{ github.sha }}" + echo "👤 Deployed by: ${{ github.actor }}" + echo "================================" + echo "✨ Deployment process completed!" \ No newline at end of file