/
/
/
1- name: Install required system packages for dotfiles
2 package:
3 name:
4 - tmux
5 - git
6 - unzip
7 - curl
8 - wget
9 - fontconfig
10 - build-essential
11 - perl
12 state: present
13 become: true
14
15- name: Create dotfile parent directory structure
16 ansible.builtin.file:
17 path: "{{ dotfiles_dest | dirname }}"
18 state: directory
19 mode: '0755'
20 owner: "{{ my_user_username }}"
21 group: "{{ my_user_primary_group }}"
22 become: true
23
24- name: Check if dotfiles repo already exists
25 stat:
26 path: "{{ dotfiles_dest }}/.git"
27 register: dotfiles_repo_exists
28
29- name: Clone dotfiles repo (first time only)
30 git:
31 repo: "{{ dotfiles_repo }}"
32 dest: "{{ dotfiles_dest }}"
33 version: "{{ dotfiles_version }}"
34 accept_hostkey: yes
35 become: true
36 become_user: "{{ my_user_username }}"
37 when: not dotfiles_repo_exists.stat.exists
38
39- name: Update dotfiles repo (only if forced)
40 git:
41 repo: "{{ dotfiles_repo }}"
42 dest: "{{ dotfiles_dest }}"
43 version: "{{ dotfiles_version }}"
44 update: yes
45 force: yes
46 accept_hostkey: yes
47 become: true
48 become_user: "{{ my_user_username }}"
49 when: dotfiles_repo_exists.stat.exists and (dotfiles_force_update | default(false))
50
51- name: Make dotfiles installer executable
52 ansible.builtin.file:
53 path: "{{ dotfiles_run_from }}/{{ dotfiles_install_cmd }}"
54 mode: '0755'
55 become: true
56 become_user: "{{ my_user_username }}"
57
58- name: Check if dotfiles are already installed (idempotency check)
59 stat:
60 path: "/home/{{ my_user_username }}/.zshrc"
61 register: dotfiles_installed
62
63- name: Run dotfiles installer
64 args:
65 chdir: "{{ dotfiles_run_from }}"
66 shell: "timeout 1800 {{ dotfiles_install_cmd }}" # 30 minute timeout
67 become: true
68 become_user: "{{ my_user_username }}"
69 environment:
70 HOME: "/home/{{ my_user_username }}"
71 PATH: "/home/{{ my_user_username }}/.local/bin:/home/{{ my_user_username }}/.cargo/bin:{{ ansible_env.PATH }}"
72 USER: "{{ my_user_username }}"
73 CARGO_HOME: "/home/{{ my_user_username }}/.cargo"
74 RUSTUP_HOME: "/home/{{ my_user_username }}/.rustup"
75 DEBIAN_FRONTEND: noninteractive # Prevent interactive prompts
76 FORCE_UNSAFE_CONFIGURE: 1 # Skip some safety checks that may prompt
77 when: not dotfiles_installed.stat.exists or dotfiles_force_reinstall | default(false)
78 register: dotfiles_result
79 failed_when: dotfiles_result.rc != 0 and dotfiles_result.rc != 130 and dotfiles_result.rc != 124 # Allow Ctrl+C and timeout exits
80 ignore_errors: yes
81 async: 2000 # Allow up to 33+ minutes total
82 poll: 30 # Check every 30 seconds
83
84- name: Display dotfiles installation result
85 debug:
86 msg: |
87 {% if dotfiles_result is defined and dotfiles_result.rc is defined %}
88 {% if dotfiles_result.rc == 0 %}
89 â
Dotfiles installation completed successfully
90 {% elif dotfiles_result.rc == 124 %}
91 â±ï¸ Dotfiles installation timed out after 30 minutes
92 The installation may still be running in the background.
93 Check manually: ps aux | grep setup_dot
94 {% elif dotfiles_result.rc == 130 %}
95 â ï¸ Dotfiles installation was interrupted (Ctrl+C)
96 {% else %}
97 â Dotfiles installation encountered issues (exit code: {{ dotfiles_result.rc }})
98 {% endif %}
99
100 {% if dotfiles_result.stdout is defined and dotfiles_result.stdout | length > 0 %}
101 Output: {{ dotfiles_result.stdout }}
102 {% endif %}
103 {% if dotfiles_result.stderr is defined and dotfiles_result.stderr | length > 0 %}
104 Errors: {{ dotfiles_result.stderr }}
105 {% endif %}
106 {% elif dotfiles_installed.stat.exists and not (dotfiles_force_reinstall | default(false)) %}
107 â¹ï¸ Dotfiles installation skipped - already installed (.zshrc exists)
108 Use -e dotfiles_force_reinstall=true to reinstall
109 Use -e dotfiles_force_update=true to update repo with local modifications
110 {% else %}
111 â¹ï¸ Dotfiles installation was not executed
112 {% endif %}
113
114