diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml new file mode 100644 index 0000000..0561b8a --- /dev/null +++ b/.github/workflows/deploy.yml @@ -0,0 +1,90 @@ +name: Deploy ttl.sh (DRY RUN) + +on: + push: + branches: + - main + workflow_dispatch: # Manual trigger for emergencies + +concurrency: + group: deploy-production + cancel-in-progress: false # Don't cancel in-progress deploys + +jobs: + build-and-push: + name: Build & Push Images + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Install Doppler CLI + uses: dopplerhq/cli-action@v3 + + - name: Authenticate to GCP Artifact Registry + run: | + # Get GCP credentials from Doppler and configure Docker + doppler secrets get GCS_KEY_ENCODED --plain | base64 -d > /tmp/gcp-key.json + gcloud auth activate-service-account --key-file=/tmp/gcp-key.json + gcloud auth configure-docker us-east4-docker.pkg.dev --quiet + rm /tmp/gcp-key.json + env: + DOPPLER_TOKEN: ${{ secrets.DOPPLER_TOKEN }} + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Build images (dry run - no push) + run: | + docker compose build + echo "✅ Build succeeded - skipping push (dry run mode)" + env: + DOPPLER_TOKEN: ${{ secrets.DOPPLER_TOKEN }} + + deploy: + name: Deploy to Production + runs-on: ubuntu-latest + needs: build-and-push + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Install Doppler CLI + uses: dopplerhq/cli-action@v3 + + - name: Install Ansible + run: | + sudo apt-get update + sudo apt-get install -y ansible + ansible-galaxy collection install community.general google.cloud community.docker + + - name: Setup SSH key + run: | + mkdir -p ~/.ssh + echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_rsa + chmod 600 ~/.ssh/id_rsa + ssh-keyscan -H 178.156.198.215 >> ~/.ssh/known_hosts + + - name: Run Ansible deployment (dry run) + working-directory: ./ansible + env: + DOPPLER_TOKEN: ${{ secrets.DOPPLER_TOKEN }} + run: | + echo "🔍 Running Ansible in check mode (dry run - no changes will be made)" + ansible-playbook --check \ + -e "cloudflare_api_token=$(doppler secrets get CF_API_TOKEN --plain)" \ + -e "cloudflare_zone_id=$(doppler secrets get CF_ZONE_ID --plain)" \ + -e "cloudflare_email=$(doppler secrets get LE_EMAIL --plain)" \ + -e "le_email=$(doppler secrets get LE_EMAIL --plain)" \ + -e "gcloud_sa_email=$(doppler secrets get GOOGLE_APPLICATION_CREDENTIALS_EMAIL --plain)" \ + -e "gcloud_sa_key_json=$(doppler secrets get GCS_KEY_ENCODED --plain)" \ + -e "gcloud_registry_host=$(doppler secrets get GOOGLE_CLOUD_ARTIFACT_REGISTRY_URI --plain)" \ + -e "gcs_key_encoded=$(doppler secrets get GCS_KEY_ENCODED --plain)" \ + -e "hook_token=$(doppler secrets get HOOK_TOKEN --plain)" \ + -e "hook_uri=$(doppler secrets get HOOK_URI --plain)" \ + -e "redis_password=$(doppler secrets get REDIS_PASSWORD --plain)" \ + -e "rediscloud_url=$(doppler secrets get REDISCLOUD_URL --plain)" \ + -e "replreg_host=$(doppler secrets get REPLREG_HOST --plain)" \ + -e "replreg_secret=$(doppler secrets get REPLREG_SECRET --plain)" \ + -e "registry_url=$(doppler secrets get REGISTRY_URL --plain)" \ + playbooks/site.yml