Deploy AMP #12
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Deploy AMP | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| environment: | |
| description: 'Server to deploy' | |
| required: true | |
| type: choice | |
| options: | |
| - staging | |
| - de | |
| country: | |
| description: 'Country to deploy (will be validated against available countries from server)' | |
| required: true | |
| type: choice | |
| options: | |
| - bfaso | |
| - boad | |
| - chad | |
| - civ | |
| - drc | |
| - ecowas | |
| - egypt | |
| - ethiopia | |
| - gambia | |
| - ggw | |
| - haiti | |
| - haitiiati | |
| - haititraining | |
| - honduras | |
| - honduraslight | |
| - honduraslightssc | |
| - jordan | |
| - kosovo | |
| - kyrgyzstan | |
| - liberia | |
| - madagascar | |
| - malawi | |
| - moldova | |
| - nepal | |
| - niger | |
| - rdidemo | |
| - rwanda | |
| - rwandatest | |
| - senegal | |
| - senegalgiz | |
| - tanzania | |
| - timor | |
| - togo | |
| - uganda | |
| - xchad | |
| pr_number: | |
| description: 'PR number (optional - if provided, will use pr-{number} format for tag and URL). See workflow logs for available PRs.' | |
| required: false | |
| type: string | |
| env: | |
| PG_VERSION: 14 | |
| # Reference list from GitHub Repository Variables | |
| COMMON_COUNTRIES: ${{ vars.COMMON_COUNTRIES }} | |
| jobs: | |
| build-and-deploy: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Setup SSH for submodules | |
| uses: webfactory/ssh-agent@v0.9.0 | |
| with: | |
| ssh-private-key: ${{ secrets.DOCKER_BUILD_SSH_KEY || '' }} | |
| - name: Configure git to use SSH for submodules | |
| run: | | |
| # Configure git to rewrite HTTPS URLs to SSH for submodules | |
| git config --global url."git@github.com:".insteadOf "https://github.com/" | |
| # Add GitHub to known hosts | |
| mkdir -p ~/.ssh | |
| ssh-keyscan -H github.com >> ~/.ssh/known_hosts 2>/dev/null || true | |
| - name: Checkout code with submodules (default branch) | |
| if: inputs.pr_number == '' | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| submodules: true | |
| # Use SSH for private submodules | |
| ssh-key: ${{ secrets.DOCKER_BUILD_SSH_KEY || '' }} | |
| - name: List available PRs and validate | |
| if: inputs.pr_number != '' | |
| id: pr_info | |
| run: | | |
| set -e | |
| echo "📋 Fetching list of open pull requests..." | |
| echo "" | |
| # Fetch open PRs using GitHub API | |
| REPO="${{ github.repository }}" | |
| PR_NUMBER="${{ inputs.pr_number }}" | |
| # Validate PR number is numeric | |
| if ! [[ "$PR_NUMBER" =~ ^[0-9]+$ ]]; then | |
| echo "❌ Error: PR number must be numeric, got: ${PR_NUMBER}" | |
| exit 1 | |
| fi | |
| # Get list of open PRs (limit to 50 most recent) | |
| PRS_RESPONSE=$(curl -s -H "Authorization: token ${{ github.token }}" \ | |
| "https://api.github.com/repos/${REPO}/pulls?state=open&per_page=50&sort=updated&direction=desc") | |
| if [ -z "$PRS_RESPONSE" ] || [ "$PRS_RESPONSE" == "[]" ]; then | |
| echo "❌ Error: Could not fetch PR list or no open PRs found" | |
| echo " Cannot validate PR #${PR_NUMBER}" | |
| exit 1 | |
| fi | |
| echo "Available open PRs:" | |
| echo "$PRS_RESPONSE" | jq -r '.[] | " #\(.number) - \(.title) (branch: \(.head.ref))"' || echo "Could not parse PR list" | |
| echo "" | |
| # Validate the provided PR number exists in open PRs | |
| PR_EXISTS=$(echo "$PRS_RESPONSE" | jq -r --arg pr "$PR_NUMBER" '.[] | select(.number == ($pr | tonumber)) | .number' || echo "") | |
| if [ -z "$PR_EXISTS" ]; then | |
| echo "❌ Error: PR #${PR_NUMBER} not found in open PRs list" | |
| echo "" | |
| echo "The PR might be:" | |
| echo " - Closed or merged" | |
| echo " - Not yet created" | |
| echo " - Incorrect number" | |
| echo "" | |
| echo "Please verify the PR number and try again." | |
| exit 1 | |
| fi | |
| # Get PR details | |
| PR_TITLE=$(echo "$PRS_RESPONSE" | jq -r --arg pr "$PR_NUMBER" '.[] | select(.number == ($pr | tonumber)) | .title' || echo "") | |
| PR_BRANCH=$(echo "$PRS_RESPONSE" | jq -r --arg pr "$PR_NUMBER" '.[] | select(.number == ($pr | tonumber)) | .head.ref' || echo "") | |
| PR_HEAD_REPO=$(echo "$PRS_RESPONSE" | jq -r --arg pr "$PR_NUMBER" '.[] | select(.number == ($pr | tonumber)) | .head.repo.full_name' || echo "") | |
| PR_HEAD_SHA=$(echo "$PRS_RESPONSE" | jq -r --arg pr "$PR_NUMBER" '.[] | select(.number == ($pr | tonumber)) | .head.sha' || echo "") | |
| echo "✅ PR #${PR_NUMBER} found: ${PR_TITLE}" | |
| echo " Branch: ${PR_BRANCH}" | |
| echo " Repository: ${PR_HEAD_REPO}" | |
| echo " SHA: ${PR_HEAD_SHA}" | |
| # Store PR branch info for checkout step | |
| echo "PR_BRANCH=${PR_BRANCH}" >> $GITHUB_OUTPUT | |
| echo "PR_HEAD_REPO=${PR_HEAD_REPO}" >> $GITHUB_OUTPUT | |
| echo "PR_HEAD_SHA=${PR_HEAD_SHA}" >> $GITHUB_OUTPUT | |
| - name: Checkout PR branch | |
| if: inputs.pr_number != '' | |
| uses: actions/checkout@v4 | |
| with: | |
| ref: ${{ steps.pr_info.outputs.PR_BRANCH }} | |
| repository: ${{ steps.pr_info.outputs.PR_HEAD_REPO }} | |
| fetch-depth: 0 | |
| submodules: true | |
| # Use SSH for private submodules | |
| ssh-key: ${{ secrets.DOCKER_BUILD_SSH_KEY || '' }} | |
| - name: Set up JDK for Maven | |
| uses: actions/setup-java@v4 | |
| with: | |
| java-version: '11' | |
| distribution: 'temurin' | |
| - name: Read AMP version from pom.xml | |
| id: amp_version | |
| run: | | |
| VERSION=$(mvn -f amp/pom.xml -q -Dexec.executable=echo -Dexec.args='${project.version}' --non-recursive exec:exec) | |
| echo "AMP_VERSION=$VERSION" >> $GITHUB_OUTPUT | |
| echo "AMP Version: $VERSION" | |
| - name: Generate deployment tag | |
| id: tag | |
| run: | | |
| # Check if PR number is provided | |
| if [ -n "${{ inputs.pr_number }}" ]; then | |
| PR_NUMBER="${{ inputs.pr_number }}" | |
| TAG="pr-${PR_NUMBER}" | |
| echo "PR_NUMBER=${PR_NUMBER}" >> $GITHUB_OUTPUT | |
| echo "Deployment tag: $TAG (PR #${PR_NUMBER})" | |
| else | |
| # Handle branch-based deployments | |
| BRANCH_NAME="${GITHUB_REF#refs/heads/}" | |
| if [[ "$BRANCH_NAME" =~ ^feature/AMP-[0-9]+.* ]]; then | |
| JIRA_ID=$(echo "$BRANCH_NAME" | sed -n 's/^feature\/AMP-\([0-9]\+\).*/\1/p') | |
| TAG="feature-${JIRA_ID}" | |
| else | |
| TAG=$(echo "$BRANCH_NAME" | sed 's/[^a-zA-Z0-9_-]/-/g' | tr '[:upper:]' '[:lower:]') | |
| fi | |
| echo "Deployment tag: $TAG" | |
| fi | |
| echo "TAG=$TAG" >> $GITHUB_OUTPUT | |
| - name: Login to ECR (Push) | |
| uses: aws-actions/amazon-ecr-login@v2 | |
| env: | |
| AWS_REGION: us-east-1 | |
| with: | |
| registries: ${{ secrets.DOCKER_REGISTRY }} | |
| - name: Set deployment hostname and user | |
| id: deploy_config | |
| run: | | |
| # Use inputs from workflow_dispatch | |
| ENV="${{ inputs.environment }}" | |
| COUNTRY="${{ inputs.country }}" | |
| # Store environment and country | |
| echo "ENV=${ENV}" >> $GITHUB_OUTPUT | |
| echo "COUNTRY=${COUNTRY}" >> $GITHUB_OUTPUT | |
| if [[ "$ENV" == "de" ]]; then | |
| echo "DEPLOY_HOST=${{ vars.AMP_DE_HOSTNAME }}" >> $GITHUB_OUTPUT | |
| # For PRs, use pr-{number} format in URL | |
| if [ -n "${{ inputs.pr_number }}" ]; then | |
| echo "AMP_URL=http://amp-${COUNTRY}-pr-${{ inputs.pr_number }}.de.ampsite.net/" >> $GITHUB_OUTPUT | |
| else | |
| echo "AMP_URL=http://amp-${COUNTRY}-${{ steps.tag.outputs.TAG }}.de.ampsite.net/" >> $GITHUB_OUTPUT | |
| fi | |
| else | |
| echo "DEPLOY_HOST=${{ vars.AMP_STAGING_HOSTNAME }}" >> $GITHUB_OUTPUT | |
| # For PRs, use pr-{number} format in URL | |
| if [ -n "${{ inputs.pr_number }}" ]; then | |
| echo "AMP_URL=http://amp-${COUNTRY}-pr-${{ inputs.pr_number }}.stg.ampsite.net/" >> $GITHUB_OUTPUT | |
| else | |
| echo "AMP_URL=http://amp-${COUNTRY}-${{ steps.tag.outputs.TAG }}.stg.ampsite.net/" >> $GITHUB_OUTPUT | |
| fi | |
| fi | |
| # Store PR number if provided | |
| if [ -n "${{ inputs.pr_number }}" ]; then | |
| echo "PR_NUMBER=${{ inputs.pr_number }}" >> $GITHUB_OUTPUT | |
| fi | |
| # Set deploy user from vars with fallback to 'jenkins' | |
| if [ -n "${{ vars.DEPLOY_USER }}" ]; then | |
| echo "DEPLOY_USER=${{ vars.DEPLOY_USER }}" >> $GITHUB_OUTPUT | |
| else | |
| echo "DEPLOY_USER=bmokandu" >> $GITHUB_OUTPUT | |
| fi | |
| - name: Setup SSH | |
| uses: webfactory/ssh-agent@v0.9.0 | |
| with: | |
| ssh-private-key: ${{ secrets.DEPLOY_SSH_PRIVATE_KEY }} | |
| - name: Setup SSH config for bastion | |
| run: | | |
| mkdir -p ~/.ssh | |
| chmod 700 ~/.ssh | |
| DEPLOY_HOST="${{ steps.deploy_config.outputs.DEPLOY_HOST }}" | |
| DEPLOY_USER="${{ steps.deploy_config.outputs.DEPLOY_USER }}" | |
| BASTION_HOST="${{ secrets.BASTION_HOST }}" | |
| BASTION_USER="${{ vars.BASTION_USER }}" | |
| # Use default bastion user if not specified (matching local config: bmokandu) | |
| if [ -z "$BASTION_USER" ] || [ "$BASTION_USER" = "" ]; then | |
| BASTION_USER="bmokandu" | |
| fi | |
| # Create SSH config matching local configuration | |
| # Pattern: *.aws uses ProxyCommand ssh -W %h.devgateway.org:%p bastion | |
| if [ -n "$BASTION_HOST" ] && [ "$BASTION_HOST" != "" ]; then | |
| # Check if deployment host matches *.aws pattern for ProxyCommand | |
| if echo "$DEPLOY_HOST" | grep -q "\.aws"; then | |
| # Use ProxyCommand pattern for *.aws hosts (matching local SSH config) | |
| # Pattern: %h.devgateway.org means if host is "ampdev.aws", target is "ampdev.aws.devgateway.org" | |
| if echo "$DEPLOY_HOST" | grep -q "\.aws\.devgateway\.org$"; then | |
| # Already in full format: something.aws.devgateway.org | |
| TARGET_HOST="$DEPLOY_HOST" | |
| elif echo "$DEPLOY_HOST" | grep -q "\.aws$"; then | |
| # Transform: something.aws -> something.aws.devgateway.org (matching %h.devgateway.org pattern) | |
| TARGET_HOST="${DEPLOY_HOST}.devgateway.org" | |
| else | |
| # Fallback: use as-is | |
| TARGET_HOST="$DEPLOY_HOST" | |
| fi | |
| echo "DEBUG: DEPLOY_HOST=$DEPLOY_HOST, TARGET_HOST=$TARGET_HOST" | |
| cat >> ~/.ssh/config << EOF | |
| Host bastion | |
| HostName $BASTION_HOST | |
| User $BASTION_USER | |
| StrictHostKeyChecking no | |
| UserKnownHostsFile /dev/null | |
| ControlMaster no | |
| Host $DEPLOY_HOST | |
| HostName $DEPLOY_HOST | |
| User $DEPLOY_USER | |
| ProxyCommand ssh -W $TARGET_HOST:%p -o ClearAllForwardings=no bastion | |
| StrictHostKeyChecking no | |
| UserKnownHostsFile /dev/null | |
| ControlMaster no | |
| EOF | |
| else | |
| # Use ProxyJump for non-*.aws hosts | |
| cat >> ~/.ssh/config << EOF | |
| Host bastion | |
| HostName $BASTION_HOST | |
| User $BASTION_USER | |
| StrictHostKeyChecking no | |
| UserKnownHostsFile /dev/null | |
| ControlMaster no | |
| Host $DEPLOY_HOST | |
| HostName $DEPLOY_HOST | |
| User $DEPLOY_USER | |
| ProxyJump bastion | |
| StrictHostKeyChecking no | |
| UserKnownHostsFile /dev/null | |
| ControlMaster no | |
| EOF | |
| fi | |
| else | |
| # No bastion - direct connection | |
| cat >> ~/.ssh/config << EOF | |
| Host $DEPLOY_HOST | |
| HostName $DEPLOY_HOST | |
| User $DEPLOY_USER | |
| StrictHostKeyChecking no | |
| UserKnownHostsFile /dev/null | |
| ControlMaster no | |
| EOF | |
| fi | |
| chmod 600 ~/.ssh/config | |
| echo "✅ Configured SSH to use bastion: ${BASTION_HOST:-'none (direct connection)'}" | |
| echo "✅ Using ProxyCommand pattern matching your local config" | |
| echo "✅ Bastion user: $BASTION_USER" | |
| echo "✅ Deployment host: $DEPLOY_HOST" | |
| echo "" | |
| echo "SSH configuration:" | |
| cat ~/.ssh/config | |
| - name: Test SSH connection | |
| run: | | |
| DEPLOY_HOST="${{ steps.deploy_config.outputs.DEPLOY_HOST }}" | |
| DEPLOY_USER="${{ steps.deploy_config.outputs.DEPLOY_USER }}" | |
| echo "Testing SSH connection through bastion..." | |
| ssh $DEPLOY_USER@$DEPLOY_HOST "echo 'SSH connection successful'" | |
| - name: Get available countries list | |
| id: countries_list | |
| run: | | |
| DEPLOY_HOST="${{ steps.deploy_config.outputs.DEPLOY_HOST }}" | |
| DEPLOY_USER="${{ steps.deploy_config.outputs.DEPLOY_USER }}" | |
| # Get available countries for this version | |
| COUNTRIES=$(ssh $DEPLOY_USER@$DEPLOY_HOST "cd /opt/amp_dbs && amp-db ls ${{ steps.amp_version.outputs.AMP_VERSION }} | sort" || echo "") | |
| COUNTRIES=$(echo "$COUNTRIES" | tr '\n' ' ' | xargs) # Trim whitespace | |
| if [ -z "$COUNTRIES" ] || [ "$COUNTRIES" = "" ]; then | |
| echo "❌ No database backups compatible with version ${{ steps.amp_version.outputs.AMP_VERSION }}" | |
| exit 1 | |
| fi | |
| # Store countries list for later use | |
| echo "COUNTRIES<<EOF" >> $GITHUB_OUTPUT | |
| echo "$COUNTRIES" >> $GITHUB_OUTPUT | |
| echo "EOF" >> $GITHUB_OUTPUT | |
| echo "==========================================" | |
| echo "Available countries for version ${{ steps.amp_version.outputs.AMP_VERSION }}:" | |
| echo "==========================================" | |
| echo "$COUNTRIES" | tr ' ' '\n' | |
| echo "==========================================" | |
| - name: Validate selected country | |
| run: | | |
| # Get country from deploy_config output | |
| COUNTRY="${{ steps.deploy_config.outputs.COUNTRY }}" | |
| # Convert countries list to newline-separated for validation | |
| COUNTRIES=$(echo "${{ steps.countries_list.outputs.COUNTRIES }}" | tr ' ' '\n') | |
| # Check if selected country is available | |
| if ! echo "$COUNTRIES" | grep -q "^${COUNTRY}$"; then | |
| echo "❌ Country '${COUNTRY}' not found in available countries" | |
| echo "" | |
| echo "Available countries:" | |
| echo "$COUNTRIES" | |
| exit 1 | |
| fi | |
| echo "✅ Country '${COUNTRY}' is available" | |
| - name: Get database version | |
| id: db_version | |
| run: | | |
| DEPLOY_HOST="${{ steps.deploy_config.outputs.DEPLOY_HOST }}" | |
| DEPLOY_USER="${{ steps.deploy_config.outputs.DEPLOY_USER }}" | |
| # Get country from deploy_config output | |
| COUNTRY="${{ steps.deploy_config.outputs.COUNTRY }}" | |
| DB_VERSION=$(ssh $DEPLOY_USER@$DEPLOY_HOST "cd /opt/amp_dbs && amp-db find ${{ steps.amp_version.outputs.AMP_VERSION }} ${COUNTRY}") | |
| echo "DB_VERSION=$DB_VERSION" >> $GITHUB_OUTPUT | |
| echo "Database version: $DB_VERSION" | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v3 | |
| - name: Get commit hash | |
| id: commit_hash | |
| run: | | |
| if git log --pretty=%an -n 1 | grep -q "GitHub Actions"; then | |
| REF="HEAD~1" | |
| else | |
| REF="HEAD" | |
| fi | |
| HASH=$(git rev-parse $REF) | |
| echo "COMMIT_HASH=$HASH" >> $GITHUB_OUTPUT | |
| echo "Commit hash: $HASH" | |
| - name: Setup SSH for Docker build | |
| uses: webfactory/ssh-agent@v0.9.0 | |
| with: | |
| ssh-private-key: ${{ secrets.DOCKER_BUILD_SSH_KEY || '' }} | |
| - name: Build Docker image | |
| env: | |
| DOCKER_BUILDKIT: 1 | |
| run: | | |
| IMAGE="${{ secrets.DOCKER_REGISTRY }}/amp/webapp:${{ steps.tag.outputs.TAG }}" | |
| echo "Using registry: ${{ secrets.DOCKER_REGISTRY }}" | |
| echo "Image: ${IMAGE}" | |
| # Build SSH args - only add if SSH_AUTH_SOCK is available (from ssh-agent) | |
| SSH_ARGS="" | |
| if [ -n "$SSH_AUTH_SOCK" ]; then | |
| SSH_ARGS="--ssh default" | |
| fi | |
| # Use cache from registry to speed up builds | |
| # Try to pull a previous image with the same tag to use as cache | |
| CACHE_FROM="" | |
| if docker pull "$IMAGE" 2>/dev/null; then | |
| echo "✅ Found existing image, using as cache" | |
| CACHE_FROM="--cache-from $IMAGE" | |
| else | |
| echo "ℹ️ No existing image found, building from scratch" | |
| fi | |
| docker build \ | |
| --progress=plain \ | |
| $SSH_ARGS \ | |
| $CACHE_FROM \ | |
| -t "$IMAGE" \ | |
| --build-arg BUILD_SOURCE="${{ steps.tag.outputs.TAG }}" \ | |
| --build-arg AMP_URL="${{ steps.deploy_config.outputs.AMP_URL }}" \ | |
| --build-arg AMP_PULL_REQUEST="${{ steps.deploy_config.outputs.PR_NUMBER || '' }}" \ | |
| --build-arg AMP_BRANCH="${GITHUB_REF#refs/heads/}" \ | |
| --build-arg AMP_REGISTRY_PRIVATE_KEY="${{ secrets.AMP_REGISTRY_PRIVATE_KEY || '' }}" \ | |
| --label git-hash="${{ steps.commit_hash.outputs.COMMIT_HASH }}" \ | |
| amp | |
| echo "IMAGE=$IMAGE" >> $GITHUB_ENV | |
| - name: Push Docker image to registry | |
| run: | | |
| docker push "${{ env.IMAGE }}" > /dev/null | |
| echo "✅ Image pushed successfully" | |
| - name: Logout from Container Registry | |
| if: always() | |
| run: docker logout ${{ secrets.DOCKER_REGISTRY }} || true | |
| - name: Update GitHub commit status | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| github.rest.repos.createCommitStatus({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| sha: '${{ steps.commit_hash.outputs.COMMIT_HASH }}', | |
| state: 'success', | |
| target_url: '${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}', | |
| description: 'Built successfully', | |
| context: 'github-actions/build' | |
| }); | |
| - name: Deploy to server | |
| id: deploy | |
| run: | | |
| set -eox pipefail | |
| DEPLOY_HOST="${{ steps.deploy_config.outputs.DEPLOY_HOST }}" | |
| DEPLOY_USER="${{ steps.deploy_config.outputs.DEPLOY_USER }}" | |
| # Check if user needs sudo for docker, or if they're in docker group | |
| # Try without sudo first, fall back to sudo if needed | |
| ssh $DEPLOY_USER@$DEPLOY_HOST bash << DEPLOY_SCRIPT | |
| set -e | |
| TAG="${{ steps.tag.outputs.TAG }}" | |
| COUNTRY="${{ steps.deploy_config.outputs.COUNTRY }}" | |
| DB_VERSION="${{ steps.db_version.outputs.DB_VERSION }}" | |
| PG_VERSION="${{ env.PG_VERSION }}" | |
| # Use the same registry that was used for building | |
| EXPECTED_IMAGE="${{ secrets.DOCKER_REGISTRY }}/amp/webapp:${TAG}" | |
| echo "==========================================" | |
| echo "Deployment Parameters:" | |
| echo " TAG: ${TAG}" | |
| echo " COUNTRY: ${COUNTRY}" | |
| echo " DB_VERSION: ${DB_VERSION}" | |
| echo " PG_VERSION: ${PG_VERSION}" | |
| echo " EXPECTED_IMAGE: ${EXPECTED_IMAGE}" | |
| echo "==========================================" | |
| # For PRs, log the PR number | |
| if [ -n "${{ inputs.pr_number }}" ]; then | |
| echo "Deploying PR #${{ inputs.pr_number }} to ${COUNTRY}" | |
| fi | |
| # Determine which registry to use | |
| ECR_REGISTRY="798366298150.dkr.ecr.us-east-1.amazonaws.com" | |
| echo "Expected image: ${EXPECTED_IMAGE}" | |
| echo "ECR registry: ${ECR_REGISTRY}" | |
| # If the image is in ECR, authenticate with ECR | |
| if echo "$EXPECTED_IMAGE" | grep -q "$ECR_REGISTRY"; then | |
| echo "Image is in ECR, authenticating..." | |
| # Try AWS CLI first (if available and configured) | |
| if command -v aws >/dev/null 2>&1; then | |
| echo "Using AWS CLI for ECR authentication..." | |
| aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin "$ECR_REGISTRY" || true | |
| else | |
| ECR_USERNAME="${{ secrets.REGISTRY_PULL_USERNAME || 'AWS' }}" | |
| ECR_PASSWORD="${{ secrets.REGISTRY_PULL_PASSWORD || '' }}" | |
| if [ -n "$ECR_PASSWORD" ]; then | |
| echo "Using provided ECR credentials..." | |
| echo "$ECR_PASSWORD" | docker login --username "$ECR_USERNAME" --password-stdin "$ECR_REGISTRY" || true | |
| else | |
| echo "⚠️ Warning: No ECR credentials provided, trying without authentication..." | |
| fi | |
| fi | |
| else | |
| echo "Image is in custom registry: $(echo $EXPECTED_IMAGE | cut -d'/' -f1)" | |
| REGISTRY_HOST=$(echo "$EXPECTED_IMAGE" | cut -d'/' -f1) | |
| ECR_USERNAME="${{ secrets.REGISTRY_PULL_USERNAME || '' }}" | |
| ECR_PASSWORD="${{ secrets.REGISTRY_PULL_PASSWORD || '' }}" | |
| # Authenticate with custom registry if credentials are provided | |
| if [ -n "$ECR_USERNAME" ] && [ -n "$ECR_PASSWORD" ]; then | |
| echo "Authenticating with custom registry: ${REGISTRY_HOST}" | |
| echo "$ECR_PASSWORD" | docker login --username "$ECR_USERNAME" --password-stdin "$REGISTRY_HOST" || true | |
| fi | |
| fi | |
| # Verify the image exists before deploying | |
| echo "" | |
| echo "Verifying image exists in registry..." | |
| if docker pull "$EXPECTED_IMAGE" 2>/dev/null; then | |
| echo "✅ Image found in registry: ${EXPECTED_IMAGE}" | |
| docker images | grep "$(echo $EXPECTED_IMAGE | cut -d':' -f2)" || true | |
| else | |
| echo "❌ ERROR: Image not found in registry: ${EXPECTED_IMAGE}" | |
| echo "" | |
| echo "Troubleshooting:" | |
| echo " 1. Check if image was pushed successfully in previous step" | |
| echo " 2. Verify registry URL matches: $(echo $EXPECTED_IMAGE | cut -d'/' -f1)" | |
| echo " 3. Check authentication credentials" | |
| echo " 4. Verify image tag: ${TAG}" | |
| echo " 5. List available images in registry:" | |
| docker images | head -10 || true | |
| exit 1 | |
| fi | |
| # Check if user can access docker without sudo | |
| if docker ps > /dev/null 2>&1; then | |
| echo "User has docker access, running amp-up2 without sudo" | |
| amp-up2 "$TAG" "$COUNTRY" "$DB_VERSION" "$PG_VERSION" | |
| elif sudo docker ps > /dev/null 2>&1; then | |
| echo "User needs sudo for docker, running amp-up2 with sudo" | |
| # If using sudo, authenticate with ECR using sudo as well | |
| if [ -n "$ECR_USERNAME" ] && [ -n "$ECR_PASSWORD" ]; then | |
| echo "$ECR_PASSWORD" | sudo docker login --username "$ECR_USERNAME" --password-stdin "$ECR_REGISTRY" || true | |
| fi | |
| sudo amp-up2 "$TAG" "$COUNTRY" "$DB_VERSION" "$PG_VERSION" | |
| else | |
| echo "❌ Cannot access Docker daemon. User may need to be added to docker group." | |
| echo "Run: sudo usermod -aG docker $USER" | |
| exit 1 | |
| fi | |
| DEPLOY_SCRIPT | |
| echo "✅ Deployment successful" | |
| - name: Cleanup Docker image | |
| if: always() | |
| run: | | |
| docker rmi "${{ env.IMAGE }}" || true | |