Files
ci-cd/.gitea/workflows/deploy-asp-net-core.yml
T

88 lines
2.6 KiB
YAML

name: Reusable Deploy
on:
workflow_call:
inputs:
image_ref:
required: true
type: string
service_name:
required: true
type: string
port:
required: false
type: string
default: ''
timeout:
required: false
type: string
default: '120'
secrets:
SSH_HOST:
required: true
SSH_USER:
required: true
SSH_PRIVATE_KEY:
required: true
jobs:
deploy:
runs-on: docker-build
steps:
- name: Deploy
uses: appleboy/ssh-action@v1.2.0
with:
host: ${{ secrets.SSH_HOST }}
username: ${{ secrets.SSH_USER }}
key: ${{ secrets.SSH_PRIVATE_KEY }}
command_timeout: ${{ inputs.timeout }}m
script: |
set -u
SERVICE="${{ inputs.service_name }}"
IMAGE="${{ inputs.image_ref }}"
echo "🚀 Updating service $SERVICE with image $IMAGE..."
# Blocks until converged; auto-rolls back if the new tasks fail
if ! timeout "${{ inputs.timeout }}" docker service update \
--force \
--with-registry-auth \
--update-failure-action rollback \
--update-monitor 15s \
--image "$IMAGE" \
"$SERVICE"; then
echo "❌ docker service update failed or timed out after ${{ inputs.timeout }}s"
docker service ps "$SERVICE" --no-trunc
docker service logs --tail 50 "$SERVICE" || true
exit 1
fi
# Did THIS rollout succeed? (ignores old failed tasks in history)
STATE=$(docker service inspect "$SERVICE" \
--format '{{if .UpdateStatus}}{{.UpdateStatus.State}}{{end}}')
echo " Update state: ${STATE:-none}"
NEW_FAILED=$(docker service ps "$SERVICE" \
--format '{{.Image}} {{.CurrentState}}' \
| grep "^$IMAGE" | grep -c "Failed" || true)
if [ "$STATE" = "rollback_completed" ] || [ "$STATE" = "rollback_started" ] \
|| [ "$STATE" = "paused" ] || [ "$NEW_FAILED" -gt 0 ]; then
echo "❌ Rollout failed (state=$STATE, failed tasks on new image=$NEW_FAILED)"
docker service ps "$SERVICE" --no-trunc
docker service logs --tail 50 "$SERVICE" || true
exit 1
fi
REPLICAS=$(docker service ls --filter "name=$SERVICE" --format '{{.Replicas}}')
echo "✅ $SERVICE running ($REPLICAS) on $IMAGE"
echo "🎉 Deployment successful!"