feat: add initial multi-environment CI/CD pipeline POC #1
@@ -66,34 +66,52 @@ jobs:
|
|||||||
url: https://practicas.prod.kubistudio.cloud
|
url: https://practicas.prod.kubistudio.cloud
|
||||||
steps:
|
steps:
|
||||||
- name: Deploy via SSH
|
- name: Deploy via SSH
|
||||||
uses: appleboy/ssh-action@v1.0.3
|
run: |
|
||||||
with:
|
set -euo pipefail
|
||||||
host: ${{ secrets.DEPLOY_HOST }}
|
IMAGE_TAG="${{ needs.build-and-push.outputs.image_tag }}"
|
||||||
username: ${{ secrets.DEPLOY_USERNAME }}
|
APP_VERSION="${{ needs.build-and-push.outputs.app_version }}"
|
||||||
key: ${{ secrets.DEPLOY_SSH_KEY }}
|
|
||||||
script: |
|
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
|
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..."
|
echo "Saving current image tag for rollback..."
|
||||||
CURRENT_IMAGE=$(docker inspect cicd-prod --format '{{.Config.Image}}' 2>/dev/null || echo "")
|
CURRENT_IMAGE=$(docker inspect cicd-prod --format '{{.Config.Image}}' 2>/dev/null || echo "")
|
||||||
|
|
||||||
echo "Pulling image..."
|
echo "Pulling image..."
|
||||||
echo "${{ secrets.TOKEN }}" | docker login ${{ env.REGISTRY_URL }} -u ${{ gitea.actor }} --password-stdin
|
echo "$TOKEN" | docker login $REGISTRY_URL -u $GITEA_ACTOR --password-stdin
|
||||||
docker pull ${{ env.REGISTRY_URL }}/${{ env.IMAGE_NAME }}:${{ needs.build-and-push.outputs.image_tag }}
|
docker pull $REGISTRY_URL/$IMAGE_NAME:$IMAGE_TAG
|
||||||
|
|
||||||
echo "Stopping existing container..."
|
echo "Stopping existing container..."
|
||||||
docker stop cicd-prod 2>/dev/null || true
|
docker stop cicd-prod 2>/dev/null || true
|
||||||
docker rm cicd-prod 2>/dev/null || true
|
docker rm cicd-prod 2>/dev/null || true
|
||||||
|
|
||||||
echo "Starting new container..."
|
echo "Starting new container..."
|
||||||
docker run -d \
|
docker run -d --name cicd-prod --restart unless-stopped -p 8083:80 \
|
||||||
--name cicd-prod \
|
|
||||||
--restart unless-stopped \
|
|
||||||
-p 8083:80 \
|
|
||||||
-e APP_ENV=production \
|
-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") \
|
-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..."
|
echo "Waiting for health check..."
|
||||||
HEALTHY=false
|
HEALTHY=false
|
||||||
@@ -129,6 +147,7 @@ jobs:
|
|||||||
|
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
EOF
|
||||||
|
|
||||||
release-notes:
|
release-notes:
|
||||||
name: Release Notes
|
name: Release Notes
|
||||||
|
|||||||
@@ -55,47 +55,78 @@ jobs:
|
|||||||
needs: build-and-push
|
needs: build-and-push
|
||||||
steps:
|
steps:
|
||||||
- name: Deploy via SSH
|
- name: Deploy via SSH
|
||||||
uses: appleboy/ssh-action@v1.0.3
|
run: |
|
||||||
with:
|
set -euo pipefail
|
||||||
host: ${{ secrets.DEPLOY_HOST }}
|
IMAGE_TAG="${{ needs.build-and-push.outputs.image_tag }}"
|
||||||
username: ${{ secrets.DEPLOY_USERNAME }}
|
|
||||||
key: ${{ secrets.DEPLOY_SSH_KEY }}
|
eval $(ssh-agent -s)
|
||||||
script: |
|
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
|
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 "Pulling image..."
|
||||||
echo "${{ secrets.TOKEN }}" | docker login ${{ env.REGISTRY_URL }} -u ${{ gitea.actor }} --password-stdin
|
echo "$TOKEN" | docker login $REGISTRY_URL -u $GITEA_ACTOR --password-stdin
|
||||||
docker pull ${{ env.REGISTRY_URL }}/${{ env.IMAGE_NAME }}:${{ needs.build-and-push.outputs.image_tag }}
|
docker pull $REGISTRY_URL/$IMAGE_NAME:$IMAGE_TAG
|
||||||
|
|
||||||
echo "Stopping existing container..."
|
echo "Stopping existing container..."
|
||||||
docker stop cicd-staging 2>/dev/null || true
|
docker stop cicd-staging 2>/dev/null || true
|
||||||
docker rm cicd-staging 2>/dev/null || true
|
docker rm cicd-staging 2>/dev/null || true
|
||||||
|
|
||||||
echo "Starting new container..."
|
echo "Starting new container..."
|
||||||
docker run -d \
|
docker run -d --name cicd-staging --restart unless-stopped -p 8082:80 \
|
||||||
--name cicd-staging \
|
|
||||||
--restart unless-stopped \
|
|
||||||
-p 8082:80 \
|
|
||||||
-e APP_ENV=staging \
|
-e APP_ENV=staging \
|
||||||
-e APP_VERSION=staging-${{ gitea.sha }} \
|
-e APP_VERSION=staging-${GIT_SHA} \
|
||||||
-e GIT_COMMIT=${{ gitea.sha }} \
|
-e GIT_COMMIT=${GIT_SHA} \
|
||||||
-e GIT_BRANCH=staging \
|
-e GIT_BRANCH=${GIT_BRANCH} \
|
||||||
-e BUILD_DATE=$(date -u +"%Y-%m-%dT%H:%M:%SZ") \
|
-e BUILD_DATE=${BUILD_DATE} \
|
||||||
-e DEPLOY_TIME=$(date -u +"%Y-%m-%dT%H:%M:%SZ") \
|
-e DEPLOY_TIME=${BUILD_DATE} \
|
||||||
-e BUILD_NUMBER=${{ gitea.run_id }} \
|
-e BUILD_NUMBER=${BUILD_NUMBER} \
|
||||||
${{ env.REGISTRY_URL }}/${{ env.IMAGE_NAME }}:${{ needs.build-and-push.outputs.image_tag }}
|
$REGISTRY_URL/$IMAGE_NAME:$IMAGE_TAG
|
||||||
|
|
||||||
echo "Running smoke tests..."
|
echo "Waiting for health check..."
|
||||||
RESPONSE=$(curl -sf http://localhost:8082/health)
|
HEALTHY=false
|
||||||
echo "Health response: $RESPONSE"
|
for i in $(seq 1 12); do
|
||||||
|
RESPONSE=$(curl -sf http://localhost:8082/health || echo "")
|
||||||
ENV_VALUE=$(echo "$RESPONSE" | python3 -c "import sys,json; print(json.load(sys.stdin)['env'])" 2>/dev/null || echo "unknown")
|
if [ -n "$RESPONSE" ]; then
|
||||||
if [ "$ENV_VALUE" != "staging" ]; then
|
ENV_VALUE=$(echo "$RESPONSE" | python3 -c "import sys,json; print(json.load(sys.stdin)['env'])" 2>/dev/null || echo "unknown")
|
||||||
echo "::error::Smoke test failed: expected env=staging, got env=$ENV_VALUE"
|
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
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
EOF
|
||||||
echo "::notice::Staging smoke tests passed"
|
|
||||||
|
|
||||||
notify:
|
notify:
|
||||||
name: Notification
|
name: Notification
|
||||||
|
|||||||
Reference in New Issue
Block a user