Starting with Drupal 8, composer is used to manage web site dependencies and to download packages to the server. A Drupal and CiviCRM website requires 100s of packages to provide the large set of functional components. Composer simplifies the process of determining which versions of packages will all work together appropriately, and fetching all of them and putting them in the right place in the code base.
Recently I read this recent blog article which advocates for setting a standard, that all extensions include the necessary definition to allow downloading CiviCRM extensions with composer. I agree with that blog article 100%. It would require all extension developers place the same lines of code in their project, or the CiviCRM Core team to setup the infrastructure to add it automatically. As we all know, it is hard to get 100s of people to do the same thing. There is an issue in the CiviCRM Infra issue queue, and it may result in the necessary updates. That would work for extensions in the CiviCRM Gitlab, but not for extensions stored elsewhere.
Skvare had developed a composer plugin internally to allow us to fetch extensions with composer. Although it is sub-optimal to the ideas proposed in the recent blog article, we don't have to wait. That article did inspire me to release this plugin open source and share it with the CiviCRM community.
If you'd like to download extensions today with composer, then try out the CiviCRM Extension Plugin.
To use, add this code to the "respositories" section of your site's composer.json
"civicrm-extension-plugin": {
"type": "vcs",
"url": "https://github.com/Skvare/civicrm-extension-plugin"
},
Then at the command line require the package:
composer require civicrm/civicrm-extension-plugin
Note, that this plugin does not calculate dependency compatibility between the extension composer.json and the site composer.json. It simply allows developers to download extensions to a specified location.
Next, you can specify what extensions to download in the composer.json "extra" section, example:
"extra": {
"civicrm": {
"extensions_install_path": "./web/sites/default/civicrm/extensions/contrib",
"extensions": {
"uk.co.vedaconsulting.gdpr": {
"url": "https://github.com/veda-consulting-company/uk.co.vedaconsulting.gdpr/archive/v2.7.zip"
},
"uk.co.vedaconsulting.mosaico": {
"url": "https://github.com/veda-consulting-company/uk.co.vedaconsulting.mosaico/archive/2.5.zip"
},
}
}
}
You can choose the location that composer downloads the extensions to, via the "extensions_install_path" value. We use a different location that is used by default. Stock installations should use "./web/sites/default/files/civicrm/ext"
You need to source the links to the extension zip file yourself, from links at the civicrm extensions page, or from extension repositories.
The key to the array, e.g "uk.co.vedaconsulting.gdpr" will be the directory name the extension is unpacked into. You can use any string you like.
The plugin will automatically download the extensions when the civicrm/civicrm-core package is installed or updated.
You can also trigger this action independently by executing on the command line:
composer civicrm:download-extensions
If you want to remove all downloaded extensions, before they are downloaded, then use the "clean" option. This is good if you remove an extension from the composer.json and no longer want it in your code base.
composer civicrm:download-extensions --clean
In the future, if the infrastructure is built to ensure all extensions are available with a composer installer type, then we will switch to that, but for now, we have this, and now you do too.
This plugin is compatible with Drupal versions 9, 10, and 11.
Contact Skvare if you have questions or would like support with this or Drupal/CiviCRM development in general.