Files
michaelschiemer/.gitea/workflows/manual-deploy.yml
Michael Schiemer 1963b10749 feat: Integrate Ansible playbooks into CI/CD workflows
- Add deploy-application-code.yml for Git-based code deployment
- Add install-composer-dependencies.yml for dependency installation
- Add deploy-image.yml for Docker image deployment
- Update build-image.yml to use Ansible playbooks
- Update manual-deploy.yml to use Ansible playbooks
- Add ANSIBLE_VAULT_PASSWORD secret handling
2025-11-07 18:14:11 +01:00

316 lines
11 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: Install Ansible
run: |
sudo apt-get update
sudo apt-get install -y ansible python3-pip
pip3 install --user ansible-core docker
- 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 Application Code to Staging
run: |
cd /workspace/repo/deployment/ansible
ansible-playbook -i inventory/production.yml \
playbooks/deploy-application-code.yml \
-e "deployment_environment=staging" \
-e "deployment_hosts=production" \
-e "git_branch=${{ steps.branch.outputs.BRANCH }}" \
--vault-password-file /tmp/vault_pass \
--private-key ~/.ssh/production
- name: Install Composer Dependencies
run: |
cd /workspace/repo/deployment/ansible
ansible-playbook -i inventory/production.yml \
playbooks/install-composer-dependencies.yml \
-e "deployment_environment=staging" \
--vault-password-file /tmp/vault_pass \
--private-key ~/.ssh/production
- name: Deploy Docker Image to Staging
run: |
cd /workspace/repo/deployment/ansible
ansible-playbook -i inventory/production.yml \
playbooks/deploy-image.yml \
-e "deployment_environment=staging" \
-e "deployment_hosts=production" \
-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: |
for i in {1..10}; do
if curl -f -k https://staging.michaelschiemer.de/health; then
echo "✅ Health check passed"
exit 0
fi
echo "⏳ Waiting for staging service... (attempt $i/10)"
sleep 10
done
echo "❌ Health check failed"
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
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: Install Ansible
run: |
sudo apt-get update
sudo apt-get install -y ansible python3-pip
pip3 install --user ansible-core docker
- 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 Application Code to Production
run: |
cd /workspace/repo/deployment/ansible
ansible-playbook -i inventory/production.yml \
playbooks/deploy-application-code.yml \
-e "deployment_environment=production" \
-e "deployment_hosts=production" \
-e "git_branch=${{ steps.branch.outputs.BRANCH }}" \
--vault-password-file /tmp/vault_pass \
--private-key ~/.ssh/production
- name: Install Composer Dependencies
run: |
cd /workspace/repo/deployment/ansible
ansible-playbook -i inventory/production.yml \
playbooks/install-composer-dependencies.yml \
-e "deployment_environment=production" \
--vault-password-file /tmp/vault_pass \
--private-key ~/.ssh/production
- name: Deploy Docker Image to Production
run: |
cd /workspace/repo/deployment/ansible
ansible-playbook -i inventory/production.yml \
playbooks/deploy-image.yml \
-e "deployment_environment=production" \
-e "deployment_hosts=production" \
-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: |
for i in {1..10}; do
if curl -f -k https://michaelschiemer.de/health; then
echo "✅ Health check passed"
exit 0
fi
echo "⏳ Waiting for production service... (attempt $i/10)"
sleep 10
done
echo "❌ Health check failed"
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 }}"