Add tests/lint/repository/test_name_emoji_and_length.py: every Ansible task
name and GitHub Actions workflow/job/step name must start with an emoji (first
char not 0-9/A-Za-z) and be <= 80 chars.
- emit emoji names at the source: cli/build/include generator now writes
"🔧 setup <app>" / "🚿 flush handlers after <app>" so generated
tasks/groups/*-roles.yml satisfy the convention too
- convert existing task/step/job/workflow names to emoji-prefixed, choosing a
task-fitting icon per action (📦 install, ✅ ensure, 🔍 probe, 🥾 bootstrap,
🚀 deploy, 🧩 service-module load, ⬇️ checkout, 📂 include-routines, ...)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add plugins/lookup/container_image.py: returns the full `image: "<ref>"`
line so templates drop the redundant image: prefix and surrounding
quotes. Supports `custom=True` to auto-construct `<entity_name>_custom`
for locally-built images, plus explicit `image=`/`version=` overrides
for exotic cases (taiga back-auth/front-oidc variants, decidim infinito
suffix, etc.).
* 25 unit tests for the lookup cover compose vs swarm prefix, custom
flag, overrides, tag_only=True, missing version warnings.
* New strict lint (tests/lint/.../test_no_raw_image_in_compose_templates)
fails on any raw `image:` line in roles/*/templates/*.j2 unless
nocheck-suppressed. Legacy `image: "{{ lookup(...) }}"` form no
longer accepted.
* Migrate 159 image refs across ~80 roles to the standalone
`{{ lookup('container_image', application_id, '<service_key>') }}`
form. 26 roles use `custom=True` (mariadb, postgres, openldap,
jenkins, jira, gitlab, nextcloud, mediawiki, shopware, wordpress,
odoo, joomla, openproject, bookwyrm, espocrm, hugo, littlejs,
fediwall, roulette-wheel, openresty, confluence and more).
* Fix svc-db-redis application_id leak: service.yml.j2 is included
into consuming roles where application_id evaluates to the outer
role, so the image lookup needs the hardcoded 'svc-db-redis'.
* Integration tests (test_templates_require_image,
test_build_requires_image) recognise the standalone lookup as an
implicit `image:` at the same indent.
* Mediawiki swarm tasks: add explicit `:{{ MEDIAWIKI_VERSION }}` to
the registry-prefixed image string because the custom var is now
bare.
Only 3 legitimate exotic nocheck-suppressed image lines remain:
matrix-mdad runner (nested services.matrix.runner.image path),
matrix mautrix bridges (per-iteration dynamic) and svc-registry-docker
(chicken-and-egg self-reference).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The IS_STACK_HOST gate in main.yml never blocked workers because
test-e2e-playwright does not set its own application_id, so DEPLOYMENT_MODE
fell through to 'compose' and IS_STACK_HOST evaluated true on every host.
Workers then ran 02_run_one.yml and crashed on the CA cert check because
the cert only exists on the manager.
Replace with block: + delegate_to: STACK_HOST + run_once: true so the
orchestration runs once on the primary manager regardless of which hosts
are in the play.
Also rename SWARM_PRIMARY_MANAGER -> STACK_HOST repo-wide to match the
existing IS_STACK_HOST symmetry and drop the swarm-specific terminology
(the variable falls back to inventory_hostname in compose mode).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Collapse two repeated swarm-vs-compose expressions into single-source-of-truth
group vars and apply across sys-svc-compose, web-app-mediawiki:
- SWARM_MANAGER_ACTIVE: true when DEPLOYMENT_MODE \!= 'swarm' or this host is
in svc-docker-swarm-manager. Used as the gate for "execute manager-only
deploy work here" (dir creation, file render, compose up, handler tasks).
- SWARM_PRIMARY_MANAGER: first svc-docker-swarm-manager or self under
compose-mode fallback. Used as delegate_to: for cluster-wide ops
(compose pull/build/up, swarm stack deploy, post-deploy DB health probe,
network create, MediaWiki one-shot install/admin).
Pure refactor — no semantic change. Subsequent edits to either expression
now live in one file.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The install + update + admin maintenance commands all run as throwaway
container instances against the custom image, with the live service's
bind mounts attached. The previous container exec-against-static-name
pattern stops working in swarm where the container name is a
per-replica swarm task id and the task itself can be reaped by the
healthcheck mid-update.
container_name is gated under swarm because docker-compose's strict
validation rejects it once replicas > 1. Cross-host config replication
in 01_configuration.yml is removed entirely: the play now runs natively
on every host in the role's group, so the LocalSettings.php / oidc.php
/ debug.php templates render in place per host.
Test inventory adds the pilot role to all three simulated swarm hosts,
which is what flips DEPLOYMENT_MODE to swarm under the new
inventory-driven model.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* scripts/lint/autoformat.sh:
- rename run_sort_claude_settings worker to run_claude (matches the
renamed scripts/lint/claude.sh).
- drop the EXIT trap that wiped status_dir; cleanup happens explicitly
after `wait` returns, so a parallel worker that interrupts the
parent never races a vanished status dir.
- each worker now captures its tool's exit code and writes one of
OK / SKIP / FAIL. Tolerated `expected violations remain`-style exits
(markdownlint-cli2 rc≤1, ansible-lint rc≤2) still count as OK; only
real failures count as FAIL.
- all workers run to completion regardless of individual tool failures
(so the user always sees the full picture); after the summary, the
script exits 1 if any worker reported FAIL.
* scripts/lint/sort_claude_settings.sh -> scripts/lint/claude.sh
(history preserved via git mv); update test_claude_settings_sorted.py
fix-hint accordingly.
Plus working-tree drift across roles/, group_vars/, inventories/,
requirements/, and .pre-commit-config.yaml accumulated from the
make-test setup phase regenerating generated artefacts during recent
test runs.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Remove early flush/notify logic from install step
- Stop triggering mediawiki update via handlers during extension setup
- Move mediawiki update logic from handler to tasks/03_update.yml
- Run update only when config/extensions/composer actually changed
- Rename admin task to keep ordered task flow (04_admin.yml)
https://chatgpt.com/share/69688a99-e940-800f-a961-96474fff8160
- Add 03_patch_settings.yml to sync $wgServer/$wgCanonicalServer, DB vars, and language
- Use single-quoted PHP strings with proper escaping; idempotent grep guards
- Wire task into main.yml; rename 03_admin→04_admin and 04_extensions→05_extensions
Ref: https://chatgpt.com/share/68c3649a-e830-800f-a059-fc8eda8f76bb