Files
michaelschiemer/deployment/legacy/gitea-workflows/manual-deploy.yml
2025-11-24 21:28:25 +01:00

287 lines
9.9 KiB
YAML
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
name: 🚀 Manual Deployment
run-name: Manual Deploy - ${{ inputs.environment }} - ${{ inputs.image_tag || 'latest' }}
on:
workflow_dispatch:
inputs:
environment:
description: 'Deployment environment'
required: true
type: choice
options:
- staging
- production
image_tag:
description: 'Image tag to deploy (e.g. abc1234-1696234567, git-abc1234). Leave empty for latest'
required: false
type: string
default: ''
branch:
description: 'Branch to checkout (default: main for production, staging for staging)'
required: false
type: string
default: ''
env:
REGISTRY: registry.michaelschiemer.de
IMAGE_NAME: framework
DEPLOYMENT_HOST: 94.16.110.151
jobs:
determine-image:
name: Determine Deployment Image
runs-on: ubuntu-latest
outputs:
image_url: ${{ steps.image.outputs.image_url }}
image_tag: ${{ steps.image.outputs.image_tag }}
registry_host: ${{ env.REGISTRY }}
image_name: ${{ env.IMAGE_NAME }}
steps:
- name: Determine image to deploy
id: image
shell: bash
run: |
REGISTRY="${{ env.REGISTRY }}"
IMAGE_NAME="${{ env.IMAGE_NAME }}"
INPUT_TAG="${{ inputs.image_tag }}"
if [ -z "$INPUT_TAG" ] || [ "$INPUT_TAG" = "" ]; then
IMAGE_TAG="latest"
else
IMAGE_TAG="$INPUT_TAG"
fi
IMAGE_URL="${REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG}"
echo "image_url=${IMAGE_URL}" >> "$GITHUB_OUTPUT"
echo "image_tag=${IMAGE_TAG}" >> "$GITHUB_OUTPUT"
echo "📦 Deployment Image:"
echo " URL: ${IMAGE_URL}"
echo " Tag: ${IMAGE_TAG}"
echo ""
echo " Image will be validated during deployment"
deploy-staging:
name: Deploy to Staging
needs: determine-image
if: inputs.environment == 'staging'
runs-on: ubuntu-latest
environment:
name: staging
url: https://staging.michaelschiemer.de
steps:
- name: Determine branch name
id: branch
shell: bash
run: |
INPUT_BRANCH="${{ inputs.branch }}"
if [ -z "$INPUT_BRANCH" ] || [ "$INPUT_BRANCH" = "" ]; then
REF_NAME="staging"
else
REF_NAME="$INPUT_BRANCH"
fi
echo "BRANCH=$REF_NAME" >> $GITHUB_OUTPUT
echo "📋 Branch: $REF_NAME"
- name: Checkout deployment scripts
run: |
REF_NAME="${{ steps.branch.outputs.BRANCH }}"
REPO="${{ github.repository }}"
if [ -n "${{ secrets.CI_TOKEN }}" ]; then
git clone --depth 1 --branch "$REF_NAME" \
"https://${{ secrets.CI_TOKEN }}@git.michaelschiemer.de/${REPO}.git" \
/workspace/repo
else
git clone --depth 1 --branch "$REF_NAME" \
"https://git.michaelschiemer.de/${REPO}.git" \
/workspace/repo || \
git clone --depth 1 \
"https://git.michaelschiemer.de/${REPO}.git" \
/workspace/repo
fi
cd /workspace/repo
- name: Setup SSH key
run: |
mkdir -p ~/.ssh
echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/production
chmod 600 ~/.ssh/production
ssh-keyscan -H ${{ env.DEPLOYMENT_HOST }} >> ~/.ssh/known_hosts
- name: Create Ansible Vault password file
run: |
if [ -n "${{ secrets.ANSIBLE_VAULT_PASSWORD }}" ]; then
echo "${{ secrets.ANSIBLE_VAULT_PASSWORD }}" > /tmp/vault_pass
chmod 600 /tmp/vault_pass
echo "✅ Vault password file created"
else
echo "⚠️ ANSIBLE_VAULT_PASSWORD secret not set, using empty password file"
touch /tmp/vault_pass
chmod 600 /tmp/vault_pass
fi
- name: Deploy to Staging (Complete)
run: |
cd /workspace/repo/deployment/ansible
ansible-playbook -i inventory/production.yml \
playbooks/deploy-complete.yml \
-e "deployment_environment=staging" \
-e "deployment_hosts=production" \
-e "git_branch=${{ steps.branch.outputs.BRANCH }}" \
-e "image_tag=${{ needs.determine-image.outputs.image_tag }}" \
-e "docker_registry=${{ needs.determine-image.outputs.registry_host }}" \
-e "docker_registry_username=${{ secrets.REGISTRY_USER }}" \
-e "docker_registry_password=${{ secrets.REGISTRY_PASSWORD }}" \
--vault-password-file /tmp/vault_pass \
--private-key ~/.ssh/production
- name: Wait for deployment to stabilize
run: sleep 30
- name: Health check
id: health
run: |
echo "🔍 Performing health checks with exponential backoff..."
DELAY=2
MAX_DELAY=60
MAX_ATTEMPTS=5
for i in $(seq 1 $MAX_ATTEMPTS); do
if curl -f -k -s https://staging.michaelschiemer.de/health > /dev/null 2>&1; then
echo "✅ Health check passed (attempt $i/$MAX_ATTEMPTS)"
exit 0
fi
if [ $i -lt $MAX_ATTEMPTS ]; then
echo "⏳ Waiting for staging service... (attempt $i/$MAX_ATTEMPTS, delay ${DELAY}s)"
sleep $DELAY
DELAY=$((DELAY * 2))
[ $DELAY -gt $MAX_DELAY ] && DELAY=$MAX_DELAY
fi
done
echo "❌ Health check failed after $MAX_ATTEMPTS attempts"
exit 1
- name: Notify deployment success
if: success()
run: |
echo "🚀 Staging deployment successful!"
echo "URL: https://staging.michaelschiemer.de"
echo "Image: ${{ needs.determine-image.outputs.image_url }}"
deploy-production:
name: Deploy to Production
needs: determine-image
if: inputs.environment == 'production'
runs-on: ubuntu-latest
concurrency:
group: deploy-production
cancel-in-progress: false
environment:
name: production
url: https://michaelschiemer.de
steps:
- name: Determine branch name
id: branch
shell: bash
run: |
INPUT_BRANCH="${{ inputs.branch }}"
if [ -z "$INPUT_BRANCH" ] || [ "$INPUT_BRANCH" = "" ]; then
REF_NAME="main"
else
REF_NAME="$INPUT_BRANCH"
fi
echo "BRANCH=$REF_NAME" >> $GITHUB_OUTPUT
echo "📋 Branch: $REF_NAME"
- name: Checkout deployment scripts
run: |
REF_NAME="${{ steps.branch.outputs.BRANCH }}"
REPO="${{ github.repository }}"
if [ -n "${{ secrets.CI_TOKEN }}" ]; then
git clone --depth 1 --branch "$REF_NAME" \
"https://${{ secrets.CI_TOKEN }}@git.michaelschiemer.de/${REPO}.git" \
/workspace/repo
else
git clone --depth 1 --branch "$REF_NAME" \
"https://git.michaelschiemer.de/${REPO}.git" \
/workspace/repo || \
git clone --depth 1 \
"https://git.michaelschiemer.de/${REPO}.git" \
/workspace/repo
fi
cd /workspace/repo
- name: Setup SSH key
run: |
mkdir -p ~/.ssh
echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/production
chmod 600 ~/.ssh/production
ssh-keyscan -H ${{ env.DEPLOYMENT_HOST }} >> ~/.ssh/known_hosts
- name: Create Ansible Vault password file
run: |
if [ -n "${{ secrets.ANSIBLE_VAULT_PASSWORD }}" ]; then
echo "${{ secrets.ANSIBLE_VAULT_PASSWORD }}" > /tmp/vault_pass
chmod 600 /tmp/vault_pass
echo "✅ Vault password file created"
else
echo "⚠️ ANSIBLE_VAULT_PASSWORD secret not set, using empty password file"
touch /tmp/vault_pass
chmod 600 /tmp/vault_pass
fi
- name: Deploy to Production (Complete)
run: |
cd /workspace/repo/deployment/ansible
ansible-playbook -i inventory/production.yml \
playbooks/deploy-complete.yml \
-e "deployment_environment=production" \
-e "deployment_hosts=production" \
-e "git_branch=${{ steps.branch.outputs.BRANCH }}" \
-e "image_tag=${{ needs.determine-image.outputs.image_tag }}" \
-e "docker_registry=${{ needs.determine-image.outputs.registry_host }}" \
-e "docker_registry_username=${{ secrets.REGISTRY_USER }}" \
-e "docker_registry_password=${{ secrets.REGISTRY_PASSWORD }}" \
--vault-password-file /tmp/vault_pass \
--private-key ~/.ssh/production
- name: Wait for deployment to stabilize
run: sleep 30
- name: Health check
id: health
run: |
echo "🔍 Performing health checks with exponential backoff..."
DELAY=2
MAX_DELAY=60
MAX_ATTEMPTS=5
for i in $(seq 1 $MAX_ATTEMPTS); do
if curl -f -k -s https://michaelschiemer.de/health > /dev/null 2>&1; then
echo "✅ Health check passed (attempt $i/$MAX_ATTEMPTS)"
exit 0
fi
if [ $i -lt $MAX_ATTEMPTS ]; then
echo "⏳ Waiting for production service... (attempt $i/$MAX_ATTEMPTS, delay ${DELAY}s)"
sleep $DELAY
DELAY=$((DELAY * 2))
[ $DELAY -gt $MAX_DELAY ] && DELAY=$MAX_DELAY
fi
done
echo "❌ Health check failed after $MAX_ATTEMPTS attempts"
exit 1
- name: Notify deployment success
if: success()
run: |
echo "🚀 Production deployment successful!"
echo "URL: https://michaelschiemer.de"
echo "Image: ${{ needs.determine-image.outputs.image_url }}"