Strip state from attributes before inserting them
[mediawiki.git] / DEVELOPERS.md
blobe4942795361b63860029e3bdaa81a62d23615966
1 # MediaWiki Developers
3 Welcome to the MediaWiki community! Please see [How to become a MediaWiki
4 hacker](https://www.mediawiki.org/wiki/How_to_become_a_MediaWiki_hacker) for
5 general information on contributing to MediaWiki.
7 ## Development environment
9 MediaWiki provides an extendable local development environment based on Docker Compose. This environment provides PHP, Apache, Xdebug and a SQLite database.
11 **Do not use the development environment to serve a public website! Bad things would happen!**
13 More documentation, examples, and configuration recipes are available at [mediawiki.org/wiki/MediaWiki-Docker][mw-docker].
15 Support is available on the [Libera IRC network][libera-home] in the [#mediawiki channel][libera-webchat], and on Phabricator by creating tasks with the [MediaWiki-Docker][mw-docker-phab] tag.
17 [mw-docker]: https://www.mediawiki.org/wiki/MediaWiki-Docker
18 [mw-docker-phab]: https://phabricator.wikimedia.org/tag/mediawiki-docker/
19 [libera-home]: https://libera.chat/
20 [libera-webchat]: https://web.libera.chat/#mediawiki
22 ## Quickstart
24 ### 1. Requirements
26 You'll need to have Docker installed:
28 * [Docker Desktop][docker-install] for macOS or Windows.
29 * [Docker engine][docker-linux] for Linux.
31 [docker-install]: https://docs.docker.com/get-docker/
32 [docker-linux]: https://docs.docker.com/engine/install/
34 **Linux users**:
36 * We recommend installing `docker-ce`, `docker-ce-cli`, `containerd.io`, and `docker-compose-plugin` by [downloading the server
37   releases][dc-release] for your distribution rather than Docker Desktop. You can also install the [binaries][dc-binaries].
38 * Follow the instructions to ["Manage Docker as a non-root user"][dc-non-root]
40 [dc-release]: https://docs.docker.com/engine/install/
41 [dc-binaries]: https://docs.docker.com/engine/install/binaries/
42 [dc-non-root]: https://docs.docker.com/install/linux/linux-postinstall/#manage-docker-as-a-non-root-user
44 **Windows users**:
46 We recommend [configuring Docker to use the Windows Subsystem for Linux (WSL)](https://docs.docker.com/desktop/wsl/#best-practices). This will result in performance improvements.
48 ### 2. Download MediaWiki files
50 Download the latest MediaWiki files to your computer. One way to download the latest alpha version of MediaWiki is to [install git](https://git-scm.com/), open a shell, navigate to the directory where you want to save the files, then type `git clone https://gerrit.wikimedia.org/r/mediawiki/core.git mediawiki`.
52 Optional: If you plan to submit patches to this repository, you will probably want to [create a Gerrit account](https://wikitech.wikimedia.org/wiki/Help:Create_a_Wikimedia_developer_account), then type `git remote set-url origin ssh://YOUR-GERRIT-USERNAME-HERE@gerrit.wikimedia.org:29418/mediawiki/core`, replacing YOUR-GERRIT-USERNAME-HERE with your Gerrit username. Please see the official [MediaWiki Gerrit tutorial](https://www.mediawiki.org/wiki/Gerrit/Tutorial) for more information.
54 ### 3. Prepare `.env` file
56 Using a text editor, create a `.env` file in the root of the MediaWiki core
57 repository, and copy these contents into that file:
59 ```sh
60 MW_SCRIPT_PATH=/w
61 MW_SERVER=http://localhost:8080
62 MW_DOCKER_PORT=8080
63 MEDIAWIKI_USER=Admin
64 MEDIAWIKI_PASSWORD=dockerpass
65 XDEBUG_CONFIG=
66 XDEBUG_ENABLE=true
67 XHPROF_ENABLE=true
68 ```
70 Windows users: Run the following command to add a blank user ID and group ID to your `.env` file:
72 ```sh
73 echo "
74 MW_DOCKER_UID=
75 MW_DOCKER_GID=" >> .env
76 ```
78 Non-Windows users: Run the following command to add your user ID and group ID to your `.env` file:
80 ```sh
81 echo "MW_DOCKER_UID=$(id -u)
82 MW_DOCKER_GID=$(id -g)" >> .env
83 ```
85 Linux users: If you'd like to use Xdebug features inside your IDE, then create a `docker-compose.override.yml` file as well:
87 ```yaml
88 version: '3.7'
89 services:
90   mediawiki:
91     # For Linux: This extra_hosts section enables Xdebug-IDE communication:
92     extra_hosts:
93       - "host.docker.internal:host-gateway"
94 ```
96 ### 4. Create the environment
98 * Start the containers:
99   ```sh
100   docker compose up -d
101   ```
102   The "up" command makes sure that the PHP and webserver containers are running (and any others in the `docker-compose.yml` file). It is safe to run at any time, and will do nothing if the containers are already running.
104   The first time, it may take a few minutes to download new Docker images.
106   The `-d` argument stands for "detached" mode, which run the services in the background. If you suspect a problem with one of the services, you can run it without `-d` to follow the server logs directly from your termimnal. You don't have to stop the services first, if you ran it with `-d` and then without, you'll get connected to the already running containers including a decent backscroll of server logs.
108   Note that MediaWiki debug logs go to `/cache/*.log` files (not sent to docker).
110 * Install PHP dependencies from Composer:
111   ```sh
112   docker compose exec mediawiki composer update
113   ```
115 * Install MediaWiki:
116   ```sh
117   docker compose exec mediawiki /bin/bash /docker/install.sh
118   ```
119   Windows users: make sure you run the above command in PowerShell as it does not work in Bash.
121 * Windows users: Make sure to set the SQLite directory to be writable.
122   ```sh
123   docker compose exec mediawiki chmod -R o+rwx cache/sqlite
124   ```
126 Done! The wiki should now be available for you at <http://localhost:8080>.
128 ## Usage
130 ### Running commands
132 You can use `docker compose exec mediawiki bash` to open a bash shell in the
133 MediaWiki container. You can then run one or more commands as needed and stay
134 within the container shell.
136 You can also run a single command in the container directly from your host
137 shell, for example: `docker compose exec mediawiki php maintenance/run.php update`.
139 ### PHPUnit
141 Run a single PHPUnit file or directory:
143 ```sh
144 docker compose exec mediawiki bash
145 instance:/w$ cd tests/phpunit
146 instance:/w/tests/phpunit$ composer phpunit -- path/to/my/test/
149 See [PHPUnit on mediawiki.org][phpunit-testing] for more examples.
151 [phpunit-testing]: https://www.mediawiki.org/wiki/Manual:PHP_unit_testing/Running_the_tests
153 ### Selenium
155 You can use [Fresh][fresh] to run [Selenium in a dedicated
156 container][selenium-dedicated]. Example usage:
158 ```sh
159 fresh-node -env -net
160 npm ci
161 npm run selenium-test
164 [selenium-dedicated]: https://www.mediawiki.org/wiki/Selenium/Getting_Started/Run_tests_using_Fresh
166 ### API Testing
168 You can use [Fresh][fresh] to run [API tests in a dedicated
169 container][api-dedicated]. Example usage:
171 ```sh
172 export MW_SERVER=http://localhost:8080/
173 export MW_SCRIPT_PATH=/w
174 export MEDIAWIKI_USER=Admin
175 export MEDIAWIKI_PASSWORD=dockerpass
176 fresh-node -env -net
177 # Create .api-testing.config.json as documented on
178 # https://www.mediawiki.org/wiki/MediaWiki_API_integration_tests
179 npm ci
180 npm run api-testing
183 [fresh]: https://github.com/wikimedia/fresh
184 [api-dedicated]: https://www.mediawiki.org/wiki/MediaWiki_API_integration_tests
186 ## Modify the development environment
188 You can override the default services from a `docker-compose.override.yml`
189 file, and make use of those overrides by changing `LocalSettings.php`.
191 Example overrides and configurations can be found under
192 [MediaWiki-Docker on mediawiki.org][mw-docker].
194 After updating `docker-compose.override.yml`, run `docker compose down`
195 followed by `docker compose up -d` for changes to take effect.
197 ### Install extra packages
199 If you need root on the container to install system packages with `apt-get` for
200 troubleshooting, you can open a shell as root with
201 `docker compose exec --user root mediawiki bash`.
203 ### Install extensions and skins
205 To install an extension or skin, follow the intructions of the mediawiki.org
206 page for the extension or skin in question, and look for any dependencies
207 or additional steps that may be needed.
209 For most extensions, only two steps are needed: download the code to the
210 right directory, and then enable the component from `LocalSettings.php`.
212 To install the Vector skin:
214 1. Clone the skin:
215     ```sh
216     cd skins/
217     git clone https://gerrit.wikimedia.org/r/mediawiki/skins/Vector
218     ```
220 2. Enable the skin, by adding the following to `LocalSettings.php`:
221     ```php
222     wfLoadSkin( 'Vector' );
223     ```
225 To install the EventLogging extension:
227 1. Clone the extension repository:
229     ```sh
230     cd extensions/
231     git clone https://gerrit.wikimedia.org/r/mediawiki/extensions/EventLogging
232     ```
234     Alternatively, if you have extension repositories elsewhere on disk, mount each one as an overlapping volume in `docker-compose.override.yml`. This is comparable to a symlink, but those are not well-supported in Docker.
236     ```yaml
237    version: '3.7'
238    services:
239      mediawiki:
240        volumes:
241          - ~/Code/EventLogging:/var/www/html/w/extensions/EventLogging:cached
242     ```
244 2. Enable the extension, by adding the following to `LocalSettings.php`:
245     ```php
246     wfLoadExtension( 'EventLogging' );
247     ```
249 ### Xdebug
251 By default, you will need to set `XDEBUG_TRIGGER=1` in the GET/POST, or as an
252 environment variable, to turn on Xdebug for a request.
254 You can also install a browser extension for controlling whether Xdebug is
255 active.  See the [official Xdebug Step Debugging][step-debug], particularly the
256 "Activating Step Debugging" section, for more details.
258 [step-debug]: https://xdebug.org/docs/step_debug
260 If you wish to run Xdebug on every request, you can set
261 `start_with_request=yes` in `XDEBUG_CONFIG` in your .env file:
264 XDEBUG_CONFIG=start_with_request=yes
267 You can pass any of Xdebug's configuration values in this variable.  For example:
270 XDEBUG_CONFIG=client_host=192.168.42.34 client_port=9000 log=/tmp/xdebug.log
273 This shouldn't be necessary for basic use cases, but see [the Xdebug settings
274 documentation](https://xdebug.org/docs/all_settings) for available settings.
276 ### Stop or recreate environment
278 Stop the environment, perhaps to reduce load when working on something
279 else. This preserves the containers, to be restarted later quickly with
280 the `docker compose up -d` command.
282 ```sh
283 docker compose stop
286 Destroy and re-create the environment. This will delete the containers,
287 including any logs, caches, and other modifications you may have made
288 via the shell.
290 ```sh
291 docker compose down
292 docker compose up -d
295 ### Re-install the database
297 To empty the wiki database and re-install it:
299 * Remove or rename the `LocalSettings.php` file.
300 * Delete the `cache/sqlite` directory.
301 * Re-run the "Install MediaWiki database" command.
303 You can now restore or copy over any modifications you had in your previous `LocalSettings.php` file. And if you have additonal extensions installed that required a database table, then also run: `docker compose exec mediawiki php maintenance/run.php update`.
305 ## Troubleshooting
307 ### Caching
309 If you suspect a change is not applying due to caching, start by [hard
310 refreshing](https://en.wikipedia.org/wiki/Wikipedia:Bypass_your_cache) the browser.
312 If that doesn't work, you can narrow it down by disabling various server-side
313 caching layers in `LocalSettings.php`, as follows:
315 ```php
316 $wgMainCacheType = CACHE_NONE;
317 $wgMessageCacheType = CACHE_NONE;
318 $wgParserCacheType = CACHE_NONE;
319 $wgResourceLoaderMaxage = [
320   'versioned' => 0,
321   'unversioned' => 0
325 The default settings of MediaWiki are such that caching is smart and changes
326 propagate immediately. Using the above settings may slow down your wiki
327 significantly. Especially on macOS and Windows, where Docker Desktop uses
328 a VM internally and thus has longer file access times.
330 See [Manual:Caching][manual-caching] on mediawiki.org for more information.
332 [manual-caching]: https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Caching
334 ### Xdebug ports
336 Older versions of Xdebug used port 9000, which could conflict with php-fpm
337 running on the host.  This document used to recommend a workaround of telling
338 your IDE to listen on a different port (e.g. 9009) and setting
339 `XDEBUG_CONFIG=remote_port=9009` in your `.env`.
341 Xdebug 3.x now uses the `client_port` value, which defaults to 9003.  This
342 should no longer conflict with local php-fpm installations, but you may need
343 to change the settings in your IDE or debugger.
345 ### Linux desktop, host not found
347 The image uses `host.docker.internal` as the `client_host` value which
348 should allow Xdebug work for Docker for Mac/Windows.
350 On Linux, you need to create a `docker-compose.override.yml` file with the following
351 contents:
353 ```yaml
354 version: '3.7'
355 services:
356   mediawiki:
357     extra_hosts:
358       - "host.docker.internal:host-gateway"
361 With the latest version of Docker on Linux hosts, this _should_ work
362 transparently as long as you're using the recommended
363 `docker-compose.override.yml`.  If it doesn't, first check `docker version` to
364 make sure you're running Docker 20.10.2 or above, and `docker compose version`
365 to make sure it's 1.27.4 or above.
367 If Xdebug still doesn't work, try specifying the hostname or IP address of your
368 host. The IP address works more reliably.  You can obtain it by running e.g.
369 `ip -4 addr show docker0` and copying the IP address into the config in `.env`,
370 like `XDEBUG_CONFIG=remote_host=172.17.0.1`
372 ### Generating logs
374 Switching on the remote log for Xdebug comes at a performance cost so only
375 use it while troubleshooting. You can enable it like so: `XDEBUG_CONFIG=remote_log=/tmp/xdebug.log`
377 ### "(Permission Denied)" errors on running docker compose
379 See if you're able to run any docker commands to start with. Try running
380 `docker container ls`, which should also throw a permission error. If not,
381 go through the following steps to get access to the socket that the docker
382 client uses to talk to the daemon.
384 `sudo usermod -aG docker $USER`
386 And then relogin (or `newgrp docker`) to re-login with the new group membership.
388 ### "(Cannot access the database: Unknown error (localhost))"
390 The environment's working directory has recently changed to `/var/www/html/w`.
391 Reconfigure this in your `LocalSettings.php` by ensuring that the following
392 values are set correctly:
394 ```php
395 $wgScriptPath = '/w';
396 $wgSQLiteDataDir = "/var/www/html/w/cache/sqlite";
399 ### Windows users, "(Cannot access the database: No database connection (unknown))"
401 The permissions with the `cache/sqlite` directory have to be set manually on Windows:
402 ```sh
403 docker compose exec mediawiki chmod -R o+rwx cache/sqlite