User:Novem Linguae/Essays/Submitting MediaWiki patches

These are my notes on getting MediaWiki and git-review set up on a Windows machine. The end goal is to be able to submit a pull request to Gerrit, and eventually get your patch merged into the MediaWiki codebase.

Get MediaWiki working on localhost
Important to get a MediaWiki localhost working so I can compile code on the fly, step debug, etc.


 * Install Docker, VS Code, git, Composer, npm
 * On first install...
 * User:Novem Linguae/Essays/Docker tutorial

Getting random PHP errors?
One of your dependencies is probably out of date. To fix:


 * For core, every skin, and every extension you have installed...
 * git checkout master
 * git pull
 * npm ci - this may take a minute or two, and it doesn't show the activity on the screen
 * composer install

Write your patch
Coding knowledge required. Languages useful for working on MediaWiki software include PHP, JavaScript, HTML, CSS, SQL, and RegEx.

Option 1 (quick and easy) - Gerrit Patch Uploader

 * https://gerrit-patch-uploader.toolforge.org/
 * You can use "git diff" and not even make any commits. Just have your changes pending.
 * If you are working on mediawiki core, for project, choose mediawiki/core, not mediawiki.
 * You will not be marked as the owner of the patches, but rather the "author". This is the main drawback.

git

 * - A display name. How you want your name to show up in.
 * - Your Gerrit username.
 * - Your Gerrit username.
 * - Your Gerrit username.

SSH

 * Follow the instructions at mw:Gerrit/Tutorial#Set Up SSH Keys in Gerrit, keeping these things in mind (for Windows users):
 * IMPORTANT: Use git bash for everything in this step and following steps, not PowerShell
 * Run git bash as an administrator. Will solve some bugs related to folder permissions.
 * The paste hotkey in git bash is Shift+Insert
 * The SSH thing in git bash doesn't like keys not in the newest format, ed25519. Keep this in mind if you are trying to reuse an SSH key generated for ToolForge or similar.
 * You can have multiple SSH keys if needed
 * SSH keys are stored in the hidden folder

git-review

 * Follow the instructions at mw:Gerrit/Tutorial#Download code using Git, keeping these things in mind (for Windows users):
 * Don't git clone anything from GitHub. Must be through Gerrit for git-review to work.
 * Use Gerrit -> Browse -> Repos to search for repos. Don't use gitiles. Gerrit -> Browse -> Repos will give you SSH links with your username already in them, for easier copy pasting.
 * Clone from a parent folder. If you're  is , the clone will create   and put the files in there.

How to submit patchset 1

 * Clone -
 * Go to master - Use master branch as your base.
 * Create branch - As normal.
 * Write code - As normal. Don't commit yet.
 * Write commit message - Add a detailed description to your first commit, in the format in the section below.
 * Commit - Don't push in the normal way. See below.
 * Push -

How to submit patchset 2+

 * Get latest code
 * If you don't need to sync - If no rebases, edits by others, edits using Gerrit, etc. you can just pull up your old branch.
 * If you need to sync -  - changeNumber is the 6 digit number in your PR's URL


 * Write code - As normal. Don't commit yet.
 * Stage your changes - Do not commit yet. If you do not stage, you will get a blank diff / null edit / no changes.
 * Amend -
 * Edit commit message - A text editor will pop open with your old commit message. Edit it or leave it alone, up to you. Do not try to write a unique commit message describing the changes between the last commit and this one. And be careful not to type anything below the  line, or it will make a new Gerrit ticket.
 * Push -

Short and sweet

 * To clone a new repo
 * cd to your root directory
 * mkdir mediawiki
 * visit the repositories page on gerrit and find the repo. example: https://gerrit.wikimedia.org/r/admin/repos/integration/config
 * copy paste the second text box into your bash, run it. example:
 * cd to the repo
 * To start a new patch
 * switch branch to master
 * create new branch
 * Patchset 1
 * start a new branch (optional but keeps things tidy)
 * long message
 * commit (don't push)
 * Patchset 2+
 * stage
 * Load a patch (yours or someone else's)
 * switch branch to master
 * Load a patch (yours or someone else's)
 * switch branch to master
 * Load a patch (yours or someone else's)
 * switch branch to master


 * Merge conflicts
 * Technical contributor onboarding/Resolve merge conflict
 * Same repo dependencies / relation chain, method 1
 * checks out the parent patch
 * make your changes
 * long message
 * - don't use --amend, don't push
 * Same repo dependencies / relation chain, method 2
 * checks out the parent patch
 * cherry pick the child patch on top of it
 * resolve merge conflicts
 * Cross repo dependencies
 * Depends-on: 
 * Cross repo dependencies
 * Depends-on: 

Gerrit pros and cons

 * Pros
 * "Your turn" / attention set feature is nice
 * Dashboard is nice
 * Patch chains / stacking patches / dependencies
 * Cons
 * Doesn't integrate with VS Code
 * Prompts for password constantly
 * Slow onboarding. Non-standard tech. Took me a week to get working, and another week to get comfortable.
 * Incredible amount of bot spam emails. Email preference settings are minimal. I turned emails off.

WMF plans to switch to GitLab. It is in progress, but they are behind schedule.

Gerrit notes

 * commit messages should be in this format: Gerrit/Commit message guidelines


 * Adding reviewers
 * Sometimes it will auto add people, which is great.
 * Wait until the Jenkins tests pass, then add 2 reviewers max.
 * Look at who has committed code or +2'd code in the repo recently.

+2 +1 -1 -2

 * Gerrit +2 +1 -1 -2
 * +2 - Someone with +2 is someone who has permission to approve patches and merge them into master. Equivalent to a GitHub collaborator or member.
 * +1 - Anyone can +1 your patch. That's just a vote of support, it doesn't merge your code.
 * -1 - Anyone can -1 your patch. That's just a vote of oppose.
 * -2 - Someone with +2 can -2 your patch. Merging of your patch by anyone with +2 will be blocked until they remove their -2.
 * Who has +2 globally
 * WMF software engineers
 * Some volunteers that were added to the mediawiki permissions group
 * Who has +2 on a specific repository
 * Varies by repository. Usually very few people. Often they are not active.
 * Sometimes leaving a comment and marking it as unresolved is nicer than leaving a -1. An unresolved comment can be good for suggestions and minor things that aren't deal breakers or bugs.

Miscellaneous

 * When modifying an extension's internationalization files (in ), only touch en.json and qqq.json. Changes there will automatically be detected and made to the other files by translatewiki.net folks.
 * There's some bugs that I think being on Windows is the cause of. I may end up running a Linux virtual machine for these subtasks to solve it.
 * Making changes to the operations/mediawiki-config repo. It has some filenames containing colons that Windows does not like.
 * Running mediawiki/core unit tests. Around 10 of them pass on Jenkins but fail locally on Windows.
 * Use  to undo a local commit without losing your changes.
 * When clicking "rebase" in Gerrit, you usually want to pick "Rebase on top of the master branch"
 * When updating packages, use, not  .   will install exactly what is in your package-lock.json (exactly what is in the repo).   changes things around a bit, which can introduce complexity.

Notes from code reviews I've received

 * Linter stuff (the linter bot will -1 your patch)
 * Don't forget spaces inside parentheses, for example
 * If you add a parameter to a function, you must add @param to the docblock
 * Lines should be 80–100 characters long, per mw:Manual:Coding_conventions#Line_width. CI will warn for lines over 120 characters.
 * Patch commit messages should be 70 characters long, to prevent wrapping in gerrit when viewed via the web
 * New MediaWiki code should use the service container pattern. This means when you are working in a class that isn't in the top layer, and you're getting other class instances, don't use . Instead, inject the instances in the class constructor. Example for a MediaWiki extension. Example for a MediaWiki core special page. The benefit of this is that you can see at the top of the class what other classes it depends on, and your class is much more testable since you can substitute all the dependencies.
 * Alphabetizing requires the Collation class, for localization reasons. Example patch.
 * PHP: Access config variables with . Don't use the   keyword.   works because most classes extend.

Ideas for easy patches to submit

 * Go find a relatively inactive repo with lots of bug reports. Bug reports are often easy if there's a steps to reproduce and they can be reproduced in the local dev environment. Step debugging will often reveal the problem.
 * Set up your code editor to underline and cross out deprecations. For PHP files and VS Code, this usually requires getting the PHPCS (PHP Code Sniffer) extension to work, and if you're working on an extension, adding the below to your .vscode/settings.json file so that class definitions from MediaWiki core are loaded. Hover over the deprecations to see what the suggested fix is.
 * Pay attention in code reviews. When experienced devs ask you to correct something, pay attention to and learn the pattern. Practice it by finding that pattern in other spots and in other repos, and submitting patches to fix the code smell.
 * Write some tests. MediaWiki doesn't have a lot of good spots for pure unit tests. Selenium tests are supported but discouraged. The bulk of MediaWiki tests seem to be integration tests of classes and APIs.

Tips for problem solving
Experienced developer time is valuable. You'll have more developer friends if you try to solve some of your own simple problems rather than asking for help all the time. Here's some tips.

Social


 * Don't DM people. Instead, ask in a chat room, to reduce pinging, and so crowdsourcing can kick in.

Technical


 * Google, StackOverflow
 * Find the official documentation spots, such as https://doc.wikimedia.org/, and read and search that.
 * "Does X ever do Y when Z?" type questions: Do a test in a local dev environment or a sandbox
 * "How do I code X?" "What is best practice for Y?" Search the repo or search multiple repos for sample code that does something similar
 * Example: I wanted to know if it was better to do  or , so I searched MediaWiki core. The former is definitely better. Thousands of results compared to almost zero results.
 * "Why doesn't my code work?"
 * Step debug in a localhost environment
 * Google the error message
 * How to figure out what code you need to modify for a small change
 * ?uselang=qqx will show you the Message name
 * then you can search the repo for the Message name

Where to get help

 * WP:DISCORD's #technical channel is one of the best places to get live chat help with any Wikipedia technical issue, including Gerrit issues