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
- 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
237 lines
8.8 KiB
YAML
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
|
|
|