diff --git a/roles/dev_env/molecule/default/converge.yml b/roles/dev_env/molecule/default/converge.yml index cf2227a..6539769 100644 --- a/roles/dev_env/molecule/default/converge.yml +++ b/roles/dev_env/molecule/default/converge.yml @@ -7,9 +7,38 @@ dev_env__users: - tester pre_tasks: + # `always` so the test user exists even under a partial `--tags` converge. - name: Create a test user to receive the environment ansible.builtin.user: name: tester create_home: true + tags: [always] roles: - role: dev_env + +# Partial-tags regression guard (O8): apply only the `config` concern to a fresh user. +# The dev_env__home preflight is tagged `always`, so a config-only run must still resolve +# the home dir and stow the dotfiles. Run the true partial path with: +# molecule converge -- --tags config +# (a full `molecule test` runs every tag, which still exercises this play idempotently). +- name: Converge — config concern only, fresh user + hosts: all + become: true + gather_facts: true + vars: + dev_env__users: + - tagtester + pre_tasks: + # `always` so the test user exists even under a partial `--tags config` converge. + - name: Create a second test user for the config-only path + ansible.builtin.user: + name: tagtester + create_home: true + tags: [always] + tasks: + - name: Apply dev_env restricted to the config concern + ansible.builtin.include_role: + name: dev_env + apply: + tags: [config] + tags: [config] diff --git a/roles/dev_env/molecule/default/verify.yml b/roles/dev_env/molecule/default/verify.yml index 04ac53a..7ebd832 100644 --- a/roles/dev_env/molecule/default/verify.yml +++ b/roles/dev_env/molecule/default/verify.yml @@ -71,3 +71,18 @@ - dev_env__dots.results[3].stat.exists - dev_env__dots.results[4].stat.exists fail_msg: dotfiles not stowed or omz/tpm not cloned + + # Partial-tags regression guard (O8): the config-only converge play provisioned + # `tagtester`. Its stowed .zshrc proves dev_env__home resolved (the `always` preflight) + # and stow (a `config` task) ran without the `users`/`packages` concerns. + - name: Stat the config-only user's stowed .zshrc + ansible.builtin.stat: + path: /home/tagtester/.zshrc + register: dev_env__tagtester_zshrc + + - name: Assert the config concern alone resolved home and stowed dotfiles + ansible.builtin.assert: + that: + - dev_env__tagtester_zshrc.stat.exists + - dev_env__tagtester_zshrc.stat.islnk + fail_msg: config-only run did not resolve dev_env__home / stow dotfiles for tagtester diff --git a/roles/dev_env/tasks/main.yml b/roles/dev_env/tasks/main.yml index 6e15ee6..ce9b6eb 100644 --- a/roles/dev_env/tasks/main.yml +++ b/roles/dev_env/tasks/main.yml @@ -7,21 +7,40 @@ cache_valid_time: 3600 tags: [packages] +# `apply: tags:` propagates the concern tag onto the INCLUDED tasks — without it a tag on +# a dynamic include_tasks only selects the include itself, not its (untagged) contents, so +# `--tags ` would run nothing (Ansible gotcha; mirrors roles/base/tasks/main.yml). - name: Install Neovim (pinned release) - ansible.builtin.include_tasks: neovim.yml + ansible.builtin.include_tasks: + file: neovim.yml + apply: + tags: [packages] tags: [packages] - name: Install oh-my-posh prompt (pinned release) - ansible.builtin.include_tasks: oh_my_posh.yml + ansible.builtin.include_tasks: + file: oh_my_posh.yml + apply: + tags: [packages] tags: [packages] - name: Install Node.js (pinned release) - ansible.builtin.include_tasks: nodejs.yml + ansible.builtin.include_tasks: + file: nodejs.yml + apply: + tags: [packages] tags: [packages] +# per_user.yml resolves dev_env__home (tagged `always`, below) then runs both the `users` +# (login shell) and `config` (dotfiles/stow) concerns; tag + apply both so either +# `--tags users` or `--tags config` reaches in and the home-dir preflight always runs. - name: Configure each developer user - ansible.builtin.include_tasks: per_user.yml + ansible.builtin.include_tasks: + file: per_user.yml + apply: + tags: [users, config] loop: "{{ dev_env__users }}" loop_control: loop_var: dev_env__user label: "{{ dev_env__user }}" + tags: [users, config] diff --git a/roles/dev_env/tasks/per_user.yml b/roles/dev_env/tasks/per_user.yml index 6a69705..e0b854c 100644 --- a/roles/dev_env/tasks/per_user.yml +++ b/roles/dev_env/tasks/per_user.yml @@ -1,12 +1,17 @@ --- +# `always`: dev_env__home must resolve on every entry into per_user.yml, including a +# partial `--tags users` or `--tags config` run — the dotfile/stow (config) and login-shell +# (users) tasks below all depend on it, so it must never be filtered out (ADR-019). - name: Look up account for {{ dev_env__user }} ansible.builtin.getent: database: passwd key: "{{ dev_env__user }}" + tags: [always] - name: Resolve home directory for {{ dev_env__user }} ansible.builtin.set_fact: dev_env__home: "{{ getent_passwd[dev_env__user][4] }}" + tags: [always] - name: Set login shell to zsh for {{ dev_env__user }} ansible.builtin.user: