The asset-mirror loop derived the staging dir and gate from a task var named
role_name, but role_name is Ansible's reserved role-magic variable pinned to the
executing role (web-svc-cdn); the vars override was silently ignored. So every
found package-lock.json (web-app-dashboard, web-app-littlejs) evaluated the gate
as 'web-svc-cdn in groups' and staged into CDN_ASSET_STAGE/web-svc-cdn/, the
second overwriting the first. No per-role dir was created, so keycloak-js (only
in dashboard's lock) was never mirrored and the CDN served 404 for
/npm/keycloak-js@24.0.5/dist/keycloak.js, breaking dashboard OIDC and the shared
universal-logout e2e across every app.
Rename the loop var to manifest_role so the override takes effect: each manifest
stages under its real role dir and the gate 'manifest_role in groups' mirrors
only deployed asset providers. Drop the redundant CDN_FLAVOR default (always set
in vars/main.yml).
Verified: build_assets.sh over dashboard's manifest produces
npm/keycloak-js@24.0.5/dist/keycloak.js; an ansible repro shows role_name stays
'web-svc-cdn' while manifest_role resolves to 'web-app-dashboard'.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The mirror task staged package manifests for every role in the repo that ships
a package-lock.json, so a penpot deploy also pulled in unrelated apps such as
web-app-littlejs (nothing references its assets) and coupled every app's deploy
to their npm builds. Move the three staging steps into tasks/utils/stage_manifest.yml
and drive them from a single looped include gated on 'role_name in group_names',
so only the apps and dependent services actually deployed here are mirrored.
Collapses the per-task loop/when duplication to one include.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>