The following is OK for patch releases 8.4.x > 8.4.y, but not OK for minor releases 8.4.x > 8.5.x. Jump to UPDATE 3 below for what I believe is "the answer" for minor release updates.
1- Backup any files that come with Drupal which you have modified, such as .htaccess, robots.txt, etc. (those 2 are the most commonly changed).
2- [I am told delete lock file is wrong, see UPDATE below] Delete the composer.lock file (in the top level folder of your site). This gets recreated in step 5.
3- Check your composer.json (in the top level folder of your site) and make sure that the "drupal:core" is in the require section and not in a replace section, for example
"require": {
"drupal/core": "^8.4"
},
not
"replace": {
"drupal/core": "^8.4"
},
If "drupal/core" is in the replace section, move it to the require section and delete the replace section. If there are other entries in the replace section, just remove the "drupal/core" not the entire replace section - but I think "drupal/core" is normally the only thing there.
Put what version you want to update to in "drupal/core", examples:
"drupal/core": "^8.5" - will update to the latest version of 8.5.
"drupal/core": "8.4.6" - will update to version 8.4.6.
5- Run this (in the top level folder of your site):
composer update drupal/core --with-dependencies
6- If no errors, then do the usual, run the updates and clear cache:
drush updatedb
drush cr
Or if not using drush, go to /update.php to run updates, then to admin/config/development/performance and hit the "Clear all caches" button.
7- If you had backed up files in the first step (.htaccess, robots.txt) put them back. But check to see if Drupal made updates to those files and add those changes to yours.
DONE
If there were errors with the composer update in step 5, it is usually due to issues with versions of the stuff in the vendor folder.
This is a great post in dealing with such issues: https://www.jeffgeerling.com/blog/2018/updating-drupalcore-composer-drupal-core-doesnt-update and read Jeff's other 2 posts on Drupal and Composer to get more knowledge about that.
I was told by 2 people on Twitter that composer.lock should not be deleted (Step 2 above). The composer update drupal/core --with-dependencies
command recreates the lock file anyways.
In testing this method I find it works fine for 8.4.3 > 8.4.6 (for example) but I get errors for 8.4.6 > 8.5.x. Will report back when I figure it out.
Example of errors:
Your requirements could not be resolved to an installable set of packages.
Problem 1
- symfony/yaml 3.4.x-dev conflicts with symfony/console[v3.2.8].
- symfony/yaml 3.4.x-dev conflicts with symfony/console[v3.2.8].
- symfony/yaml 3.4.x-dev conflicts with symfony/console[v3.2.8].
- drupal/core 8.5.0 requires symfony/yaml ~3.4.5 -> satisfiable by symfony/yaml[3.4.x-dev].
- Installation request for drupal/core 8.5.0 -> satisfiable by drupal/core[8.5.0].
- Installation request for symfony/console (locked at v3.2.8, required as ~3.2.8) -> satisfiable by symfony/console[v3.2.8].
This post by Jeff Geerling addresses similar issues, but so far no luck for me: https://www.jeffgeerling.com/blog/2018/updating-drupalcore-composer-drupal-core-doesnt-update
So... the only thing that seems to work for me for 8.4.x > 8.5.x is the "nuclear option" that so many others seem to use, which is run composer update
.
I guess that is OK so long as you are sure about the module versions in composer.json. Maybe one should lock them down to the current version. For example:
"drupal/address": "1.3"
rather than:
"drupal/address": "^1.3"
But is the the right answer?
OK the answer that seems to be everywhere is to do the "nuclear option":
A. Delete the /vendor
folder.
B. Run composer update
and simply update your modules along with core. Or, lock down the module versions in composer.json
if you don't want to update them.
One person on Drupal Slack said "the whole philosophy of Composer is that you should always be updating packages, as frequently as possible". Packaged includes modules I think. So it makes some sense I guess.
Once I got from 8.4.6 to 8.5.0, this worked fine to get from 8.5.0 to 8.5.1 composer update drupal/core --with-dependencies
just as it did for 8.4.3 to 8.4.6.
I am starting to conclude that "the answer" is that deleting the vendor folder and the composer.lock file, then using composer update
is fine, and that one should simply make sure the version numbers for dependencies in the composer.json file are what you want. It's not that big a deal to manage what module versions you want to keep or allow to update in composer.json
.
For example:
"drupal/admin_toolbar": "1.18",
means stick with 1.18
"drupal/admin_toolbar": "^1.18",
means go ahead and update but within 1.x (not 2.x)
This is backed up by a comment (General Redneck) on this post: https://www.jeffgeerling.com/blog/2018/updating-drupalcore-composer-drupal-core-doesnt-update
"One of the things I've found as I work in support is that locking down the versions of modules and core is a good idea so that you CAN thermonuke the thing when you want because there are times when some of the various plugins even don't want to behave correctly."
By the way, the composer.lock file is no help with composer update
because it gets blown away (as opposed to composer install
where he lock file is read):
Running composer install
will:
- Check if a
composer.lock
exists
- If not, perform a
composer update
to create one
- If
composer.lock
exists, install the specified versions from the lock file
Running composer update
will:
- Check
composer.json
- Determine the latest versions to install based on your version specs
- Install the latest versions
- Update
composer.lock
to reflect the latest versions installed
Ref: https://www.engineyard.com/blog/composer-its-all-about-the-lock-file
I see this is mentioned above: https://github.com/drupal-composer/drupal-project. I have used that and it's fine but it is not a requirement for using Composer with Drupal. It is confusing as it sort of "sounds" like it is from the name. When I first started with Drupal 8 I thought it was required, so built my first D8 site with that, thinking it was best practice.
That "version" of Drupal has he docroot in a /web folder, not in the top folder of the project. Also there is a bunch of stuff added to .gitignore compared to normal Drupal:
/drush/contrib/
/vendor/
/web/core/
/web/modules/contrib/
/web/themes/contrib/
/web/profiles/contrib/
/web/libraries/
So, this version of Drupal is really more meant for sites which are using continuous integration to do a new build of Drupal on every deploy, using composer install. If you deploy with a more normal method, you obviously have to commit all the above stuff to your git repo or it will not get deployed to your server [1], and that stuff is all needed for Drupal to run.
[1] if git is involved with your deploy - if you deploy with SFTP, ignore this.