Planning the route to a supported release
You cannot always go straight there
Each Moodle release states the oldest release it can upgrade from. A site that is far behind has to stop at one or more intermediate releases, and long-term support releases are often the natural stopping points because they stay patched for longer. We read the release requirements, plot the route, and note for each hop what the database upgrade will change. On big sites some hops take hours because large tables are rewritten, and that has to be known before the maintenance window is announced.
PHP and the database move too
Releases support a window of PHP versions, and those windows shift. An old Moodle may not run on a modern PHP, while the target release will not run on the old one. So somewhere along the route the server changes, and the order matters. The same goes for the database: minimum versions rise, and older MySQL and MariaDB installs may need their character set and row format converted along the way. We script these steps and run them in the rehearsal exactly as they will run on the day.
Plugins decide whether the upgrade finishes
Moodle checks plugins before upgrading and will flag any that are missing from disk or declare themselves incompatible. Our audit goes further. For each plugin we find a version for every hop, read its upgrade notes, and test the activities that use it. Abandoned plugins get one of three outcomes: we patch them, we migrate their content to a core activity, or we uninstall them cleanly. Custom plugins written for you are updated to current APIs as part of the work, in the way set out on our Moodle plugin development page.
What we verify after each run
A completed upgrade screen proves little. After the rehearsal we compare user, course, enrolment, grade and completion counts with the source, check that the database schema matches what Moodle expects, run cron and confirm scheduled tasks finish, and walk through a test script: log in, open a course, attempt a quiz, submit an assignment, grade it, download a certificate. Integrations are retested, since single sign-on and web service clients are sensitive to changes.
The day itself
The live upgrade repeats a procedure that has already worked. The site goes into maintenance mode, backups are taken, the scripted steps run from the command line, caches are purged and the checks are repeated. If a check fails and cannot be fixed inside the window, we restore and try again another day. Afterwards we stay close for the first teaching week, when most questions about the new interface arrive, and ongoing Moodle maintenance keeps the site from falling behind again.