diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml new file mode 100644 index 0000000..b3f0b69 --- /dev/null +++ b/.github/workflows/cd.yml @@ -0,0 +1,94 @@ +# Continuous Deployment Workflow +# This workflow deploys your application to Kubernetes cluster +# Trigger: Manual dispatch only + +name: CD - Deploy to Kubernetes + +# Trigger configuration - manual dispatch only +on: + workflow_dispatch: + inputs: + image_tag: + description: 'Docker image tag to deploy (e.g., latest, v1.0.0)' + required: false + default: 'latest' + type: string + namespace: + description: 'Kubernetes namespace (e.g., production, staging)' + required: false + default: 'default' + type: string + ingress_host: + description: 'Ingress host domain (e.g., www.example.com)' + required: false + default: '' + type: string + +# Environment variables available to all jobs +env: + # Kubernetes configuration + KUBECONFIG_DATA: ${{ secrets.KUBECONFIG_DATA }} + KUBERNETES_URL: ${{ secrets.KUBERNETES_URL }} + KUBERNETES_NAMESPACE: ${{ inputs.namespace || secrets.KUBERNETES_NAMESPACE }} + KUBERNETES_INGRESS_HOST: ${{ inputs.ingress_host || secrets.KUBERNETES_INGRESS_HOST }} + + # Container registry configuration + CONTAINER_REGISTRY_URL: ${{ secrets.CONTAINER_REGISTRY_URL }} + CONTAINER_REGISTRY_USERNAME: ${{ secrets.CONTAINER_REGISTRY_USERNAME }} + CONTAINER_REGISTRY_NAMESPACE: ${{ secrets.CONTAINER_REGISTRY_NAMESPACE }} + CONTAINER_REGISTRY_PASSWORD: ${{ secrets.CONTAINER_REGISTRY_PASSWORD }} + CONTAINER_IMAGE_NAME: ${{ secrets.CONTAINER_IMAGE_NAME }} + CONTAINER_IMAGE_TAG: ${{ inputs.image_tag || 'latest' }} + +jobs: + deploy: + name: Deploy to Kubernetes + runs-on: ubuntu-latest + + steps: + # Step 1: Checkout code from repository + - name: Checkout code + uses: actions/checkout@v4 + + # Step 2: Install kubectl (Kubernetes CLI tool) + - name: Install kubectl + uses: azure/setup-kubectl@v4 + with: + version: 'latest' + + # Step 3: Install envsubst (for environment variable substitution) + - name: Install envsubst + run: | + sudo apt-get update + sudo apt-get install -y gettext-base + + # Step 4: Make CD script executable + - name: Make CD script executable + run: chmod +x script/cd.sh + + # Step 5: Deploy to Kubernetes + - name: Deploy to Kubernetes + run: ./script/cd.sh deploy + + # Step 6: Output deployment summary + - name: Deployment Summary + if: success() + run: | + echo "### :white_check_mark: Deployment Successful!" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "**Application:** \`${CONTAINER_IMAGE_NAME}\`" >> $GITHUB_STEP_SUMMARY + echo "**Namespace:** \`${KUBERNETES_NAMESPACE}\`" >> $GITHUB_STEP_SUMMARY + echo "**Image:** \`${CONTAINER_REGISTRY_URL}/${CONTAINER_REGISTRY_NAMESPACE}/${CONTAINER_IMAGE_NAME}:${CONTAINER_IMAGE_TAG}\`" >> $GITHUB_STEP_SUMMARY + echo "**URL:** http://${KUBERNETES_INGRESS_HOST}" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "---" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "**Deployment Time:** $(date -u +'%Y-%m-%d %H:%M:%S UTC')" >> $GITHUB_STEP_SUMMARY + + # Step 7: Output failure message + - name: Deployment Failed + if: failure() + run: | + echo "### :x: Deployment Failed!" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "Please check the logs above for error details." >> $GITHUB_STEP_SUMMARY diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..bc6b2c2 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,60 @@ +# Continuous Integration Workflow +# This workflow builds and pushes Docker images to your private registry +# Trigger: Manual dispatch only + +name: CI - Build and Push + +# Trigger configuration - manual dispatch only +on: + workflow_dispatch: + inputs: + image_tag: + description: 'Docker image tag (e.g., latest, v1.0.0)' + required: false + default: 'latest' + type: string + +# Environment variables available to all jobs +env: + CONTAINER_REGISTRY_URL: ${{ secrets.CONTAINER_REGISTRY_URL }} + CONTAINER_REGISTRY_USERNAME: ${{ secrets.CONTAINER_REGISTRY_USERNAME }} + CONTAINER_REGISTRY_NAMESPACE: ${{ secrets.CONTAINER_REGISTRY_NAMESPACE }} + CONTAINER_REGISTRY_PASSWORD: ${{ secrets.CONTAINER_REGISTRY_PASSWORD }} + CONTAINER_IMAGE_NAME: ${{ secrets.CONTAINER_IMAGE_NAME }} + CONTAINER_IMAGE_TAG: ${{ inputs.image_tag || 'latest' }} + +jobs: + build-and-push: + name: Build and Push Docker Image + runs-on: ubuntu-latest + + steps: + # Step 1: Checkout code from repository + - name: Checkout code + uses: actions/checkout@v4 + + # Step 2: Set up Docker Buildx (for advanced Docker builds) + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + # Step 3: Make CI script executable + - name: Make CI script executable + run: chmod +x script/ci.sh + + # Step 4: Build Docker image + - name: Build Docker image + run: ./script/ci.sh build + + # Step 5: Push Docker image to registry + - name: Push Docker image + run: ./script/ci.sh push + + # Step 6: Output summary + - name: Summary + run: | + echo "### :rocket: Build Complete!" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "**Image:** \`${CONTAINER_REGISTRY_URL}/${CONTAINER_REGISTRY_NAMESPACE}/${CONTAINER_IMAGE_NAME}:${CONTAINER_IMAGE_TAG}\`" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "**Registry:** ${CONTAINER_REGISTRY_URL}" >> $GITHUB_STEP_SUMMARY + echo "**Tag:** ${CONTAINER_IMAGE_TAG}" >> $GITHUB_STEP_SUMMARY