CiviCRM Extension Composer Plugin

Published
2024-11-26 14:44
Written by
jackrabbithanna - member of the CiviCRM community - view blog guidelines

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.

Filed under

Comments

Thanks @jackrabbithanna. This looks like a really useful stop-gap solution, and one which would likely work well with build steps.I can definitely see cases where this would be useful.

I notice that it's using the packaged .zip archives, so I assume you would have issues if you wanted to use a specific commit that hadn't gone into an official release yet?

@bradleyt

No, it only downloads a zip and doesn't clone a repo and checkout a branch/tag/commit
You could manually checkout the repo and create your own zip and place it "somewhere" that then the extension could fetch.

> I notice that it's using the packaged .zip archives, so I assume you would have issues if you wanted to use a specific commit that hadn't gone into an official release yet?

That depends on whether the releases are simple exports or compiled outputs. I'd wager most extensions are simple exports, and (for those) Github can do it easily. Just give a "tree-ish identifer" (branch or tag or commit) in the download URL.

https://github.com/OWNER/REPO/archive/COMMIT.zip

But if it needs some kind of compilation, then that's not enough.