88 lines
2.6 KiB
YAML
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!" |