From aaedaab3dac961a1e70178448540debe97df8bed Mon Sep 17 00:00:00 2001 From: Kevin Veen-Birkenbach Date: Mon, 1 Sep 2025 13:04:57 +0200 Subject: [PATCH] refactor(web-app-mediawiki): unify debug & oidc handling via _ensure_require, introduce host-side prep, switch to bind mounts - Removed obsolete Installation.md, TODO.md, 02_debug.yml, 05_oidc.yml and legacy debug enable/disable tasks - Added 01_prep.yml to render debug.php/oidc.php on host side before container start - Introduced _ensure_require.yml for generic require_once management in LocalSettings.php - Renamed 01_install.yml -> 02_install.yml to align with new numbering - Updated docker-compose.yml.j2 to bind-mount mw-local into /opt/mw-local - Adjusted vars/main.yml to define MEDIAWIKI_LOCAL_MOUNT_DIR and MEDIAWIKI_LOCAL_PATH - Templates debug.php.j2 and oidc.php.j2 now gated by MODE_DEBUG and MEDIAWIKI_OIDC_ENABLED - main.yml now orchestrates prep, install, debug, extensions, oidc require, admin consistently Ref: https://chatgpt.com/share/68b57db2-efcc-800f-a733-aca952298437 --- roles/web-app-mediawiki/Installation.md | 145 ------------------ roles/web-app-mediawiki/TODO.md | 3 - roles/web-app-mediawiki/tasks/01_prep.yml | 20 +++ roles/web-app-mediawiki/tasks/02_debug.yml | 11 -- .../tasks/{01_install.yml => 02_install.yml} | 0 roles/web-app-mediawiki/tasks/05_oidc.yml | 61 -------- .../tasks/_debug_disable.yml | 27 ---- .../web-app-mediawiki/tasks/_debug_enable.yml | 45 ------ .../tasks/_ensure_require.yml | 29 ++++ roles/web-app-mediawiki/tasks/main.yml | 35 +++-- .../web-app-mediawiki/templates/debug.php.j2 | 27 +++- .../templates/docker-compose.yml.j2 | 1 + roles/web-app-mediawiki/templates/oidc.php.j2 | 12 +- roles/web-app-mediawiki/vars/main.yml | 8 +- 14 files changed, 110 insertions(+), 314 deletions(-) delete mode 100644 roles/web-app-mediawiki/Installation.md delete mode 100644 roles/web-app-mediawiki/TODO.md create mode 100644 roles/web-app-mediawiki/tasks/01_prep.yml delete mode 100644 roles/web-app-mediawiki/tasks/02_debug.yml rename roles/web-app-mediawiki/tasks/{01_install.yml => 02_install.yml} (100%) delete mode 100644 roles/web-app-mediawiki/tasks/05_oidc.yml delete mode 100644 roles/web-app-mediawiki/tasks/_debug_disable.yml delete mode 100644 roles/web-app-mediawiki/tasks/_debug_enable.yml create mode 100644 roles/web-app-mediawiki/tasks/_ensure_require.yml diff --git a/roles/web-app-mediawiki/Installation.md b/roles/web-app-mediawiki/Installation.md deleted file mode 100644 index 208d7313..00000000 --- a/roles/web-app-mediawiki/Installation.md +++ /dev/null @@ -1,145 +0,0 @@ -# Installation - -## Generate LocalSettings.php -Login to the container: - -```bash -docker-compose exec -it application /bin/sh -``` - -Seed the LocalSettings.php: - -```bash -cat > LocalSettings.php << EOF - "\$wgResourceBasePath/resources/assets/wiki.png" ]; - -## UPO means: this is also a user preference option - -\$wgEnableEmail = true; -\$wgEnableUserEmail = true; # UPO - -\$wgEmergencyContact = "apache@🌻.invalid"; -\$wgPasswordSender = "apache@🌻.invalid"; - -\$wgEnotifUserTalk = false; # UPO -\$wgEnotifWatchlist = false; # UPO -\$wgEmailAuthentication = true; - -## Database settings -\$wgDBtype = "mysql"; -\$wgDBserver = "database:3306"; -\$wgDBname = "mediawiki"; -\$wgDBuser = "mediawiki"; -\$wgDBpassword = "test"; - -# MySQL specific settings -\$wgDBprefix = ""; - -# MySQL table options to use during installation or update -\$wgDBTableOptions = "ENGINE=InnoDB, DEFAULT CHARSET=binary"; - -## Shared memory settings -\$wgMainCacheType = CACHE_NONE; -\$wgMemCachedServers = []; - -## To enable image uploads, make sure the 'images' directory -## is writable, then set this to true: -\$wgEnableUploads = false; -\$wgUseImageMagick = true; -\$wgImageMagickConvertCommand = "/usr/bin/convert"; - -# InstantCommons allows wiki to use images from https://commons.wikimedia.org -\$wgUseInstantCommons = false; - -# Periodically send a pingback to https://www.mediawiki.org/ with basic data -# about this MediaWiki instance. The Wikimedia Foundation shares this data -# with MediaWiki developers to help guide future development efforts. -\$wgPingback = true; - -## If you use ImageMagick (or any other shell command) on a -## Linux server, this will need to be set to the name of an -## available UTF-8 locale -\$wgShellLocale = "C.UTF-8"; - -## Set \$wgCacheDirectory to a writable directory on the web server -## to make your wiki go slightly faster. The directory should not -## be publicly accessible from the web. -#\$wgCacheDirectory = "\$IP/cache"; - -# Site language code, should be one of the list in ./languages/data/Names.php -\$wgLanguageCode = "en"; - -\$wgSecretKey = "603fe88c985b05706f19aaf77d2a61459555ff21a4a4d4ef0aa15c8f8ec50f00"; - -# Changing this will log out all existing sessions. -\$wgAuthenticationTokenVersion = "1"; - -# Site upgrade key. Must be set to a string (default provided) to turn on the -# web installer while LocalSettings.php is in place -\$wgUpgradeKey = "f99263b0f3a7c59a"; - -## For attaching licensing metadata to pages, and displaying an -## appropriate copyright notice / icon. GNU Free Documentation -## License and Creative Commons licenses are supported so far. -\$wgRightsPage = ""; # Set to the title of a wiki page that describes your license/copyright -\$wgRightsUrl = ""; -\$wgRightsText = ""; -\$wgRightsIcon = ""; - -# Path to the GNU diff3 utility. Used for conflict resolution. -\$wgDiff3 = "/usr/bin/diff3"; - -## Default skin: you can change the default skin. Use the internal symbolic -## names, ie 'vector', 'monobook': -\$wgDefaultSkin = "vector"; - -# Enabled skins. -# The following skins were automatically enabled: -wfLoadSkin( 'MonoBook' ); -wfLoadSkin( 'Timeless' ); -wfLoadSkin( 'Vector' ); - - -# End of automatically generated settings. -# Add more configuration options below. -EOF -``` \ No newline at end of file diff --git a/roles/web-app-mediawiki/TODO.md b/roles/web-app-mediawiki/TODO.md deleted file mode 100644 index bc5996cc..00000000 --- a/roles/web-app-mediawiki/TODO.md +++ /dev/null @@ -1,3 +0,0 @@ -# Todo -- This role needs to be updated to the new role structure -- It needs to be tested - Really antique role which wasn't used since ages, because I used discourse in production instead and just updated the refactored and restructure stuff here. \ No newline at end of file diff --git a/roles/web-app-mediawiki/tasks/01_prep.yml b/roles/web-app-mediawiki/tasks/01_prep.yml new file mode 100644 index 00000000..2467fa77 --- /dev/null +++ b/roles/web-app-mediawiki/tasks/01_prep.yml @@ -0,0 +1,20 @@ +--- +- name: "PREP | Ensure mw-local mount directory exists on host" + file: + path: "{{ MEDIAWIKI_LOCAL_MOUNT_DIR }}" + state: directory + mode: "0755" + +- name: "PREP | Render oidc.php (host side)" + when: MEDIAWIKI_OIDC_ENABLED | bool + template: + src: "oidc.php.j2" + dest: "{{ MEDIAWIKI_LOCAL_MOUNT_DIR }}/oidc.php" + mode: "0644" + no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" + +- name: "PREP | Render debug.php (host side, always; content gated by MODE_DEBUG)" + template: + src: "debug.php.j2" + dest: "{{ MEDIAWIKI_LOCAL_MOUNT_DIR }}/debug.php" + mode: "0644" diff --git a/roles/web-app-mediawiki/tasks/02_debug.yml b/roles/web-app-mediawiki/tasks/02_debug.yml deleted file mode 100644 index 3e172721..00000000 --- a/roles/web-app-mediawiki/tasks/02_debug.yml +++ /dev/null @@ -1,11 +0,0 @@ ---- -# Aktiviert Debug, wenn MODE_DEBUG=true; entfernt es sauber, wenn false. - -- name: "DEBUG | Enable block when MODE_DEBUG=true" - when: MODE_DEBUG | bool - include_tasks: _debug_enable.yml - -- name: "DEBUG | Disable block when MODE_DEBUG=false" - when: not (MODE_DEBUG | bool) - include_tasks: _debug_disable.yml - diff --git a/roles/web-app-mediawiki/tasks/01_install.yml b/roles/web-app-mediawiki/tasks/02_install.yml similarity index 100% rename from roles/web-app-mediawiki/tasks/01_install.yml rename to roles/web-app-mediawiki/tasks/02_install.yml diff --git a/roles/web-app-mediawiki/tasks/05_oidc.yml b/roles/web-app-mediawiki/tasks/05_oidc.yml deleted file mode 100644 index 78098765..00000000 --- a/roles/web-app-mediawiki/tasks/05_oidc.yml +++ /dev/null @@ -1,61 +0,0 @@ ---- -# All operations remain INSIDE the running container. -# Template is rendered into docker_compose.directories.config on the host. -# Change detection is based on checksum comparison vs. container file. - -- name: "OIDC | Ensure local config directory exists" - file: - path: "{{ MEDIAWIKI_CONFIG_DIR }}" - state: directory - mode: "0755" - -- name: "OIDC | Render oidc.php locally (template into config dir)" - template: - src: "oidc.php.j2" - dest: "{{ MEDIAWIKI_OIDC_FILE }}" - mode: "0644" - no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" - -- name: "OIDC | Compute local checksum" - stat: - path: "{{ MEDIAWIKI_OIDC_FILE }}" - checksum_algorithm: sha256 - register: _local_oidc - -- name: "OIDC | Compute container checksum (if exists)" - shell: > - docker exec {{ MEDIAWIKI_CONTAINER }} bash -lc - "test -f {{ MEDIAWIKI_HTML_DIR }}/oidc.php && - sha256sum {{ MEDIAWIKI_HTML_DIR }}/oidc.php | awk '{print $1}' || echo MISSING" - args: - executable: /bin/bash - register: _remote_oidc - changed_when: false - -- name: "OIDC | Copy oidc.php into container docroot only if different" - shell: > - if [ "{{ (_remote_oidc.stdout | default('') | trim) }}" != "{{ _local_oidc.stat.checksum }}" ]; then - docker cp "{{ MEDIAWIKI_OIDC_FILE }}" "{{ MEDIAWIKI_CONTAINER }}:{{ MEDIAWIKI_HTML_DIR }}/oidc.php" && - docker exec {{ MEDIAWIKI_CONTAINER }} bash -lc "chown {{ MEDIAWIKI_USER }}:{{ MEDIAWIKI_USER }} {{ MEDIAWIKI_HTML_DIR }}/oidc.php && chmod 0644 {{ MEDIAWIKI_HTML_DIR }}/oidc.php" && - echo COPIED; - fi - args: - executable: /bin/bash - register: _cp_oidc - changed_when: "'COPIED' in (_cp_oidc.stdout | default(''))" - -- name: "OIDC | Require oidc.php once inside LocalSettings.php" - shell: | - docker exec -u {{ MEDIAWIKI_USER }} {{ MEDIAWIKI_CONTAINER }} bash -lc ' - LSP={{ MEDIAWIKI_HTML_DIR }}/LocalSettings.php - LINE="require_once __DIR__ . '\''/oidc.php'\'';" - if ! grep -Fqx -- "$LINE" "$LSP"; then - printf "%s\n" "$LINE" >> "$LSP" - echo ADDED_REQUIRE - fi - ' - args: - executable: /bin/bash - register: _mw_oidc_req - changed_when: "'ADDED_REQUIRE' in (_mw_oidc_req.stdout | default(''))" - diff --git a/roles/web-app-mediawiki/tasks/_debug_disable.yml b/roles/web-app-mediawiki/tasks/_debug_disable.yml deleted file mode 100644 index bc1318c2..00000000 --- a/roles/web-app-mediawiki/tasks/_debug_disable.yml +++ /dev/null @@ -1,27 +0,0 @@ -- name: "Remove require_once line from LocalSettings.php (if present)" - shell: | - docker exec -u {{ MEDIAWIKI_USER }} {{ MEDIAWIKI_CONTAINER }} bash -lc ' - LSP={{ MEDIAWIKI_HTML_DIR }}/LocalSettings.php - if [ -f "$LSP" ]; then - if grep -Fqx -- "require_once __DIR__ . '\''/debug.php'\'';" "$LSP"; then - sed -i "\#require_once __DIR__ . '/debug.php';#d" "$LSP" - echo REMOVED_REQUIRE - fi - fi - ' - args: { executable: /bin/bash } - register: _dbg_rm_req - changed_when: "'REMOVED_REQUIRE' in (_dbg_rm_req.stdout | default(''))" - -- name: "Remove debug.php from container (if present)" - shell: > - docker exec {{ MEDIAWIKI_CONTAINER }} bash -lc - "if [ -f {{ MEDIAWIKI_HTML_DIR }}/debug.php ]; then rm -f {{ MEDIAWIKI_HTML_DIR }}/debug.php; echo REMOVED_FILE; fi" - args: { executable: /bin/bash } - register: _dbg_rm_file - changed_when: "'REMOVED_FILE' in (_dbg_rm_file.stdout | default(''))" - -- name: "Remove local debug.php (if present)" - file: - path: "{{ MEDIAWIKI_CONFIG_DIR }}/debug.php" - state: absent \ No newline at end of file diff --git a/roles/web-app-mediawiki/tasks/_debug_enable.yml b/roles/web-app-mediawiki/tasks/_debug_enable.yml deleted file mode 100644 index 86f8e2b5..00000000 --- a/roles/web-app-mediawiki/tasks/_debug_enable.yml +++ /dev/null @@ -1,45 +0,0 @@ -- name: "Render debug.php locally" - template: - src: "debug.php.j2" - dest: "{{ MEDIAWIKI_CONFIG_DIR }}/debug.php" - mode: "0644" - -- name: "Compute local checksum" - stat: - path: "{{ MEDIAWIKI_CONFIG_DIR }}/debug.php" - checksum_algorithm: sha256 - register: _dbg_local - -- name: "Compute container checksum (if exists)" - shell: > - docker exec {{ MEDIAWIKI_CONTAINER }} bash -lc - "test -f {{ MEDIAWIKI_HTML_DIR }}/debug.php && - sha256sum {{ MEDIAWIKI_HTML_DIR }}/debug.php | awk '{print $1}' || echo MISSING" - args: { executable: /bin/bash } - register: _dbg_remote - changed_when: false - -- name: "Copy debug.php into container only if different" - shell: > - if [ "{{ (_dbg_remote.stdout | default('') | trim) }}" != "{{ _dbg_local.stat.checksum }}" ]; then - docker cp "{{ MEDIAWIKI_CONFIG_DIR }}/debug.php" "{{ MEDIAWIKI_CONTAINER }}:{{ MEDIAWIKI_HTML_DIR }}/debug.php" && - docker exec {{ MEDIAWIKI_CONTAINER }} bash -lc "chown {{ MEDIAWIKI_USER }}:{{ MEDIAWIKI_USER }} {{ MEDIAWIKI_HTML_DIR }}/debug.php && chmod 0644 {{ MEDIAWIKI_HTML_DIR }}/debug.php" && - echo COPIED; - fi - args: { executable: /bin/bash } - register: _dbg_cp - changed_when: "'COPIED' in (_dbg_cp.stdout | default(''))" - -- name: "require_once debug.php in LocalSettings.php" - shell: | - docker exec -u {{ MEDIAWIKI_USER }} {{ MEDIAWIKI_CONTAINER }} bash -lc ' - LSP={{ MEDIAWIKI_HTML_DIR }}/LocalSettings.php - LINE="require_once __DIR__ . '\''/debug.php'\'';" - if ! grep -Fqx -- "$LINE" "$LSP"; then - printf "%s\n" "$LINE" >> "$LSP" - echo ADDED_DEBUG_REQUIRE - fi - ' - args: { executable: /bin/bash } - register: _dbg_req - changed_when: "'ADDED_DEBUG_REQUIRE' in (_dbg_req.stdout | default(''))" \ No newline at end of file diff --git a/roles/web-app-mediawiki/tasks/_ensure_require.yml b/roles/web-app-mediawiki/tasks/_ensure_require.yml new file mode 100644 index 00000000..be606a82 --- /dev/null +++ b/roles/web-app-mediawiki/tasks/_ensure_require.yml @@ -0,0 +1,29 @@ +--- +# Inputs (per include übergeben): +# - ensure_present: bool (true => sicherstellen, dass Zeile existiert; false => entfernen) +# - require_path: string (z. B. "{{ MEDIAWIKI_LOCAL_PATH }}/debug.php") + +- name: "Ensure require_once('{{ require_path }}') present/absent in LocalSettings.php" + shell: | + docker exec -u {{ MEDIAWIKI_USER }} {{ MEDIAWIKI_CONTAINER}} bash -lc ' + set -e + LSP={{ MEDIAWIKI_HTML_DIR }}/LocalSettings.php + LINE="require_once '\''{{ require_path }}'\'';" + test -f "$LSP" || exit 0 + if {{ (ensure_present | bool) | ternary("true","false") }}; then + if ! grep -Fqx -- "$LINE" "$LSP"; then + printf "%s\n" "$LINE" >> "$LSP" + echo ADDED_REQUIRE + fi + else + if grep -Fqx -- "$LINE" "$LSP"; then + sed -i "\#require_once '{{ require_path }}';#d" "$LSP" + echo REMOVED_REQUIRE + fi + fi + ' + args: { executable: /bin/bash } + register: _req_mut + changed_when: > + 'ADDED_REQUIRE' in (_req_mut.stdout | default('')) or + 'REMOVED_REQUIRE' in (_req_mut.stdout | default('')) diff --git a/roles/web-app-mediawiki/tasks/main.yml b/roles/web-app-mediawiki/tasks/main.yml index 500817d6..3e30847d 100644 --- a/roles/web-app-mediawiki/tasks/main.yml +++ b/roles/web-app-mediawiki/tasks/main.yml @@ -3,20 +3,35 @@ include_role: name: sys-stk-full-stateful vars: - docker_compose_flush_handlers: true + docker_compose_flush_handlers: false + +- name: "Prepare host files for '{{ application_id }}'" + include_tasks: 01_prep.yml + +- name: "flush handlers for '{{ application_id }}' after preparation finished" + meta: flush_handlers - name: "Load install procedures for '{{ application_id }}''" - include_tasks: 01_install.yml + include_tasks: 02_install.yml -- name: "Load debug procedures for '{{ application_id }}''" - include_tasks: 02_debug.yml + +- name: "DEBUG | Ensure require_once(debug.php) matches MODE_DEBUG" + include_tasks: _ensure_require.yml + vars: + ensure_present: "{{ MODE_DEBUG | bool }}" + require_path: "{{ MEDIAWIKI_LOCAL_PATH }}/debug.php" + when: MODE_DEBUG | bool - name: "Load admin setup procedures for '{{ application_id }}''" include_tasks: 03_admin.yml -- name: "Load OIDC procedures for '{{ application_id }}''" - include_tasks: "{{ item }}" - loop: - - 04_extensions.yml - - 05_oidc.yml - when: MEDIAWIKI_OIDC_ENABLED | bool \ No newline at end of file +- name: "Load extensions procedures for '{{ application_id }}''" + include_tasks: "04_extensions.yml" + when: MEDIAWIKI_OIDC_ENABLED | bool + +- name: "OIDC | Ensure require_once(oidc.php) present" + include_tasks: _ensure_require.yml + vars: + ensure_present: true + require_path: "{{ MEDIAWIKI_LOCAL_PATH }}/oidc.php" + when: MEDIAWIKI_OIDC_ENABLED | bool diff --git a/roles/web-app-mediawiki/templates/debug.php.j2 b/roles/web-app-mediawiki/templates/debug.php.j2 index 711c7c7d..03a6fc3e 100644 --- a/roles/web-app-mediawiki/templates/debug.php.j2 +++ b/roles/web-app-mediawiki/templates/debug.php.j2 @@ -1,9 +1,22 @@ 'php://stderr', 'OpenIDConnect' => 'php://stderr', ]); +{% else %} +/** + * DEBUG DISABLED (MODE_DEBUG=false) + * Intentionally a no-op. File stays present to keep require_once stable. + */ +{% endif %} diff --git a/roles/web-app-mediawiki/templates/docker-compose.yml.j2 b/roles/web-app-mediawiki/templates/docker-compose.yml.j2 index 9de7aa22..29622374 100644 --- a/roles/web-app-mediawiki/templates/docker-compose.yml.j2 +++ b/roles/web-app-mediawiki/templates/docker-compose.yml.j2 @@ -5,6 +5,7 @@ image: "{{ MEDIAWIKI_IMAGE }}:{{ MEDIAWIKI_VERSION }}" volumes: - "data:/var/www/html/" + - "{{ MEDIAWIKI_LOCAL_MOUNT_DIR }}:{{ MEDIAWIKI_LOCAL_PATH }}:ro" ports: - "127.0.0.1:{{ ports.localhost.http[application_id] }}:{{ container_port }}" {% include 'roles/docker-container/templates/healthcheck/curl.yml.j2' %} diff --git a/roles/web-app-mediawiki/templates/oidc.php.j2 b/roles/web-app-mediawiki/templates/oidc.php.j2 index 2d474918..5f5269db 100644 --- a/roles/web-app-mediawiki/templates/oidc.php.j2 +++ b/roles/web-app-mediawiki/templates/oidc.php.j2 @@ -1,18 +1,19 @@ 'OpenIDConnect', 'data' => [ - // For Keycloak, use the REALM URL, e.g. https://auth.example/realms/ 'providerURL' => '{{ MEDIAWIKI_OIDC_ISSUER }}', 'clientID' => '{{ MEDIAWIKI_OIDC_CLIENT_ID }}', 'clientsecret' => '{{ MEDIAWIKI_OIDC_CLIENT_SECRET }}', @@ -21,7 +22,8 @@ $wgPluggableAuth_Config = [ ], ]; -// Helpful defaults $wgOpenIDConnect_UseEmailNameAsUserName = true; $wgOpenIDConnect_MigrateUsers = true; // ### OIDC (PluggableAuth) – END + +{% endif %} \ No newline at end of file diff --git a/roles/web-app-mediawiki/vars/main.yml b/roles/web-app-mediawiki/vars/main.yml index 60cb52be..ae06b8f1 100644 --- a/roles/web-app-mediawiki/vars/main.yml +++ b/roles/web-app-mediawiki/vars/main.yml @@ -10,7 +10,9 @@ MEDIAWIKI_URL: "{{ domains | get_url(application_id, WEB_PROT ## Folders MEDIAWIKI_HTML_DIR: "/var/www/html" MEDIAWIKI_CONFIG_DIR: "{{ docker_compose.directories.config }}" -MEDIAWIKI_OIDC_FILE: "{{ docker_compose.directories.config }}/oidc.php" +MEDIAWIKI_VOLUMES_DIR: "{{ docker_compose.directories.volumes }}" +MEDIAWIKI_LOCAL_MOUNT_DIR: "{{ MEDIAWIKI_VOLUMES_DIR }}/mw-local" +MEDIAWIKI_LOCAL_PATH: "/opt/mw-local" ## Docker MEDIAWIKI_VERSION: "{{ applications | get_app_conf(application_id, 'docker.services.mediawiki.version') }}" @@ -32,10 +34,10 @@ MEDIAWIKI_OIDC_ISSUER: "{{ OIDC.CLIENT.ISSUER_URL }}" MEDIAWIKI_OIDC_BUTTON_TEXT: "{{ OIDC.BUTTON_TEXT }}" # Extensions -MEDIAWIKI_EXT_BRANCH: "REL1_44" # passend zu MediaWiki 1.44 +MEDIAWIKI_EXT_BRANCH: "REL1_44" MEDIAWIKI_EXT_CFG_BASE: "{{ MEDIAWIKI_CONFIG_DIR }}/mwext/{{ MEDIAWIKI_EXT_BRANCH }}" MEDIAWIKI_EXT_LIST: - name: "PluggableAuth" url: "https://codeload.github.com/wikimedia/mediawiki-extensions-PluggableAuth/tar.gz/refs/heads/{{ MEDIAWIKI_EXT_BRANCH }}" - name: "OpenIDConnect" - url: "https://codeload.github.com/wikimedia/mediawiki-extensions-OpenIDConnect/tar.gz/refs/heads/{{ MEDIAWIKI_EXT_BRANCH }}" \ No newline at end of file + url: "https://codeload.github.com/wikimedia/mediawiki-extensions-OpenIDConnect/tar.gz/refs/heads/{{ MEDIAWIKI_EXT_BRANCH }}"