Restore composer.json after failed drush installation

Created on 16 October 2024, 9 months ago

Problem/Motivation

In this Slack thread we've discussed the details:

jurgenhaas
I have a follow-up question to https://www.drupal.org/node/3459196 where we added a new variable $_UPGRADE_STATUS_COMPOSER_EXTRA to the composer command for the upgrade status job. Now, I run into a similar issue in the .require-drush include task, where composer require is used but also without the optional composer extra arguments. Should we use $COMPOSER_EXTRA there just like in the major composer update command? Without adding those extras, drush can't be installed if we e.g. have to ignore a system extension dependency. But without drush being installed, the composer-lint task is failing for some strange resaon.

Here is a sample pipeline for that: https://git.drupalcode.org/project/sqrl/-/pipelines/311538

fjgarlin

I thought we were taking care of the composer.lock file here https://git.drupalcode.org/project/gitlab_templates/-/blob/main/includes/include.drupalci.main.yml?ref_type=heads#L489-498

are you on the latest _GITLAB_TEMPLATES_REF ?

ignore the above. I was on the wrong composer validate

yeah, I see installing drush failed in the composer step.

I wonder if that kept the changes in composer.json but not composer.lock

jurgenhaas

That's what it looks like, yes.

fjgarlin

we are capturing the error in here

      # Install drush (if not present) but allow failures as it might not be compatible with all Drupal versions.
      composer require --dev --update-with-all-dependencies drush/drush || EXIT_CODE_DRUSH_REQUIRE=$?
      if [ "$EXIT_CODE_DRUSH_REQUIRE" != "" ]; then
        printf "$DIVIDER\nWARNING: Drush could NOT be installed. This is not a hard dependency for the default jobs, so this is just a warning.$DIVIDER\n"
      fi

so we could potentially revert the issue inside the if [ "$EXIT_CODE_DRUSH_REQUIRE" != "" ]; then

fjgarlin

do you mind creating an issue with the above info?

drush shouldn’t be a hard dependency, so if it fails we should just leave the files as before trying

Proposed resolution

Revert composer.json after failed drush installation so that it matches the composer.lock file.

πŸ› Bug report
Status

Active

Component

gitlab-ci

Created by

πŸ‡©πŸ‡ͺGermany jurgenhaas Gottmadingen

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Merge Requests

Comments & Activities

  • Issue created by @jurgenhaas
  • First commit to issue fork.
  • Merge request !274Revert change. β†’ (Merged) created by fjgarlin
  • πŸ‡ͺπŸ‡ΈSpain fjgarlin

    Ready for review.

  • πŸ‡©πŸ‡ͺGermany jurgenhaas Gottmadingen

    Hmm, not sure what's going on. The composer require fails with a PHP stack trace and so does the composer remove afterwards as well. As if something got into the code base which conflicts with something in composer.

    See https://git.drupalcode.org/project/sqrl/-/jobs/3069951 where I have used issue/gitlab_templates-3481194 and 3481194-revert-failed-drush-changes as variables when running the pipeline.

  • πŸ‡ͺπŸ‡ΈSpain fjgarlin

    Thanks for the quick test. It was a quick MR to see if that'd be enough, but it's not.

    We can probably copy the composer.json/lock files before trying the operation and if it fails, then put those files back and run "composer install" again, as if nothing would have happened.

    I'm not sure I'll have the time to work on it today, but I'll make notes in the MR right now so I won't forget or if anybody wants to give it a go.

  • πŸ‡ͺπŸ‡ΈSpain fjgarlin

    I went ahead and did the change directly as I was almost typing full commands πŸ˜…
    Ready for testing again.

  • πŸ‡ΊπŸ‡ΈUnited States cmlara

    Just a note: this was a composer crash.

    Normally composer will revert the composer.json back if it is unable to require a new package due to resolution issues.

    Likely it is this Composer bug:
    https://github.com/composer/composer/issues/12151

    Especially since the module has the following in its .gitlab-ci.yml:

    COMPOSER_EXTRA: '--ignore-platform-req=ext-sodium'
    

    Arguably this failure may be correct as the situation implies composer had a serious problem and the system is in an inconsistent state, composer could have written files into vendor/ and than crashed corrupting the rest of the results (I’m not sure when the lock file is written, before or after file writing).

    Would suggest considering this works as designed.

    Side note: the drush job needs to ignore extensions as well for it to ever work in this scenario.

  • πŸ‡©πŸ‡ͺGermany jurgenhaas Gottmadingen

    Especially since the module has the following in its .gitlab-ci.yml: COMPOSER_EXTRA

    That's why I suggested, that this variable should also be used for all subsequent composer commands. That's why extra arguments are provided and if so, they need to be used all the time.

    @fjgarlin would you mind if we added that variable to this composer command as well? I bet, the problem will then disappear.

  • πŸ‡ͺπŸ‡ΈSpain fjgarlin

    The problem is that the options are not the same for install/update/require I think. There are a couple of options in each one not compatible in the other ones.

    Note that if Drush is really required as dependency, it should be included in the project's "composer.json" file and that way COMPOSER_EXTRA will actually be taken into account.

    What we are trying in this block of code is a nice-to-have (ie: we've detected that you don't have drush but it might be useful to have it, so let's try, otherwise continue).

    So, for me, the current MR solves the issue of leaving an inconsistent composer.json/lock + vendor files. It should just try, otherwise continue as if nothing would have happened. Hard dependencies (even if they are test dependencies) should be on composer.json in my opinion.

  • πŸ‡©πŸ‡ͺGermany jurgenhaas Gottmadingen

    That's correct. However, the issue is not about drush, it's that composer fails because of a system requirement on libsodium in this project, which we don't have in our PHP images, and we can happily ignore as we don't need it for the pipelines. That said, any composer command would fail that didn't ignore that extension.

    So, I can confirm that the current MR fixes the issue in the sqrl project.

    My concern is, we only avoid the symptom, while the underlying issue is still there and could hit us elsewhere anytime again.

    But I take your point, that composer extras can be different for each command. Not so for ignoring requirements. They are the same everywhere. Maybe we should start a follow-up issue to propose that we provide separate support for ignoring requirements and then use that for all composer commands when not empty?

  • πŸ‡ͺπŸ‡ΈSpain fjgarlin

    Happy for a follow-up, but I also quote myself from before:

    Note that if Drush is really required as dependency, it should be included in the project's "composer.json" file and that way COMPOSER_EXTRA will actually be taken into account.

    Thanks for the review

  • πŸ‡©πŸ‡ͺGermany jurgenhaas Gottmadingen

    Sure, but we don't need drush.

  • πŸ‡ͺπŸ‡ΈSpain fjgarlin

    Oh cool. In that case, I don't think we are calling any other composer update/require anywhere else in the codebase. The drush one is a special case, and this code will fix any quirks, and the "upgrade status" one has a dedicated variable, so I think we're good when it comes to variables.

    That also means, that a hard failure in composer install should provoke an error exist in the composer jobs I guess.

    But I might be missing something (foggy brain, long week), so if you feel that we need a follow-up for a case not covered, just create it and we can discuss further in there.

  • Pipeline finished with Skipped
    9 months ago
    #316881
    • fjgarlin β†’ committed ee06b5cd on main
      Issue #3481194 by fjgarlin, jurgenhaas, cmlara: Restore composer.json...
  • πŸ‡ͺπŸ‡ΈSpain fjgarlin

    Merged. Thanks!

  • Automatically closed - issue fixed for 2 weeks with no activity.

Production build 0.71.5 2024