Commit Graph
14 Commits
Author SHA1 Message Date
kevinveenbirkenbachandClaude Opus 4.8 4039313266 refactor(tasks): enforce and apply a single task-file numbering scheme
Add tests/lint/repository/test_task_file_numbering.py: numbered task
files use exactly two leading digits, a numbered *_core.yml must be
00_core.yml, per directory the numbers are unique/consecutive and start
at 01 (00 with a core file), numbered includes appear in ascending
order, and shared helpers live in tasks/utils/ instead of the numbered
chain.

Apply it across every role: rename NN_core.yml to 00_core.yml with a
consecutive down-shift of the siblings, move letter-suffix children into
a subdirectory named after their parent task, relocate helpers included
from more than one place into tasks/utils/, and update every reference
(include_tasks, path_absolute, .ansible-lint-ignore, requirement docs).
Legacy narration comments in the touched files are deleted; the upstream
xwiki.properties reference block opts out via nocheck. The unused
MAILU_IP6_PUBLIC var (only ever named in now-removed comments) is dropped.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-23 20:01:31 +02:00
kevinveenbirkenbachandClaude Fable 5 40e553069d refactor(structure): nest prefix-grouped sibling files into subfolders
Move files that share a delimiter-bounded name prefix within a folder (threshold 2) into a subfolder named after the prefix, dropping the prefix from the filename. Covers plugins/filter (docker, generate, has, merge, get/all), env handler subpackages, utils/roles/entity, utils/tests/swarm/write, role SQL/scripts/templates, keycloak/mailu task-includes, shared tasks/utils/load, and CI scripts. Update every import, query_file/script/include_tasks/src/lookup target, compose bind mount, and python -m path to the new locations.

Extend the prefix-grouped-files lint to threshold 2 with dir-level .nocheck and file-head nocheck opt-outs, and skip groups whose shortest member's stem equals the shared prefix. Keep flat only where a loader forbids nesting: WordPress mu-plugins and the docs/requirements namespace. Ansible filter discovery is recursive, so nested filters stay Jinja-resolvable.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-14 20:00:03 +02:00
kevinveenbirkenbachandClaude Opus 4.8 cddb0dc59b feat(lint): require emoji-prefixed task/step/job names + convert existing
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>
2026-06-28 22:45:06 +02:00
kevinveenbirkenbachandClaude Opus 4.7 222cc4015b refactor(web-app-xwiki): extract inline XML payloads + SPOT admin-group page
Six ``uri_retry`` tasks under ``roles/web-app-xwiki/tasks/`` carried
their XML payload as inline ``body: |`` blocks (CheckExtension Groovy
page, InstallExtensions Groovy page, the administrator user-page
PUT/POST pair, and the post-Fix-#8 XWikiAdminGroup PUT/POST pair).
Inline XML mixes Ansible YAML indentation with Jinja control flow
(``{% raw %}``-escaping for ``{{groovy}}`` delimiters), defeats
editor XML support, and silently rots when a future contributor
copy/edits the snippet without realising the surrounding ``body: |``
context.

Split by concern:

- ``templates/xml/*.xml.j2`` — six XML files that embed Jinja:
  ``user_page``, ``user_xwikiusers_object``,
  ``xwiki_admin_group_page``, ``xwiki_admin_group_member_object``,
  ``install_extensions_page``, ``main_webhome_page`` (the last one
  was already a template; moved here for symmetry with the new five).
- ``files/xml/check_extension_page.xml`` — fully static; rewritten
  without ``{% raw %}{{groovy}}{% endraw %}`` because the file is
  served via ``lookup('file', …)`` (no Jinja pass), so ``{{groovy}}``
  reaches XWiki literally.

Task references migrate to ``body: "{{ lookup('template',
'xml/<name>.xml.j2') }}"`` (or ``lookup('file', 'xml/<name>.xml')``
for the static case), normalising the previously bespoke long-form
``roles/web-app-xwiki/templates/main_webhome_page.xml.j2`` lookup in
the bargain.

SPOT-extract the magic string ``XWikiAdminGroup``:

- ``XWIKI_ADMIN_GROUP_PAGE: "XWikiAdminGroup"`` in vars/main.yml,
  documented as the page-name part used by REST URLs, the
  XAR-shipped page, the LDAP ``group_mapping`` argument, and the
  OIDC ``groups.mapping`` argument.
- Five call sites updated to ``{{ XWIKI_ADMIN_GROUP_PAGE }}`` or
  bare ``XWIKI_ADMIN_GROUP_PAGE`` inside list contexts:
  ``tasks/03_administrator.yml`` (×4 — two task names, the PUT URL,
  the POST URL), ``templates/xml/xwiki_admin_group_page.xml.j2``,
  ``templates/compose.yml.j2`` (LDAP group_mapping), and
  ``templates/xwiki.properties.j2`` (OIDC groups.mapping, in a
  commented example).

Lint guard: new ``tests/lint/ansible/tasks/test_no_inline_xml_body.py``
scans every ``roles/`` and ``tasks/`` YAML for ``body: |`` (or
``body: >``) folded scalars whose first content line starts with
``<`` and fails with a pointer at the matching ``templates/xml/...``
or ``files/xml/...`` alternative. JSON / shell / SQL bodies stay
allowed. Per-task opt-out: ``# nocheck: inline-xml-body`` on the
``body:`` line or the line above. Five unit tests cover the
scanner: matches XML body, ignores JSON body, honours same-line
nocheck, honours line-above nocheck, repo-wide sweep clean after
this refactor.

XWiki v17.10.8 distribution-merge behaviour was cross-checked
against upstream (``AbstractXarEntryType.upgradeType =
THREEWAYS``); the empty ``<member/>`` placeholder in the
XAR-shipped ``XWikiAdminGroup`` cannot overwrite our explicitly-added
member (different GUID / number).

``make test`` green across all 5 targets.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-26 13:25:15 +02:00
kevinveenbirkenbachandClaude Opus 4.7 dc79ee8f73 fix(web-app-xwiki): PUT-create XWikiAdminGroup before member POST
`XWIKI | Ensure user is in XWikiAdminGroup` POSTed
`<XWiki.XWikiGroups>{<member>XWiki.administrator</member>}</…>` to
`POST /rest/wikis/xwiki/spaces/XWiki/pages/XWikiAdminGroup/objects`,
hit HTTP 404 31 retries in a row, and aborted the deploy (job
77797115264 on run 26428083128, debian/no-SSO variant).

XWiki's REST `…/pages/<name>/objects` resource resolves the parent
page first; a 404 means the page document does not exist yet. The
admin-group page ships in
`xwiki-platform-distribution-ui-base/.../XWikiAdminGroup.xml` and is
materialised by the XWiki Distribution Job on first boot. The
Distribution Job did not finish materialising it before the
administrator-bootstrap step fired in this run — log evidence:
`XWiki.administrator` user-page POST 201 at 08:24:41 (line 487473),
group POST 404 at 10:09:27 (line 487745), no
`XWikiAdminGroup` PUT/import in between.

Mirror the pattern already used two tasks above for the user page:
PUT-create `XWiki.XWikiAdminGroup` (idempotent — returns 200/202 when
the Distribution Job won the race, 201 when we beat it) before POSTing
the membership object. The new PUT + the existing POST live inside a
single `block:` gated by `not (XWIKI_SSO_ENABLED | bool)` — the
existing `XWIKI_SSO_ENABLED` SPOT in vars/main.yml subsumes the
duplicated `not LDAP and not OIDC` clause on the POST task.

Distribution-Job-overwrite risk assessed against XWiki v17.10.8
upstream source:

- `AbstractXarEntryType.upgradeType` defaults to
  `UpgradeType.THREEWAYS` (3-way merge, not OVERWRITE/SKIP). Verified
  at `xwiki-platform-xar-model/.../type/AbstractXarEntryType.java:38`.
- `DocumentMergeImporter.importDocument` passes the existing document
  as merge-current; the XAR template ships an empty `<member/>`
  placeholder with a hardcoded GUID
  (`46d387f2-4d8d-446d-a618-8bfcb655ba18`), so our REST-created
  XWikiGroups object (auto-assigned number, fresh GUID) is treated as
  a separate object and survives a later XAR re-install. The empty
  placeholder also means the XAR install has no member value to
  overwrite with.
- Combined risk: ~5% that a future XWiki release changes the upgrade
  type or the XAR-shipped XWikiAdminGroup content; logged for review
  but not blocking.

Confidence: ~92%. Remaining ~8% covers (a) future XWiki XAR re-runs
with non-default conflict actions, (b) custom merge-conflict configs
in the deployed flavor, (c) unbedachte XWiki internal listeners.

Variant scope: no-SSO only (`XWIKI_SSO_ENABLED == false`). The OIDC
and LDAP variants delegate group membership to the SSO mapper and
skip this task entirely, so the fix is a no-op there.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-26 13:25:15 +02:00
kevinveenbirkenbachandClaude Opus 4.7 c52e4269bf chore(tooling): integrate mbake (Makefile linter/formatter) + working-tree drift sync
Makefile lint integration:
* scripts/install/lint.sh: replace the prior checkmake binary install with
  ensure_mbake (mbake is pip-installable, parses our Makefile correctly
  whereas checkmake bailed on .ONESHELL: / .SHELLFLAGS: / ifneq).
* scripts/lint/makefile.sh: new runner — `mbake format --check Makefile`
  reports formatting drift and missing .PHONY declarations.
* scripts/lint/autoformat.sh: add a two-pass `mbake format Makefile`
  (mbake's formatter is not strictly idempotent on the first pass).
* Makefile: split the multi-line `.PHONY:` block into 18 single-line
  `.PHONY:` declarations so mbake's parser can validate it; add the
  previously-missing `install-python-dev` and `build-dependency` PHONY
  targets; add `lint-makefile` aggregate-and-direct target.
* .pre-commit-config.yaml: new make-lint-makefile hook scoped to
  `^Makefile$`.
* .github/workflows/lint-makefile.yml: new CI workflow (pip-install mbake
  + make lint-makefile).
* .github/workflows/ci-orchestrator.yml: wire lint-makefile into
  lint-gate.needs.

Misc:
* .gitignore: add roles/importer_result.json (tooling artefact written by
  galaxy-importer when it runs in roles/).

Plus working-tree drift across roles/, group_vars/, inventories/, and
tasks/ that 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>
2026-05-09 00:32:44 +02:00
kevinveenbirkenbach 63ddd24aaf feat(req-015): self-built Moodle image, OIDC+LDAP hybrid + LDAP-only variants 2026-05-04 18:37:03 +02:00
kevinveenbirkenbachandClaude Opus 4.6 b70a783423 refactor(lookups): migrate to runtime applications/users lookups
Replaces inline `applications`/`users` merging with dedicated lookup
plugins and runtime hydration. Introduces `add_csp_hash` filter,
integrates sort into `find_dock_val_by_bkp_entr`, splits the Keycloak
one-shot realm import into `05a_realm_import_run.yml`, and fixes the
Mastodon administrator task YAML. Removes obsolete `csp_hashes` filter,
`sys-token-store` Jinja filter, and empty CLI setup modules.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-15 23:44:19 +02:00
kevinveenbirkenbach c6f5fdea15 refactor plugins layout and migrate uri calls to uri_retry 2026-03-19 01:41:07 +01:00
kevinveenbirkenbach ce56746340 REmoved unnecessary defaults 2026-02-06 02:10:01 +01:00
kevinveenbirkenbach 63c8225173 fix(xwiki): stabilize REST auth and superadmin setup
* Replace heredoc-based Dockerfile logic with printf to avoid silent build failures
* Ensure superadmin credentials are reliably written into xwiki.cfg at build time
* Introduce shared REST session task to fetch JSESSIONID and XWiki-Form-Token
* Use cookie + CSRF token headers consistently for all REST write operations
* Switch uri auth parameters to url_username / url_password for clarity and consistency
* Normalize internal URLs via XWIKI_DOCKER_REACH_URL
* Make extension install, admin setup, and cleanup idempotent and reliable

https://chatgpt.com/share/695c1c63-0218-800f-ba36-f7640b0d1f2f
2026-01-05 21:17:26 +01:00
kevinveenbirkenbach 0566c426c9 Refactored administrator page variables 2025-09-16 19:57:07 +02:00
kevinveenbirkenbach f106d5ec36 web-app-xwiki: admin bootstrap & REST/extension install fixes
• Guard admin tasks via XWIKI_SSO_ENABLED
• Create admin using XWikiUsers object API
• Wait for REST without DW redirect
• Install OIDC/LDAP via /rest/jobs (+verify)
• Mount xwiki.cfg/properties under Tomcat WEB-INF
• Build REST URLs with url_join; enable DW auto bootstrap + repos

https://chatgpt.com/share/68c42502-a5cc-800f-b05a-a1dbe48f014d
2025-09-12 15:50:30 +02:00
kevinveenbirkenbach f576b42579 XWiki: two-phase bootstrap + extension install before enabling auth; add XOR validation
- Add 02_validation.yml to prevent OIDC+LDAP enabled simultaneously
- Introduce _flush_config.yml with switches (OIDC/LDAP/superadmin)
- Bootstrap with native+superadmin → create admin → install extensions (superadmin) → enable final auth
- Refactor REST vars (XWIKI_REST_BASE, XWIKI_REST_XWIKI, XWIKI_REST_EXTENSION_INSTALL)
- Update templates to use switch vars; gate OIDC block in properties
- Idempotent REST readiness waits

Conversation: https://chatgpt.com/share/68c40c1e-2b3c-800f-b59f-8d37baa9ebb2
2025-09-12 14:04:02 +02:00