Role deduplication fails with `-‌-skip-tags always`

For Ansible 2.19, reduced to the following:

Playbook:

[…]
  roles:
  - role: mariadb
  - role: xyz  # actual product name changed
[…]

Roles:

$ cat roles/mariadb/meta/main.yml 
---
dependencies:
- role: mysql_mariadb_common
$ cat roles/xyz/meta/main.yml     
---
dependencies:
- role: mysql_mariadb_common

$ cat roles/mysql_mariadb_common/tasks/main.yml
---
- name: "DEBUG | discover roles : hosts mapping | role mysql_mariadb_common"
  ansible.builtin.debug:
    msg: "host {{ inventory_hostname_short }} has role mysql_mariadb_common"
  tags: ["has-roles", "has-role-mysql_mariadb_common"]
  delegate_to: localhost

When called as env ANSIBLE_GATHERING=explicit ansible-playbook -t has-roles --skip-tags always $playbookname, the mysql_mariadb_common role is ran twice (once before each of the depending roles).

Interesting :thinking:

I can reproduce this on 2.20 too. Shared role is invoked twice but only if --skip-tags always is specified. That one is the culprit.

This is as if skipping the always tag makes Ansible skip some internal hidden deduplicator task.

I personally use this pattern in my code but never encountered this problem… and now that I think, I can’t remember if I ever used --skip-tags always.

Thanks for reproducing and tracking this down!

I have a few always-tagged tasks (the one with the asserts (see above), which needs facts gathering for some hosts, and one that checks the clocktime of the controlled systems against the controlling node, etc.), and I want to skip these when I do a local-only thing like figuring out which hosts have which roles (this info gets collected in a dump file that gets committed as documentation), as this can run without needing to contact the targets (not all targets are even up normally).

Internally we flag a role_complete task with always so skipping that makes the ‘role not finished’ so it does not count for de duplication. Please open a bug report on github: Issues · ansible/ansible · GitHub

filed role deduplication not ran with `--skip-tags always` · Issue #87820 · ansible/ansible · GitHub

thanks