From 0a798cf3b0748863eb5b87fc6ec9977e1f196749 Mon Sep 17 00:00:00 2001 From: JosueDev-afk Date: Tue, 2 Jun 2026 21:50:48 -0600 Subject: [PATCH] refactor: replace appleboy/ssh-action with native ssh command execution in deployment workflows --- .gitea/workflows/deploy-prod.yml | 47 +++++++++----- .gitea/workflows/deploy-staging.yml | 95 +++++++++++++++++++---------- 2 files changed, 96 insertions(+), 46 deletions(-) diff --git a/.gitea/workflows/deploy-prod.yml b/.gitea/workflows/deploy-prod.yml index 110d34e..bcd6df0 100644 --- a/.gitea/workflows/deploy-prod.yml +++ b/.gitea/workflows/deploy-prod.yml @@ -66,34 +66,52 @@ jobs: url: https://practicas.prod.kubistudio.cloud steps: - name: Deploy via SSH - uses: appleboy/ssh-action@v1.0.3 - with: - host: ${{ secrets.DEPLOY_HOST }} - username: ${{ secrets.DEPLOY_USERNAME }} - key: ${{ secrets.DEPLOY_SSH_KEY }} - script: | + run: | + set -euo pipefail + IMAGE_TAG="${{ needs.build-and-push.outputs.image_tag }}" + APP_VERSION="${{ needs.build-and-push.outputs.app_version }}" + + eval $(ssh-agent -s) + echo "${{ secrets.DEPLOY_SSH_KEY }}" | ssh-add - + + mkdir -p ~/.ssh + ssh-keyscan -H ${{ secrets.DEPLOY_HOST }} >> ~/.ssh/known_hosts 2>/dev/null + + # 1. Pasamos las variables como argumentos en el mismo orden + ssh ${{ secrets.DEPLOY_USERNAME }}@${{ secrets.DEPLOY_HOST }} bash -s \ + "${{ env.REGISTRY_URL }}" \ + "${{ env.IMAGE_NAME }}" \ + "${IMAGE_TAG}" \ + "${APP_VERSION}" \ + "${{ gitea.actor }}" \ + "${{ secrets.TOKEN }}" << 'EOF' set -euo pipefail + # 2. Las recibimos dentro de la sesión remota + REGISTRY_URL=$1 + IMAGE_NAME=$2 + IMAGE_TAG=$3 + APP_VERSION=$4 + GITEA_ACTOR=$5 + TOKEN=$6 + echo "Saving current image tag for rollback..." CURRENT_IMAGE=$(docker inspect cicd-prod --format '{{.Config.Image}}' 2>/dev/null || echo "") echo "Pulling image..." - echo "${{ secrets.TOKEN }}" | docker login ${{ env.REGISTRY_URL }} -u ${{ gitea.actor }} --password-stdin - docker pull ${{ env.REGISTRY_URL }}/${{ env.IMAGE_NAME }}:${{ needs.build-and-push.outputs.image_tag }} + echo "$TOKEN" | docker login $REGISTRY_URL -u $GITEA_ACTOR --password-stdin + docker pull $REGISTRY_URL/$IMAGE_NAME:$IMAGE_TAG echo "Stopping existing container..." docker stop cicd-prod 2>/dev/null || true docker rm cicd-prod 2>/dev/null || true echo "Starting new container..." - docker run -d \ - --name cicd-prod \ - --restart unless-stopped \ - -p 8083:80 \ + docker run -d --name cicd-prod --restart unless-stopped -p 8083:80 \ -e APP_ENV=production \ - -e APP_VERSION=${{ needs.build-and-push.outputs.app_version }} \ + -e APP_VERSION=${APP_VERSION} \ -e DEPLOY_TIME=$(date -u +"%Y-%m-%dT%H:%M:%SZ") \ - ${{ env.REGISTRY_URL }}/${{ env.IMAGE_NAME }}:${{ needs.build-and-push.outputs.image_tag }} + $REGISTRY_URL/$IMAGE_NAME:$IMAGE_TAG echo "Waiting for health check..." HEALTHY=false @@ -129,6 +147,7 @@ jobs: exit 1 fi + EOF release-notes: name: Release Notes diff --git a/.gitea/workflows/deploy-staging.yml b/.gitea/workflows/deploy-staging.yml index 7cdd3a1..fc04655 100644 --- a/.gitea/workflows/deploy-staging.yml +++ b/.gitea/workflows/deploy-staging.yml @@ -55,47 +55,78 @@ jobs: needs: build-and-push steps: - name: Deploy via SSH - uses: appleboy/ssh-action@v1.0.3 - with: - host: ${{ secrets.DEPLOY_HOST }} - username: ${{ secrets.DEPLOY_USERNAME }} - key: ${{ secrets.DEPLOY_SSH_KEY }} - script: | + run: | + set -euo pipefail + IMAGE_TAG="${{ needs.build-and-push.outputs.image_tag }}" + + eval $(ssh-agent -s) + echo "${{ secrets.DEPLOY_SSH_KEY }}" | ssh-add - + + mkdir -p ~/.ssh + ssh-keyscan -H ${{ secrets.DEPLOY_HOST }} >> ~/.ssh/known_hosts 2>/dev/null + + # 1. Pasamos las variables como argumentos en el mismo orden + ssh ${{ secrets.DEPLOY_USERNAME }}@${{ secrets.DEPLOY_HOST }} bash -s \ + "${{ env.REGISTRY_URL }}" \ + "${{ env.IMAGE_NAME }}" \ + "${IMAGE_TAG}" \ + "${{ gitea.sha }}" \ + "${{ gitea.actor }}" \ + "${{ gitea.run_id }}" \ + "${{ secrets.TOKEN }}" << 'EOF' set -euo pipefail - + + # 2. Las recibimos dentro de la sesión remota + REGISTRY_URL=$1 + IMAGE_NAME=$2 + IMAGE_TAG=$3 + GIT_SHA=$4 + GITEA_ACTOR=$5 + BUILD_NUMBER=$6 + TOKEN=$7 + + # Variables locales del script + GIT_BRANCH="staging" + BUILD_DATE=$(date -u +"%Y-%m-%dT%H:%M:%SZ") + echo "Pulling image..." - echo "${{ secrets.TOKEN }}" | docker login ${{ env.REGISTRY_URL }} -u ${{ gitea.actor }} --password-stdin - docker pull ${{ env.REGISTRY_URL }}/${{ env.IMAGE_NAME }}:${{ needs.build-and-push.outputs.image_tag }} - + echo "$TOKEN" | docker login $REGISTRY_URL -u $GITEA_ACTOR --password-stdin + docker pull $REGISTRY_URL/$IMAGE_NAME:$IMAGE_TAG + echo "Stopping existing container..." docker stop cicd-staging 2>/dev/null || true docker rm cicd-staging 2>/dev/null || true - + echo "Starting new container..." - docker run -d \ - --name cicd-staging \ - --restart unless-stopped \ - -p 8082:80 \ + docker run -d --name cicd-staging --restart unless-stopped -p 8082:80 \ -e APP_ENV=staging \ - -e APP_VERSION=staging-${{ gitea.sha }} \ - -e GIT_COMMIT=${{ gitea.sha }} \ - -e GIT_BRANCH=staging \ - -e BUILD_DATE=$(date -u +"%Y-%m-%dT%H:%M:%SZ") \ - -e DEPLOY_TIME=$(date -u +"%Y-%m-%dT%H:%M:%SZ") \ - -e BUILD_NUMBER=${{ gitea.run_id }} \ - ${{ env.REGISTRY_URL }}/${{ env.IMAGE_NAME }}:${{ needs.build-and-push.outputs.image_tag }} - - echo "Running smoke tests..." - RESPONSE=$(curl -sf http://localhost:8082/health) - echo "Health response: $RESPONSE" - - ENV_VALUE=$(echo "$RESPONSE" | python3 -c "import sys,json; print(json.load(sys.stdin)['env'])" 2>/dev/null || echo "unknown") - if [ "$ENV_VALUE" != "staging" ]; then - echo "::error::Smoke test failed: expected env=staging, got env=$ENV_VALUE" + -e APP_VERSION=staging-${GIT_SHA} \ + -e GIT_COMMIT=${GIT_SHA} \ + -e GIT_BRANCH=${GIT_BRANCH} \ + -e BUILD_DATE=${BUILD_DATE} \ + -e DEPLOY_TIME=${BUILD_DATE} \ + -e BUILD_NUMBER=${BUILD_NUMBER} \ + $REGISTRY_URL/$IMAGE_NAME:$IMAGE_TAG + + echo "Waiting for health check..." + HEALTHY=false + for i in $(seq 1 12); do + RESPONSE=$(curl -sf http://localhost:8082/health || echo "") + if [ -n "$RESPONSE" ]; then + ENV_VALUE=$(echo "$RESPONSE" | python3 -c "import sys,json; print(json.load(sys.stdin)['env'])" 2>/dev/null || echo "unknown") + if [ "$ENV_VALUE" = "staging" ]; then + echo "::notice::Staging smoke tests passed" + HEALTHY=true + break + fi + fi + sleep 5 + done + if [ "$HEALTHY" = false ]; then + echo "::error::Staging smoke tests/health check failed" exit 1 fi - - echo "::notice::Staging smoke tests passed" + EOF notify: name: Notification