Files
michaelschiemer/deployment/ansible/roles/application/tasks/deploy_code.yml
Michael Schiemer 36ef2a1e2c
Some checks failed
🚀 Build & Deploy Image / Determine Build Necessity (push) Failing after 10m14s
🚀 Build & Deploy Image / Build Runtime Base Image (push) Has been skipped
🚀 Build & Deploy Image / Build Docker Image (push) Has been skipped
🚀 Build & Deploy Image / Run Tests & Quality Checks (push) Has been skipped
🚀 Build & Deploy Image / Auto-deploy to Staging (push) Has been skipped
🚀 Build & Deploy Image / Auto-deploy to Production (push) Has been skipped
Security Vulnerability Scan / Check for Dependency Changes (push) Failing after 11m25s
Security Vulnerability Scan / Composer Security Audit (push) Has been cancelled
fix: Gitea Traefik routing and connection pool optimization
- Remove middleware reference from Gitea Traefik labels (caused routing issues)
- Optimize Gitea connection pool settings (MAX_IDLE_CONNS=30, authentication_timeout=180s)
- Add explicit service reference in Traefik labels
- Fix intermittent 504 timeouts by improving PostgreSQL connection handling

Fixes Gitea unreachability via git.michaelschiemer.de
2025-11-09 14:46:15 +01:00

237 lines
8.8 KiB
YAML

---
# Deploy Application Code via Git or Rsync
- name: Set git_repo_url from provided value or default
ansible.builtin.set_fact:
git_repo_url: "{{ application_git_repository_url if (application_git_repository_url is defined and application_git_repository_url != '') else application_git_repository_url_default }}"
- name: Determine deployment method
ansible.builtin.set_fact:
deployment_method: "{{ application_deployment_method | default('git') }}"
when: application_deployment_method is not defined
- name: Ensure Git is installed (for Git deployment)
ansible.builtin.apt:
name: git
state: present
update_cache: no
become: yes
when: deployment_method == 'git'
- name: Ensure application code directory exists
ansible.builtin.file:
path: "{{ application_code_dest }}"
state: directory
owner: "{{ ansible_user }}"
group: "{{ ansible_user }}"
mode: '0755'
become: yes
# Git Deployment Tasks
- name: Check if repository already exists (Git)
ansible.builtin.stat:
path: "{{ application_code_dest }}/.git"
register: git_repo_exists
when: deployment_method == 'git'
- name: Check if destination directory exists (Git)
ansible.builtin.stat:
path: "{{ application_code_dest }}"
register: dest_dir_exists
when: deployment_method == 'git'
- name: Remove destination directory if it exists but is not a git repo (Git)
ansible.builtin.file:
path: "{{ application_code_dest }}"
state: absent
when:
- deployment_method == 'git'
- dest_dir_exists.stat.exists
- not git_repo_exists.stat.exists
become: yes
- name: Clone repository (if not exists) (Git)
ansible.builtin.git:
repo: "{{ git_repo_url }}"
dest: "{{ application_code_dest }}"
version: "{{ application_git_branch }}"
force: no
update: no
when:
- deployment_method == 'git'
- not git_repo_exists.stat.exists
environment:
GIT_TERMINAL_PROMPT: "0"
vars:
ansible_become: no
register: git_clone_result
retries: "{{ application_git_retries | default(5) }}"
delay: "{{ application_git_retry_delay | default(10) }}"
until: git_clone_result is succeeded
ignore_errors: yes
- name: Fail if git clone failed after retries (Git)
ansible.builtin.fail:
msg: "Failed to clone repository after {{ application_git_retries | default(5) }} retries. Gitea may be unreachable or overloaded. Last error: {{ git_clone_result.msg | default('Unknown error') }}"
when:
- deployment_method == 'git'
- not git_repo_exists.stat.exists
- git_clone_result is failed
- name: Check if repository is already on correct branch (Git)
ansible.builtin.shell: |
cd {{ application_code_dest }}
CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "")
TARGET_BRANCH="{{ application_git_branch | default('main') }}"
if [ "$CURRENT_BRANCH" = "$TARGET_BRANCH" ] || [ "$CURRENT_BRANCH" = "HEAD" ]; then
echo "ALREADY_ON_BRANCH"
else
echo "NEEDS_UPDATE"
fi
register: git_branch_check
changed_when: false
failed_when: false
when:
- deployment_method == 'git'
- git_repo_exists.stat.exists
- application_skip_git_update | default(false) | bool == false
- name: Update repository (if exists and not already on correct branch) (Git)
ansible.builtin.git:
repo: "{{ git_repo_url }}"
dest: "{{ application_code_dest }}"
version: "{{ application_git_branch }}"
force: yes
update: yes
when:
- deployment_method == 'git'
- git_repo_exists.stat.exists
- application_skip_git_update | default(false) | bool == false
- git_branch_check.stdout | default('NEEDS_UPDATE') == 'NEEDS_UPDATE'
environment:
GIT_TERMINAL_PROMPT: "0"
vars:
ansible_become: no
register: git_update_result
retries: "{{ application_git_retries | default(5) }}"
delay: "{{ application_git_retry_delay | default(10) }}"
until: git_update_result is succeeded
ignore_errors: yes
- name: Skip git update (repository already on correct branch or skip flag set)
ansible.builtin.debug:
msg: "Skipping git update - repository already on correct branch or skip_git_update is set"
when:
- deployment_method == 'git'
- git_repo_exists.stat.exists
- (application_skip_git_update | default(false) | bool == true) or (git_branch_check.stdout | default('NEEDS_UPDATE') == 'ALREADY_ON_BRANCH')
- name: Fail if git update failed after retries (Git)
ansible.builtin.fail:
msg: "Failed to update repository after {{ application_git_retries | default(5) }} retries. Gitea may be unreachable or overloaded. Last error: {{ git_update_result.msg | default('Unknown error') }}"
when:
- deployment_method == 'git'
- git_repo_exists.stat.exists
- application_skip_git_update | default(false) | bool == false
- git_branch_check.stdout | default('NEEDS_UPDATE') == 'NEEDS_UPDATE'
- git_update_result is defined
- git_update_result is failed
- name: Set ownership of repository files (Git)
ansible.builtin.file:
path: "{{ application_code_dest }}"
owner: "{{ ansible_user }}"
group: "{{ ansible_user }}"
recurse: yes
become: yes
when: deployment_method == 'git'
# Rsync Deployment Tasks
- name: Clear destination directory before sync (Rsync)
ansible.builtin.shell: |
# Remove all files and directories except .git (if it exists)
find {{ application_code_dest }} -mindepth 1 -maxdepth 1 -not -name '.git' -exec rm -rf {} + 2>/dev/null || true
become: yes
changed_when: true
failed_when: false
register: clear_result
when: deployment_method == 'rsync'
- name: Display clear status (Rsync)
ansible.builtin.debug:
msg: "Cleared destination directory before sync (preserved .git if present)"
when:
- deployment_method == 'rsync'
- clear_result.rc | default(0) == 0
- application_show_status | default(true) | bool
- name: Synchronize application code from repository root (Rsync)
ansible.builtin.synchronize:
src: "{{ application_rsync_source }}/"
dest: "{{ application_code_dest }}/"
delete: no
recursive: yes
rsync_opts: "{{ application_rsync_opts | default(['--chmod=D755,F644', '--exclude=.git', '--exclude=.gitignore', '--exclude=node_modules', '--exclude=vendor', '--exclude=.env', '--exclude=.env.*', '--exclude=*.log', '--exclude=.idea', '--exclude=.vscode', '--exclude=.DS_Store', '--exclude=*.swp', '--exclude=*.swo', '--exclude=*~', '--exclude=.phpunit.result.cache', '--exclude=coverage', '--exclude=.phpunit.cache', '--exclude=public/assets', '--exclude=storage/logs', '--exclude=storage/framework/cache', '--exclude=storage/framework/sessions', '--exclude=storage/framework/views', '--exclude=deployment', '--exclude=docker', '--exclude=.deployment-archive-*', '--exclude=docs', '--exclude=tests']) }}"
when: deployment_method == 'rsync'
delegate_to: localhost
run_once: true
- name: Ensure executable permissions on PHP scripts (Rsync)
ansible.builtin.file:
path: "{{ application_code_dest }}/{{ item }}"
mode: '0755'
loop: "{{ application_php_scripts | default(['worker.php', 'console.php']) }}"
when:
- deployment_method == 'rsync'
- item is defined
ignore_errors: yes
- name: Verify critical files exist (Rsync)
ansible.builtin.stat:
path: "{{ application_code_dest }}/{{ item }}"
register: critical_files_check
loop: "{{ application_critical_files | default(['worker.php', 'console.php', 'composer.json']) }}"
when: deployment_method == 'rsync'
- name: Display file verification results (Rsync)
ansible.builtin.debug:
msg: |
File Verification:
{% for result in critical_files_check.results | default([]) %}
- {{ result.item }}: {{ 'EXISTS' if result.stat.exists else 'MISSING' }}
{% endfor %}
when:
- deployment_method == 'rsync'
- application_show_status | default(true) | bool
- critical_files_check is defined
- name: Fail if critical files are missing (Rsync)
ansible.builtin.fail:
msg: |
Critical files are missing after sync:
{% for result in critical_files_check.results | default([]) %}
{% if not result.stat.exists %}- {{ result.item }}{% endif %}
{% endfor %}
when:
- deployment_method == 'rsync'
- critical_files_check is defined
- critical_files_check.results | selectattr('stat.exists', 'equalto', false) | list | length > 0
- name: Display deployment summary
ansible.builtin.debug:
msg: |
========================================
Application Code Deployment Summary
========================================
Method: {{ deployment_method | upper }}
Destination: {{ application_code_dest }}
{% if deployment_method == 'git' %}
Repository: {{ git_repo_url }}
Branch: {{ application_git_branch }}
{% elif deployment_method == 'rsync' %}
Source: {{ application_rsync_source }}
{% endif %}
========================================
when: application_show_status | default(true) | bool