Integrated Composer

Learn how to deploy a site with Integrated Composer

Contributors: Ari Gold, Edward Angert.

Discuss in our Forum Discuss in Slack

Integrated Composer is a Pantheon platform feature that extends Composer functionality to WordPress and Drupal's core files, and treats them as a managed dependency. Integrated Composer enables one-click updates from the Dashboard for upstream updates and Composer dependencies on your Composer-managed Pantheon site.

Get Started With Integrated Composer

Drupal 9 with Integrated Composer

  • Follow the Drupal 9 doc to create a new Drupal 9 site with Integrated Composer built in.

  • To upgrade or migrate an existing site to Drupal 9 with Integrated Composer, visit the Migrate to Drupal 9 guide.

  • To convert an existing Drupal 8 site to a Composer-managed site with Integrated Composer, visit the Composer Convert doc.

 Note

drupal-composer-managed is the recommended Composer-based Drupal 9 upstream. The Composer-based Drupal 9 upstreams below have been deprecated.

  • drupal-project
  • drupal-recommended

You can use the Terminus Conversion Tools Plugin if you want to convert your site from one of the deprecated upstreams to the supported drupal-composer-managed upstream.

WordPress with Integrated Composer

  1. Fork the Pantheon-maintained repository from https://github.com/pantheon-upstreams/wordpress-project.

  2. Add a new Custom Upstream on the Pantheon Dashboard.

  3. Create a new WordPress site from the Upstream. Do not customize the upstream as yet.

  4. In the Dev environment, click Visit Development Site and follow the prompts to complete the CMS installation.

  5. Clone the site locally and run composer install.

Add a Dependency to an Individual Site

  1. Clone the Git repository from the Pantheon site's dashboard.

  2. Run composer install:

     composer install
  3. Add a new dependency locally:

     composer require drupal/pkg-name
  4. Commit composer.json and composer.lock and push.

    • Pantheon will run Composer, build artifacts, and deploy the changes to your Dev or Multidev environment. You can now deploy the changes from the updated Dev environment to the Test and Live environments.
  5. Complete the steps to commit Dev changes to Test and Live through your Pantheon dashboard or with Terminus env:deploy.

Remove Individual Site Dependencies

You can remove site dependencies if they are no longer needed. You should use caution when removing individual site dependencies. You can cause problems with your site if you decide you no longer need a module but leave it installed, and then remove site dependencies.

  1. Clone the database from Live to all other environments before continuing.

  2. Ensure that all modules in the package have been uninstalled. You can uninstall modules in the Drupal admin dashboard, or from the command line with Terminus:

    terminus drush site.live -- pm:uninstall module1 module2
  3. Remove the dependency locally:

     composer remove drupal/pkg-name
  4. Commit composer.json and composer.lock and push.

    • Pantheon will run Composer, generate build artifacts, etc.

Add a Package from a Private Repository

The following steps outline a method for adding a package from a private GitHub repository. For additional information on handling private packages, refer to the official Composer documentation.

For this procedure, a GitHub token will be added to your code repository. It allows anyone with the token to read and write to any private repositories associated with the issuing account. To limit the scope of the GitHub token access, you can create a new GitHub user and give that user permission to only the private repositories needed for your Composer packages and ensure your site repository code is not published publicly.

  1. Go to GitHub's Personal Access Tokens page and generate a new token. Ensure the repo scope is selected.

  2. Add the private GitHub repository to composer.json, replacing <token> with your newly generated token.

    composer.json
    "repositories": [
         {
             "type": "vcs",
             "url": "https://<token>@github.com/mycompany/my-private-repo"
         }
     ],
  3. Require the package and specify the branch, prefixed with dev-

    composer.json
     "require": {
         "mycompany/my-private-repo": "dev-branch-name"
     },
  4. Run composer update to install the new package.

  5. If the above command update works locally, commit the updated composer files and add them to your environment

    git add composer.json composer.lock
    git commit -m "Adding private package <your-package>"
    git push

Apply One-click Updates

  1. Navigate to Code in the Dev tab of the site's Dashboard.

  2. Click Check Now.

  3. If updates are available, click Apply Updates.

Upstream

Upstream refers to the source code that is hosted in the Pantheon code repository and includes the core code for Drupal, WordPress, and some customizations for the Pantheon platform.

Upstream and Site Structure

The upstream has the following directory structure:

code/
code/
├─ .gitignore
├─ composer.json
└─ pantheon.upstream.yml
├─ README.md
└─ upstream-configuration/ or upstream-config/ for WordPress
   └─ composer.json
└─ web/
   └─ sites/ for Drupal
   └─ wp-content/ for WordPress
  • .gitignore: Prevents build artifacts generated by Composer from being committed to the upstream or site code repositories. Note that changing the tracking status of composer-managed files and directories can result in build failures or lead to unexpected errors.
  • composer.json: The two different composer.json files allow customization of individual sites without inherent merge conflicts and enable one-click updates.
    • Root-level: Site-level customizations.
    • Drupal: upstream-configuration/ or WordPress: upstream-config/:
      • composer.json: Composer automatically updates composer.json with customizations for the upstream. Avoid manually modifying this file.
  • pantheon.upstream.yml: The build_step: true directive in pantheon.upstream.yml enables the build step.

When a site is created, Pantheon runs composer install, generates a composer.lock file, and commits it back to the site’s code repository. To avoid potential merge conflicts after applying an upstream update, do not commit the composer.lock file to the upstream repository.

Build artifacts are stored in a Git tag like pantheon_build_artifacts_$BRANCHNAME, where $BRANCHNAME is the name of the environment or Multidev feature branch.

It is a requirement that all build artifacts should be ignored in the .gitignore file. Ensure you add entries to the .gitignore any time you modify the build to move installation files to a new locations.

How to Add Dependencies to Your Upstream

  1. Clone the Git repository from the Pantheon site's Dashboard.

  2. Change into the Upstream's configuration directory:

    • Drupal:

      cd upstream-configuration
    • WordPress:

      cd upstream-config 
  3. Run composer require for each dependency:

    composer require drupal/pkg-name --no-update
    • --no-update tells Composer to disable automatic updates of the dependency. This makes Composer faster when adding dependencies to the Upstream as shown here.
    • --no-update should not be included when adding dependencies to a site.
  4. Optional : Set or increment the current configuration version. This step can be skipped initially. Only perform this step if you are prompted to update the Composer config version.

    • Confirm the version:

      composer config version
    • Increment the config version number when you update dependencies. If you don't increment the version number, Composer will ignore updated dependencies.

    • Replace 1.0.1 in this example with the latest version number:

      composer config version 1.0.1
  5. Commit and push.

Support

Pantheon Supports Composer 2

The version of Composer on the platform is Composer 2.

Some packages are not compatible with Composer 2. If you encounter a build error that instructs you to contact Support, validate the package version's compatibility locally first, and check Drupal's Preparing your site for Composer 2 documentation for packages that have already been identified.

Pantheon's Scope of Support for Composer

Pantheon supports the version of Composer integrated into the Pantheon platform and available for use with all Drupal 8+ and WordPress sites. Pantheon’s support for Composer is limited to the application level, and any Composer scripts or modifications made with a Composer script are outside the Pantheon Scope of Support.

Troubleshooting Code Syncs, Upstream Updates, and Redirect Errors

Site-local Drush Is Required for Drupal 9 Sites

Do not remove drush/drush from composer.json. If it's removed, terminus drush commands will fail with errors related to Twig.

Build Step Affected Files That Are Not Ignored by Git

Some users have encountered an error when Git recognizes an unexpected change in composer.json:

The build step affected files that are not ignored by git:
+ echo M composer.json M composer.lock
M composer.json M composer.lock
+ exit 1

To resolve this error:

  1. Add an empty new line to the end of composer.json:

    echo "" >> composer.json
  2. Commit and push the changes

View the Output of the Commit Log First

If you encounter an error during a code sync or if the site is missing files that should be added by Integrated Composer, the Build Log may contain information that can help you troubleshoot:

  1. Navigate to Code in the Dev tab of your Site Dashboard.

  2. In the Commit Log section, find the most recent commit and click View Log to view the Composer command that was run and the output that was given by that command.

Dashboard Workflow Shows an Error During Sync Code or Deploying to a New Environment

If there is an error in the output, it may be due to an error in the site's composer.json or composer.lock file, or there may be an issue with a Composer library the site uses.

To resolve, examine the error in the log. It may be a syntax or parse error of the JSON files, or some sort of error loading a library via Composer. You can also try running the same command on your local Git checkout of the site's code and see if you can update the composer.json and composer.lock files to run the command successfully.

Creating a New Multidev or Deploying to an Environment Results in an Empty Site

You must manually allow any plugin that acts on the code base of your site in your composer.json file. This is a Composer 2.2 requirement introduced on July 1, 2022 that provides an additional layer of security. Sites that were working previously will have builds that fail because of this new requirement. Failed builds can arise as a broken environment or as unreflected code changes after a commit.

Read more about this security requirement in Composer's Documentation

You might see one of the following issues:

  • Fatal error: Cannot redeclare format_size() (previously declared in /code/web/core/includes/common.inc:137) in /code/vendor/drupal/core/includes/common.inc on line 137

  • Pantheon error page with “No code” or “No site detected” on newly initialized environments

  • Fatal error: Cannot redeclare drupal_get_filename() (previously declared in /code/vendor/drupal/core/includes/bootstrap.inc:164) in /code/web/core/includes/bootstrap.inc on line 164

Follow the steps below to resolve the issue:

  1. Clone the site to your local computer and ensure that Composer 2.2 or later is installed locally.

  2. Run composer install and complete the interactive prompts to allow plugins.

    • The prompts will look like this:

      composer install
      composer/installers contains a Composer plugin which is currently not in your allow-plugins config. See https://getcomposer.org/allow-plugins
      Do you trust "composer/installers" to execute code and wish to enable it now? (writes "allow-plugins" to composer.json) [y,n,d,?] y
      cweagans/composer-patches contains a Composer plugin which is currently not in your allow-plugins config. See https://getcomposer.org/allow-plugins
      Do you trust "cweagans/composer-patches" to execute code and wish to enable it now? (writes "allow-plugins" to composer.json) [y,n,d,?]
  3. Commit and push the code up to your site.

Upstream Updates Cannot Be Applied

When you click Apply Updates, the process completes with the error, Something went wrong when applying updates. View log. Click View log to view the output of the log:

We were not able to perform the merge safely. See the Applying Upstream Updates doc (https://pantheon.io/docs/core-updates) for further debugging tips. Conflicts: [
  "CONFLICT (content): Merge conflict in composer.json"
]

Issue 1: The site might use a Custom Upstream.

Solution 1: Copy the Upstream URL and then follow Solution 2:

  1. From the Site Dashboard, navigate to the Dev environment.

  2. Click Settings, then About site.

  3. Copy the Upstream URL and use it instead of the Pantheon Upstream URL in Solution 2.

Issue 2: The upstream updates and your Composer changes to the site, are in a conflict that cannot be automatically merged by Git.

  • We do not recommend using Auto-resolve updates in this case since it will cause your changes to the site's composer.json file to be lost.

Solution 2:

Merge the changes manually:

  1. Create a local Git clone of the Pantheon site repository.

  2. Merge in the upstream changes:

    git remote add upstream <upstream_url> && git fetch upstream
    git merge upstream/master
  3. You will get a message that there are conflicts in composer.json that cannot be merged automatically:

    Auto-merging composer.json
    CONFLICT (content): Merge conflict in composer.json
    
    Automatic merge failed; fix conflicts and then commit the result.
  4. Resolve the conflict and follow the instructions to commit the merged changes.

  5. To verify that the merge was successful, run composer install on your local branch to verify that the composer.json parses correctly, and that the correct libraries are installed or updated. If the command fails, then the merge was not made correctly and the error message may point to how composer.json needs to change.

  6. Push the changes to Pantheon. Integrated Composer will run again with the updated composer.json.

Changes Lost During Direct Upload or Commit

Do not commit module/plugin or theme files directly to your site when in Git mode. You also should not upload module/plugin or theme files directly to your site when in SFTP mode. Direct commits and uploads will be lost because the .gitignore file in your upstream repository has several defined paths, which causes files in those directories to be ignored. These directories are:

code/web/sites
code/web/
└─ core/
└─ drush/Commands/contrib/
└─ libraries/
└─ modules/contrib/
└─ private/scripts/quicksilver
└─ profiles/contrib/
└─ sites/*/files/
└─ sites/*/private/
└─ themes/contrib/

See the .gitignore file for Drupal here.

The contrib folders are where community contributed modules, profiles, and themes would reside. The custom folders, which are not ignored, are where modules, profiles, and themes created by you would reside.

code/web/
code/web/wp-content/
└─ mu-plugins/
└─ plugins/
└─ themes/

See the .gitignore file for WordPress here.

See Add a Dependency to an Individual Site above to add module/plugin or theme as a dependency to your site.

Changes Lost During Upstream Updates

When Auto-Resolve Updates is selected and the composer.json contents are changed in the upstream, all changes the site's developers made to composer.json will be removed if Git cannot automatically merge the changes.

To resolve, there are two potential solutions:

Issues using wikimedia/composer-merge-plugin

Use of the wikimedia/composer-merge-plugin is deprecated within Drupal.

When using Pantheon's Integrated Composer, this plugin often tries to run a "composer update" during the "composer install," which is not allowed and will cause errors. We recommend removing composer-merge-plugin from your Composer toolchain.

Patches containing binary diffs fail in Pantheon

If your site contains a binary patch, such as https://www.drupal.org/files/issues/2020-06-27/2340699-110.patch, the Composer build step will fail. This is because cweagans/composer-patches use the patch utility to apply patches. The most recent version of this utility does not support binary patches and fails when deployed.

A workaround for this issue, is to reconfigure the patch to exclude the binary contents in it.

Potential Wordpress Multisite with Composer Subdirectory Solution

We support WordPress multisites with subdirectories. However, if you are working with a composer-based Multisite ​setup, your sub sites might produce redirect errors. Your reference URLs might be incorrect if your WordPress core file path looks like this: /code/web/wp.

 Note

The solution outlined below has worked for select customers, and may not work for your specific configuration / environment.

Move your WordPress core files from /code/web/wp to the /code/web root by using the example WordPress Composer script.

Note that this script is only intended as an example to help you get started. You will most likely need to make changes to match your current configuration.

FAQ

What Composer commands does Pantheon run?

All Composer commands are available through the Commit Log in the Site Dashboard's development environment.

Can I view live logs?

Composer build logs are only available after the task or action completes (or fails).

How do I view Composer's changes?

Use git diff to view changes, excluding composer.lock:

git diff d94d1a1179 -- . ':(exclude)composer.lock'

Try composer-lock-diff to see what packages have changed after composer update.

Can I use a Composer GUI?

Pantheon does not offer support for Composer GUIs or any conflicts that might be caused by one.

Why are contrib modules placed in /modules/composer instead of /modules/contrib?

Contrib modules added by Integrated Composer from the now deprecated Drupal Project upstream are placed in the /modules/composer directory in case a site already has non-Composer-managed modules in the standard /modules/contrib directory. If your site does not fall into this category, it is safe to rename the composer directory back to the standard contrib and alter the installer path to match.

We recommend upgrading to the Drupal Composer Managed Project, which installs modules to the standard contrib directory. This /modules/contrib directory is added by default to the .gitignore file which tells Git to ignore files generated by Composer. You can manually add packages and make commits up to the repository by modifying the .gitignore file with the following exception:

!/web/modules/contrib/my-non-composer-module

 Note

All modules will be overwritten by Integrated Composer if you don't add the exception code above. Don't manually add modules with the .gitignore exception if they are included in your composer.json file as this can create a conflict that causes Integrated Composer to fail.

What features are planned for Integrated Composer on Pantheon?

Pantheon's devs are working hard to make the Integrated Composer experience on Pantheon better.

Features that are still in development: