You'll need to use a command-line to do this part. Since extensions aren't
compatible between major versions of Bolt we'll need to disable all the current
ones and then later in the process we can install ones that have a version
compatible with version 3.1. If you haven't done already it may be a
good idea to keep a note of which extensions you had installed, an easy way to
see this is by looking in the require section of extensions/composer.json.

From within your extensions directory run the following two commands.

rm -Rf ./vendor/

composer dump-autoload

This will disable any extensions from loading into Bolt and prevent any fatal
errors from incompatible extensions.

When you get to the frontend you may still have issues where you are calling
extension functions from within your theme twig templates. If this is the case
you may also have to temporarily comment these out until you have the relevant
extension installed and working.

Bolt 3.1 has seen a major refactor and simplification of the Request ->
Dispatch -> Controller code so if your site uses a custom controller this is
likely to be the first set of errors you will run into.

Firstly controllers have moved to a new namespace, it's likely that if you have
a custom controller you will have extended the default Bolt frontend controller
which previously was at Bolt\Controllers\Frontend, this is a simple change,
you will need to change this to Bolt\Controller\Frontend.

In many cases this may be enough to get your app running, however if you are
calling any of the main Bolt frontend methods then the method signature has
changed and you will need to adjust the calls.

For instance you may see this error:

Catchable fatal error: Argument 1 passed to Bolt\Controller\Frontend::record() must be an instance of Symfony\Component\HttpFoundation\Request

This is because the methods now only receive a Request object rather than
passing in the entire Application object.

The signature of the Bolt routing class has changed so if you see the below:

Catchable fatal error: Argument 1 passed to Bolt\Controller\Requirement::__construct() must be an instance of Bolt\Config, none given

You need to alter the construction to pass in the Bolt config object so this:
$this->mount('', new Routing()); or $app->mount('', new Routing());
becomes
$this->mount('', new Routing($this['config'])); or $app->mount('', new Routing($app['config']));

If all you need to do is provide additional requirements (or override the
existing ones) then you are best served by extending or replacing the new
$app['controller.requirement'] rather than calling $app->mount() method.
Here's an example:

The routing file will then look for a controller mounted to
$app['controller.mycustomcontroller'] and then look for the doCustomStuff()
method. You will need to make sure that this mounted service implements
ControllerProviderInterface and then you can safely remove any manual calls to
$app->mount().

If your app uses local extensions or independently mounts them using
$app['extensions']->register(new Extension()) or similar, then you will need
to make sure they conform to the new extensions structure for Bolt 3.0.