--- # Ansible Playbook: Setup Gitea Repository # Purpose: Automatically create repository in Gitea and configure Git remote # Usage: # ansible-playbook -i inventory/production.yml playbooks/setup-gitea-repository.yml \ # --vault-password-file secrets/.vault_pass \ # -e "repo_name=michaelschiemer" \ # -e "repo_owner=michael" \ # -e "repo_private=false" - name: Setup Gitea Repository hosts: production vars: ansible_connection: local gitea_url: "https://{{ gitea_domain | default('git.michaelschiemer.de') }}" gitea_admin_username: "{{ vault_gitea_admin_username | default('admin') }}" gitea_admin_password: "{{ vault_gitea_admin_password | default('') }}" tasks: - name: Set repository variables from parameters set_fact: repo_name: "{{ repo_name | default('michaelschiemer') }}" repo_owner: "{{ repo_owner | default('michael') }}" repo_private: "{{ repo_private | default(false) | bool }}" repo_description: "{{ repo_description | default('Main application repository') }}" repo_auto_init: "{{ repo_auto_init | default(false) | bool }}" configure_git_remote: "{{ configure_git_remote | default(true) | bool }}" git_repo_path: "{{ git_repo_path | default('/home/michael/dev/michaelschiemer') }}" - name: Verify Gitea is accessible uri: url: "{{ gitea_url }}" method: GET status_code: [200, 302, 502] validate_certs: false timeout: 10 register: gitea_health failed_when: false - name: Debug Gitea health status debug: msg: "Gitea health check returned status: {{ gitea_health.status }}" - name: Fail if Gitea is not accessible fail: msg: "Gitea is not accessible at {{ gitea_url }}. Status: {{ gitea_health.status }}. Please check if Gitea is running." when: gitea_health.status not in [200, 302, 502] - name: Check if API token exists in vault set_fact: has_vault_token: "{{ vault_git_token is defined and vault_git_token | length > 0 }}" no_log: true - name: Get or create Gitea API token uri: url: "{{ gitea_url }}/api/v1/users/{{ gitea_admin_username }}/tokens" method: POST user: "{{ gitea_admin_username }}" password: "{{ gitea_admin_password }}" body_format: json body: name: "ansible-repo-setup-{{ ansible_date_time.epoch }}" scopes: - write:repository - read:repository - admin:repo status_code: [201, 400, 401, 502] validate_certs: false force_basic_auth: yes register: api_token_result failed_when: false when: not has_vault_token no_log: true - name: Extract API token from response set_fact: gitea_api_token: "{{ api_token_result.json.sha1 | default('') }}" when: - not has_vault_token - api_token_result.status == 201 - api_token_result.json.sha1 is defined no_log: true - name: Use existing API token from vault set_fact: gitea_api_token: "{{ vault_git_token }}" when: has_vault_token no_log: true - name: Set flag to use basic auth if token creation failed set_fact: use_basic_auth: "{{ gitea_api_token | default('') | length == 0 }}" no_log: true - name: Fail if no authentication method available fail: msg: "Could not create or retrieve Gitea API token, and admin credentials are not available. Please create a token manually or set vault_git_token in vault." when: - use_basic_auth | bool - gitea_admin_password | default('') | length == 0 - name: Initialize repo_check variable set_fact: repo_check: {"status": 0} when: repo_check is not defined - name: Check if repository already exists (with token) uri: url: "{{ gitea_url }}/api/v1/repos/{{ repo_owner }}/{{ repo_name }}" method: GET headers: Authorization: "token {{ gitea_api_token }}" status_code: [200, 404, 502] validate_certs: false timeout: 10 register: repo_check_token when: not use_basic_auth failed_when: false - name: Set repo_check from token result set_fact: repo_check: "{{ repo_check_token }}" when: - not use_basic_auth - repo_check_token is defined - name: Check if repository already exists (with basic auth) uri: url: "{{ gitea_url }}/api/v1/repos/{{ repo_owner }}/{{ repo_name }}" method: GET user: "{{ gitea_admin_username }}" password: "{{ gitea_admin_password }}" status_code: [200, 404, 502] validate_certs: false force_basic_auth: yes timeout: 10 register: repo_check_basic when: use_basic_auth failed_when: false no_log: true - name: Set repo_check from basic auth result set_fact: repo_check: "{{ repo_check_basic }}" when: - use_basic_auth - repo_check_basic is defined - name: Debug repo_check status debug: msg: "Repository check - Status: {{ repo_check.status | default('undefined') }}, use_basic_auth: {{ use_basic_auth | default('undefined') }}" - name: Create repository in Gitea (with token) uri: url: "{{ gitea_url }}/api/v1/user/repos" method: POST headers: Authorization: "token {{ gitea_api_token }}" Content-Type: "application/json" body_format: json body: name: "{{ repo_name }}" description: "{{ repo_description }}" private: "{{ repo_private }}" auto_init: "{{ repo_auto_init }}" status_code: [201, 409, 502] validate_certs: false timeout: 10 register: repo_create_result when: - (repo_check.status | default(0)) in [404, 502, 0] - not use_basic_auth failed_when: false - name: Create repository in Gitea (with basic auth) uri: url: "{{ gitea_url }}/api/v1/user/repos" method: POST user: "{{ gitea_admin_username }}" password: "{{ gitea_admin_password }}" body_format: json body: name: "{{ repo_name }}" description: "{{ repo_description }}" private: "{{ repo_private }}" auto_init: "{{ repo_auto_init }}" status_code: [201, 409] validate_certs: false force_basic_auth: yes timeout: 10 register: repo_create_result when: - (repo_check.status | default(0)) != 200 - use_basic_auth no_log: true - name: Display repository creation result debug: msg: "Repository {{ repo_owner }}/{{ repo_name }} already exists or was created successfully" when: repo_check.status | default(0) == 200 or (repo_create_result is defined and repo_create_result.status | default(0) == 201) - name: Get repository clone URL set_fact: repo_clone_url: "{{ gitea_url | replace('https://', '') | replace('http://', '') }}/{{ repo_owner }}/{{ repo_name }}.git" repo_https_url: "https://{{ gitea_admin_username }}:{{ gitea_api_token }}@{{ gitea_url | replace('https://', '') | replace('http://', '') }}/{{ repo_owner }}/{{ repo_name }}.git" - name: Check if Git repository exists locally stat: path: "{{ git_repo_path }}/.git" register: git_repo_exists when: configure_git_remote | bool - name: Configure Git remote (local) command: > git remote set-url origin {{ repo_clone_url }} args: chdir: "{{ git_repo_path }}" register: git_remote_result when: - configure_git_remote | bool - git_repo_path is defined - git_repo_exists.stat.exists changed_when: git_remote_result.rc == 0 failed_when: false - name: Add Git remote if it doesn't exist command: > git remote add origin {{ repo_clone_url }} args: chdir: "{{ git_repo_path }}" register: git_remote_add_result when: - configure_git_remote | bool - git_repo_path is defined - git_repo_exists.stat.exists - git_remote_result.rc != 0 changed_when: git_remote_add_result.rc == 0 failed_when: false - name: Display success message debug: msg: - "✅ Repository created successfully!" - "Repository URL: {{ gitea_url }}/{{ repo_owner }}/{{ repo_name }}" - "Clone URL: {{ repo_clone_url }}" - "" - "Next steps:" - "1. Push your code: git push -u origin staging" - "2. Monitor pipeline: {{ gitea_url }}/{{ repo_owner }}/{{ repo_name }}/actions" - "" - "Note: If you need to push, you may need to authenticate with:" - " Username: {{ gitea_admin_username }}" - " Password: (use vault_gitea_admin_password or create a Personal Access Token)"