Last active
February 27, 2026 14:01
-
-
Save reijovosu/a14fb830829e20b2f427f9eb5ebb0b3d to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| --- | |
| # ansible-playbook -i localhost, -c local zsh-setup.yml -K | |
| # | |
| - name: Setup zsh + oh-my-zsh + plugins + hostname prompt (macOS + Linux) | |
| hosts: all | |
| gather_facts: true | |
| vars: | |
| # Configure for the SSH login user by default | |
| target_user: "{{ ansible_user_id }}" | |
| # Best-effort home defaults | |
| target_home: >- | |
| {{ (ansible_facts.os_family == 'Darwin') | |
| | ternary('/Users/' ~ target_user, '/home/' ~ target_user) }} | |
| zsh_path: /bin/zsh | |
| zsh_plugins: | |
| - { | |
| name: "zsh-syntax-highlighting", | |
| repo: "https://github.com/zsh-users/zsh-syntax-highlighting.git", | |
| } | |
| - { | |
| name: "zsh-autosuggestions", | |
| repo: "https://github.com/zsh-users/zsh-autosuggestions.git", | |
| } | |
| - { | |
| name: "zsh-completions", | |
| repo: "https://github.com/zsh-users/zsh-completions.git", | |
| } | |
| zsh_path_line: "export PATH=$HOME/bin:/usr/local/bin:$PATH" | |
| zsh_plugins_line: "plugins=(git zsh-completions zsh-autosuggestions zsh-syntax-highlighting)" | |
| # PROMPT modes: | |
| # A) Always hostname: | |
| zsh_prompt_line_hostname: "PROMPT='%{$fg_bold[green]%}➜%{$reset_color%} %{$fg_bold[blue]%}%m%{$reset_color%} %{$fg_bold[cyan]%}%~%{$reset_color%}${git_prompt_info:+ ${git_prompt_info}} %# '" | |
| # B) Show localhost when local, hostname when SSH: | |
| zsh_prompt_line_localhost: "PROMPT='%{$fg_bold[green]%}➜%{$reset_color%} %{$fg_bold[blue]%}${SSH_CONNECTION:+%m}${SSH_CONNECTION:-localhost}%{$reset_color%} %{$fg_bold[cyan]%}%~%{$reset_color%}${git_prompt_info:+ ${git_prompt_info}} %# '" | |
| # Choose which prompt you want: | |
| prompt_mode: "hostname" # or "localhost_when_local" | |
| do_apt_upgrade: false | |
| pre_tasks: | |
| - name: macOS - ensure Homebrew exists | |
| ansible.builtin.command: brew --version | |
| register: brew_version | |
| changed_when: false | |
| failed_when: false | |
| when: ansible_facts.os_family == "Darwin" | |
| - name: macOS - fail if Homebrew is missing | |
| ansible.builtin.fail: | |
| msg: "Homebrew not found on this Mac. Install Homebrew first, then re-run this play." | |
| when: ansible_facts.os_family == "Darwin" and brew_version.rc != 0 | |
| tasks: | |
| # ------------------------- | |
| # Packages: Linux (Debian/Ubuntu family) | |
| # ------------------------- | |
| - name: Linux - apt update | |
| ansible.builtin.apt: | |
| update_cache: true | |
| cache_valid_time: 3600 | |
| become: true | |
| when: ansible_facts.os_family == "Debian" | |
| - name: Linux - apt upgrade (optional) | |
| ansible.builtin.apt: | |
| upgrade: dist | |
| become: true | |
| when: ansible_facts.os_family == "Debian" and do_apt_upgrade | bool | |
| - name: Linux - install git and zsh | |
| ansible.builtin.apt: | |
| name: [git, zsh] | |
| state: present | |
| become: true | |
| when: ansible_facts.os_family == "Debian" | |
| # ------------------------- | |
| # Fix locale warnings on Debian/Ubuntu (perl / locale errors) | |
| # ------------------------- | |
| - name: Linux - ensure locales package installed | |
| ansible.builtin.apt: | |
| name: locales | |
| state: present | |
| update_cache: true | |
| become: true | |
| when: ansible_facts.os_family == "Debian" | |
| - name: Linux - ensure en_GB.UTF-8 locale is enabled in /etc/locale.gen | |
| ansible.builtin.lineinfile: | |
| path: /etc/locale.gen | |
| regexp: '^#?\s*en_GB\.UTF-8\s+UTF-8\s*$' | |
| line: 'en_GB.UTF-8 UTF-8' | |
| become: true | |
| when: ansible_facts.os_family == "Debian" | |
| - name: Linux - generate locales | |
| ansible.builtin.command: locale-gen | |
| register: locale_gen | |
| changed_when: "'Generating locales' in locale_gen.stdout or 'Generation complete' in locale_gen.stdout" | |
| become: true | |
| when: ansible_facts.os_family == "Debian" | |
| - name: Linux - set default system locale | |
| ansible.builtin.command: "update-locale LANG={{ linux_locale | default('en_GB.UTF-8') }} LC_ALL={{ linux_locale | default('en_GB.UTF-8') }}" | |
| become: true | |
| changed_when: false | |
| when: ansible_facts.os_family == "Debian" | |
| # ------------------------- | |
| # Packages: macOS (Homebrew) | |
| # ------------------------- | |
| - name: macOS - install git and zsh with Homebrew | |
| community.general.homebrew: | |
| name: [git, zsh] | |
| state: present | |
| when: ansible_facts.os_family == "Darwin" | |
| # ------------------------- | |
| # Set default shell to zsh | |
| # ------------------------- | |
| - name: Linux - ensure zsh is the user's login shell | |
| ansible.builtin.user: | |
| name: "{{ target_user }}" | |
| shell: "{{ zsh_path }}" | |
| become: true | |
| when: ansible_facts.os_family != "Darwin" | |
| - name: macOS - attempt to set login shell (may require extra rights) | |
| ansible.builtin.command: "chsh -s {{ zsh_path }} {{ target_user }}" | |
| changed_when: false | |
| failed_when: false | |
| when: ansible_facts.os_family == "Darwin" | |
| # ------------------------- | |
| # Oh My Zsh (idempotent via git) | |
| # ------------------------- | |
| - name: Clone oh-my-zsh | |
| ansible.builtin.git: | |
| repo: "https://github.com/ohmyzsh/ohmyzsh.git" | |
| dest: "{{ target_home }}/.oh-my-zsh" | |
| version: master | |
| update: true | |
| - name: Ensure ~/.zshrc exists (copy template if missing) | |
| ansible.builtin.copy: | |
| src: "{{ target_home }}/.oh-my-zsh/templates/zshrc.zsh-template" | |
| dest: "{{ target_home }}/.zshrc" | |
| remote_src: true | |
| owner: "{{ target_user }}" | |
| mode: "0644" | |
| force: false | |
| # ------------------------- | |
| # Plugins | |
| # ------------------------- | |
| - name: Ensure custom plugins directory exists | |
| ansible.builtin.file: | |
| path: "{{ target_home }}/.oh-my-zsh/custom/plugins" | |
| state: directory | |
| owner: "{{ target_user }}" | |
| mode: "0755" | |
| - name: Install zsh plugins | |
| ansible.builtin.git: | |
| repo: "{{ item.repo }}" | |
| dest: "{{ target_home }}/.oh-my-zsh/custom/plugins/{{ item.name }}" | |
| update: true | |
| loop: "{{ zsh_plugins }}" | |
| # ------------------------- | |
| # Update ~/.zshrc | |
| # ------------------------- | |
| - name: Ensure PATH line exists in ~/.zshrc | |
| ansible.builtin.lineinfile: | |
| path: "{{ target_home }}/.zshrc" | |
| regexp: '^export PATH=\$HOME/bin:/usr/local/bin:\$PATH$' | |
| line: "{{ zsh_path_line }}" | |
| create: true | |
| owner: "{{ target_user }}" | |
| mode: "0644" | |
| - name: Ensure plugins line includes your plugins | |
| ansible.builtin.lineinfile: | |
| path: "{{ target_home }}/.zshrc" | |
| regexp: '^plugins=\(' | |
| line: "{{ zsh_plugins_line }}" | |
| owner: "{{ target_user }}" | |
| - name: Ensure compinit line exists in ~/.zshrc | |
| ansible.builtin.lineinfile: | |
| path: "{{ target_home }}/.zshrc" | |
| regexp: "^autoload -U compinit && compinit$" | |
| line: "autoload -U compinit && compinit" | |
| insertafter: EOF | |
| owner: "{{ target_user }}" | |
| - name: Choose prompt line based on prompt_mode | |
| ansible.builtin.set_fact: | |
| chosen_prompt_line: >- | |
| {{ (prompt_mode == 'localhost_when_local') | |
| | ternary(zsh_prompt_line_localhost, zsh_prompt_line_hostname) }} | |
| - name: Ensure PROMPT line is set after oh-my-zsh loads | |
| ansible.builtin.lineinfile: | |
| path: "{{ target_home }}/.zshrc" | |
| regexp: "^PROMPT=" | |
| line: "{{ chosen_prompt_line }}" | |
| insertafter: '^source \$ZSH/oh-my-zsh\.sh' | |
| owner: "{{ target_user }}" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment