diff --git a/.github/workflows/cicd.yaml b/.github/workflows/cicd.yaml index 65ea434..4dcacb3 100644 --- a/.github/workflows/cicd.yaml +++ b/.github/workflows/cicd.yaml @@ -1,4 +1,4 @@ -name: Auto Deploy to Ghaymah +name: Deploy to Ghaymah Cloud on: push: @@ -7,57 +7,43 @@ on: branches: [ main, master ] env: - IMAGE_NAME: weather-app - DOCKER_USERNAME: ahmedgamalyousef - APP_NAME: weather-app - APP_PORT: 5000 + # These can be overridden in repository variables + APP_NAME: ${{ github.event.repository.name }} + APP_PORT: 3000 + DOCKER_IMAGE: ${{ github.repository }} jobs: - build-test-deploy: - # name: Build, Test & Deploy - # runs-on: ubuntu-latest + build-and-push: + name: Build and Push Docker Image + runs-on: ubuntu-latest + + outputs: + image_tag: ${{ steps.version.outputs.IMAGE_TAG }} + short_sha: ${{ steps.version.outputs.SHORT_SHA }} steps: - # Step 1: Checkout code - - name: Checkout repository + - name: Checkout code uses: actions/checkout@v4 - # # Step 2: Set up Node.js (if your app needs it) - # - name: Setup Node.js - # uses: actions/setup-node@v4 - # with: - # node-version: '18' - # cache: 'npm' - - # # Step 3: Install dependencies and test - # - name: Install dependencies - # run: npm install - - # - name: Run tests - # run: npm test - - # Step 4: Set up Docker Buildx - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - - # Step 5: Login to Docker Hub - - name: Login to Docker Hub - uses: docker/login-action@v3 - with: - username: ${{ secrets.DOCKER_USERNAME }} - password: ${{ secrets.DOCKER_PASSWORD }} - - # Step 6: Extract version from git commit - - name: Get version from commit + - name: Extract metadata and version id: version run: | SHORT_SHA=$(git rev-parse --short HEAD) TIMESTAMP=$(date +%Y%m%d%H%M%S) - echo "VERSION=${SHORT_SHA}-${TIMESTAMP}" >> $GITHUB_OUTPUT - echo "IMAGE_TAG=${{ secrets.DOCKER_USERNAME }}/${{ env.IMAGE_NAME }}:${SHORT_SHA}-${TIMESTAMP}" >> $GITHUB_OUTPUT - echo "🔨 Building version: ${SHORT_SHA}-${TIMESTAMP}" + echo "SHORT_SHA=${SHORT_SHA}" >> $GITHUB_OUTPUT + echo "IMAGE_TAG=${{ secrets.DOCKERHUB_USERNAME }}/${{ env.DOCKER_IMAGE }}:${SHORT_SHA}-${TIMESTAMP}" >> $GITHUB_OUTPUT + echo "LATEST_TAG=${{ secrets.DOCKERHUB_USERNAME }}/${{ env.DOCKER_IMAGE }}:latest" >> $GITHUB_OUTPUT + echo "📦 Version: ${SHORT_SHA}-${TIMESTAMP}" + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Login to DockerHub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} - # Step 7: Build and push Docker image - name: Build and push Docker image uses: docker/build-push-action@v5 with: @@ -65,98 +51,127 @@ jobs: push: true tags: | ${{ steps.version.outputs.IMAGE_TAG }} - ${{ secrets.DOCKER_USERNAME }}/${{ env.IMAGE_NAME }}:latest + ${{ steps.version.outputs.LATEST_TAG }} cache-from: type=gha cache-to: type=gha,mode=max labels: | org.opencontainers.image.source=${{ github.server_url }}/${{ github.repository }} org.opencontainers.image.revision=${{ github.sha }} - # Step 8: Install Ghaymah CLI + - name: Show image info + run: | + echo "✅ Image built and pushed:" + echo " Versioned: ${{ steps.version.outputs.IMAGE_TAG }}" + echo " Latest: ${{ steps.version.outputs.LATEST_TAG }}" + + deploy-to-ghaymah: + name: Deploy to Ghaymah + runs-on: ubuntu-latest + needs: build-and-push + if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master' + + steps: + - name: Checkout code + uses: actions/checkout@v4 + - name: Install Ghaymah CLI run: | echo "📥 Installing Ghaymah CLI..." - curl -sSl https://cli.ghaymah.systems/install.sh | bash + curl -sSL https://cli.ghaymah.systems/install.sh | bash echo "✅ Ghaymah CLI installed" - # Step 9: Configure Ghaymah - - name: Configure Ghaymah deployment - if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master' + - name: Configure Ghaymah authentication run: | - echo "⚙️ Creating Ghaymah configuration..." - - # Create .ghaymah.json configuration - cat > .ghaymah.json << EOF - { - "container": { - "image": "${{ steps.version.outputs.IMAGE_TAG }}", - "pullSecretName": "" - }, - "name": "${{ env.APP_NAME }}", - "ports": [ - { - "expose": true, - "number": ${{ env.APP_PORT }} - } - ], - "projectId": "${{ secrets.GHAYMAH_PROJECT_ID }}", - "publicAccess": { - "baseDomain": "hosted.ghaymah.systems", - "domain": "auto", - "enabled": true - }, - "resourceTier": "t1" - } - EOF - - echo "✅ Configuration file created" - cat .ghaymah.json + echo "🔐 Setting up Ghaymah authentication..." + $HOME/ghaymah/bin/gy auth login --email "${{ secrets.GHAYMAH_EMAIL }}" --password "${{ secrets.GHAYMAH_PASSWORD }}" + echo "✅ Authenticated with Ghaymah" - # Step 10: Deploy to Ghaymah - - name: Deploy to Ghaymah - if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master' + - name: Create or get project + id: project + run: | + echo "🏗️ Setting up project..." + + # Use repository name as project name, or custom from secrets + PROJECT_NAME="${{ secrets.GHAYMAH_PROJECT_NAME || github.event.repository.name }}" + + # Check if project exists + if $HOME/ghaymah/bin/gy resource project get --name "$PROJECT_NAME" > /dev/null 2>&1; then + echo "✅ Using existing project: $PROJECT_NAME" + PROJECT_ID=$($HOME/ghaymah/bin/gy resource project get --name "$PROJECT_NAME" | grep -oP 'ID:\s*\K[^\s]+' || echo "") + else + echo "📝 Creating new project: $PROJECT_NAME" + PROJECT_ID=$($HOME/ghaymah/bin/gy resource project create --set .name="$PROJECT_NAME" | grep -oP 'ID:\s*\K[^\s]+') + fi + + if [ -z "$PROJECT_ID" ]; then + echo "❌ Failed to get project ID" + exit 1 + fi + + echo "PROJECT_ID=$PROJECT_ID" >> $GITHUB_OUTPUT + echo "PROJECT_NAME=$PROJECT_NAME" >> $GITHUB_OUTPUT + echo "✅ Project ID: $PROJECT_ID" + + - name: Create Ghaymah configuration + run: | + echo "⚙️ Creating deployment configuration..." + + # Use custom app name or default to repository name + APP_NAME="${{ secrets.GHAYMAH_APP_NAME || env.APP_NAME }}" + APP_PORT="${{ env.APP_PORT }}" + IMAGE_TAG="${{ needs.build-and-push.outputs.image_tag }}" + PROJECT_ID="${{ steps.project.outputs.PROJECT_ID }}" + + cat > .ghaymah.json << EOF +{ + "container": { + "image": "$IMAGE_TAG", + "pullSecretName": "" + }, + "name": "$APP_NAME", + "ports": [ + { + "expose": true, + "number": $APP_PORT + } + ], + "projectId": "$PROJECT_ID", + "publicAccess": { + "baseDomain": "hosted.ghaymah.systems", + "domain": "auto", + "enabled": true + }, + "resourceTier": "t1" +} +EOF + + echo "✅ Configuration file created:" + echo " App: $APP_NAME" + echo " Port: $APP_PORT" + echo " Image: $IMAGE_TAG" + echo " Project: $PROJECT_ID" + + - name: Deploy application run: | echo "🚀 Deploying to Ghaymah..." - - # Deploy the application - gy resource app launch - - echo "✅ Deployment command completed" + $HOME/ghaymah/bin/gy resource app launch + echo "✅ Deployment initiated" - # Step 11: Wait and verify deployment - - name: Verify deployment - if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master' + - name: Wait for deployment run: | - echo "⏳ Waiting for deployment to become ready..." - sleep 45 - - APP_URL="https://${{ env.APP_NAME }}.hosted.ghaymah.systems" - echo "🌐 Your updated app is available at: $APP_URL" - - # Try to check if app is responding - echo "🔍 Checking application health..." - if command -v curl > /dev/null; then - for i in {1..6}; do - if curl -s -f --max-time 10 "$APP_URL" > /dev/null; then - echo "✅ Application is healthy and responding!" - break - else - echo "⏱️ Attempt $i: Application not ready yet, waiting 10 seconds..." - sleep 10 - fi - done - fi + echo "⏳ Waiting for deployment to complete..." + sleep 30 + APP_NAME="${{ secrets.GHAYMAH_APP_NAME || env.APP_NAME }}" + echo "🌐 Your app should be available at: https://${APP_NAME}.hosted.ghaymah.systems" - # Step 12: Deployment summary - - name: Deployment summary - if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master' + - name: Show deployment summary run: | echo "" - echo "🎉 DEPLOYMENT SUCCESSFUL!" - echo "================================" - echo "📱 Application: ${{ env.APP_NAME }}" - echo "🐳 Image: ${{ steps.version.outputs.IMAGE_TAG }}" - echo "🌐 URL: https://${{ env.APP_NAME }}.hosted.ghaymah.systems" + echo "🎉 DEPLOYMENT COMPLETE!" + echo "========================" + echo "📱 Application: ${{ secrets.GHAYMAH_APP_NAME || env.APP_NAME }}" + echo "🏗️ Project: ${{ steps.project.outputs.PROJECT_NAME }}" + echo "🐳 Image: ${{ needs.build-and-push.outputs.image_tag }}" echo "🔗 Commit: ${{ github.sha }}" - echo "👤 Triggered by: ${{ github.actor }}" - echo "================================" \ No newline at end of file + echo "🌐 URL: https://${{ secrets.GHAYMAH_APP_NAME || env.APP_NAME }}.hosted.ghaymah.systems" + echo "========================" \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1795c8d --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.history \ No newline at end of file