Skip to content

Magento 2: Changed upgrading database - #3812

Merged
peterjaap merged 3 commits into
deployphp:masterfrom
dverkade:magento2-change-db-deployment
Apr 19, 2024
Merged

peterjaap merged 3 commits into
deployphp:masterfrom
dverkade:magento2-change-db-deployment

Conversation

@dverkade

Copy link
Copy Markdown
Contributor

This PR addresses two issues:

  • Currently the Magento 2 recipe runs the following command to update the database setup:upgrade however this command does more then only upgrading the database. It can change the sort order of the modules listed in app/etc/config.php or if a module is not listed in that file it will enable that module. IMHO deployments should be consistent, and the app/etc/config.php shouldn't be changed during deployment. That's why I changed this into two commands that actually only update the DB schema and DB data. I've borrowed this from the Magento 2 Capistrano implementation, which already does it like this: https://github.com/davidalger/capistrano-magento2/blob/master/lib/capistrano/tasks/magento.rake#L261
  • I've also fixed issue Magento 2 Recipe: Use roles to execute DB tasks only on one server #3800 by only running the DB commands once on the selected servers. This will fix the issue of multiple DB upgrades which are executed on every node instead of only one node.

… once if multiple servers are selected for the deployment
@peterjaap

peterjaap commented Apr 18, 2024

Copy link
Copy Markdown
Contributor

Thanks for the PR!

Changing setup:upgrade to the two separate upgrade commands is a great idea.

However, I don't see this working;

run("{{bin/php}} {{bin/magento}} setup:db-data:upgrade --no-interaction")->once();

Afaik run() returns a string (the output of the command) and not an object to set once() on. This should be wrapped in a separate task(), which can take once(). Right, @antonmedv ?

As a sidenote, we ran into accidentally enabling non-listed modules error with setup:upgrade before. To avoid this, we created a small PHP tool to check this before the deployment task starts in our pipeline;

<?php

$output = [];
exec('php bin/magento module:status --disabled', $output, $exitCode);

// If No disabled modules, exit with exit code 1
if ($exitCode === 1) {
    exit(0);
}

$config = include 'app/etc/config.php';

$whitelistedDisabledModules = $config['whitelisted_disabled_modules'] ?? [];
$messages = [];

foreach ($output as $module) {
    if (!in_array($module, $whitelistedDisabledModules)) {
        $messages[] = $module . ' is disabled in modules but not whitelisted under whitelisted_disabled_modules in app/etc/config.php.';
    }
}

if (!empty($messages)) {
    foreach ($messages as $message) {
        echo $message . PHP_EOL;
    }
    exit(1);
} else {
    exit(0);
}

Maybe you'll find it useful too.

@antonmedv

Copy link
Copy Markdown
Member

Yeap. Once should be applied to tasks

@antonmedv
antonmedv requested a review from peterjaap April 18, 2024 15:23
@peterjaap

Copy link
Copy Markdown
Contributor

Perfect!

@peterjaap
peterjaap merged commit 8e8f496 into deployphp:master Apr 19, 2024
@peterjaap

peterjaap commented Apr 26, 2024

Copy link
Copy Markdown
Contributor

@dverkade I just had time to take a deeper look at this, and I have some concerns.

The installSchema is now ran from setup:db-schema-upgrade.

The installDataFixtures is now ran from setup:db-data:upgrade.

So far so good.

However, now $installer->removeUnusedTriggers();` seems not to be triggered.

Also, app:config:import is not ran at this point. Won't this cause issues when people put configuration settings in app/etc/config.php? The Capistrano task runs this separately, see here.

I feel like we should add app:config:import in a separate task. That does leave the removal of the unused triggers..

@dverkade

dverkade commented May 7, 2024

Copy link
Copy Markdown
Contributor Author

@peterjaap I've checked and the app:config:import command is already triggered before the db:upgrade here. So no issue there.

Regarding the removeUnusedTriggers() function. That's interesting and IMHO is an issue of Magento itself. Shouldn't that be part of the setup:db-schema:upgrade command too as this will make sure the db-schema is up to date. I've never had issues with this setup (and that particular function not being run) while using Capistrano which we have used for years before moving to Deployer.

@peterjaap

Copy link
Copy Markdown
Contributor

@dverkade I guess it won't immediately introduce issues when the unused triggers aren't removed, it's more a part of good database hygiene. Weirdly enough, that removeUnusedTriggers() call is the ONLY call in the whole of Magento where it's run.

@peterjaap

Copy link
Copy Markdown
Contributor

It also looks like that the removeUnusedTriggers() call also CREATED triggers <2.4.6, which could indeed cause issues down the line; magento/magento2#33386 (comment)

@peterjaap

Copy link
Copy Markdown
Contributor

The nicest solution would be that core Magento will contain a console command to delete the unused triggers, so we can call that too. Or that it is behind a flag in the setup:db-schema:upgrade command.

midweste pushed a commit to midweste/deployer that referenced this pull request Jun 1, 2024
* origin/master: (40 commits)
  Improve the configuration options console output in provision:configure (deployphp#3840)
  Update Craft CMS deploy recipe (deployphp#3839)
  [automatic] Update docs with bin/docgen
  Update provision.php
  Feature/UI enhancements (deployphp#3835)
  Hotfix/v7.4.0: Fixes caddyfile and realpath errors in provision:website (deployphp#3837)
  [automatic] Update docs with bin/docgen
  docs(recipe/shopware): add code syntax highlighting (deployphp#3834)
  [automatic] Update docs with bin/docgen
  docs(recipe/magento2): fix typo in conccurent (deployphp#3830)
  [automatic] Update docs with bin/docgen
  magento2 theme processing fix for 3786 (deployphp#3818)
  use md5 of task name for section id in gitlab ci (deployphp#3817)
  [automatic] Update docs with bin/docgen
  Magento 2: Changed upgrading database (deployphp#3812)
  [automatic] Update docs with bin/docgen
  Shopware: Added `deploy:update_code` (deployphp#3816)
  [automatic] Update docs with bin/docgen
  Update nodejs to LTS version (deployphp#3815)
  Update LICENSE
  ...
@rickvb97-io

Copy link
Copy Markdown

Hi guys, we recently upgraded our deployer package from v4.7.0 to v7.5.5 and noticed that this change breaks deployments (to production) if dev modules are committed in the app/etc/config.php file. Due to this change, we had to rollback the module update. Is this something that can be fixed?

@peterjaap

Copy link
Copy Markdown
Contributor

@rickvb97-io why would there be dev modules in an config.php that goes to production?

@dverkade

Copy link
Copy Markdown
Contributor Author

@rickvb97-io your issue is unrelated to this pull request. If you have modules in the dev section of your composer.json they should not be in your app/etc/config.php file as PHP Deployer will only install non dev modules when deploying (to production). So this will cause your module not to be available in Magento and cause issues that the enabled module in app/etc/config.php can't be found.

@rickvb97-io

rickvb97-io commented Nov 19, 2024

Copy link
Copy Markdown

@peterjaap Because I don't think there is currently no option to exclude dev modules on a production environment in the config.php. Symlinking the config.php isn't an option, because new modules aren't added.

Not committing the dev modules in the config.php is inconvenient and only causes hassle among (our) developers.

If you have an idea, I would like to hear it.

@peterjaap

Copy link
Copy Markdown
Contributor

@rickvb97-io we use a system where we symlink the config.php in the repository to config.production.php and use a symlink locally to config.development.php. Both are committed to the Git repo.

@dverkade

Copy link
Copy Markdown
Contributor Author

@rickvb97-io @peterjaap As mentioned in my earlier comment, this is not an issue related to this PR. IMHO this should not be discussed here and if you want to continue the conversation you should open up a separate issue for it.

@peterjaap

Copy link
Copy Markdown
Contributor

Agreed

@peterjaap

peterjaap commented Nov 29, 2024

Copy link
Copy Markdown
Contributor

Not related to this repo, but I still wanted to share. Here's a diff for vendor/magento/magento2-base/setup/src/Magento/Setup/Console/Command/ModuleConfigStatusCommand.php to remove the dev modules from the check so it doesn't give this error;

10a11,12
> use Composer\Factory;
> use Composer\IO\NullIO;
88a91,102
>             $devModules = $this->getDevModules();
>             if (count($devModules)) {
>                 foreach ($devModules as $moduleName) {
>                     if (isset($currentModuleConfig[$moduleName])) {
>                         $output->writeln(
>                             '<info>Ignoring dev module ' . $moduleName . ' for this check.</info>'
>                         );
>                         unset($currentModuleConfig[$moduleName]);
>                     }
>                 }
>             }
> 
107a122,144
>     }
> 
>     private function getDevModules(): array
>     {
>         $composer = Factory::create(new NullIO());
>         $config = $composer->getConfig();
>         $rootPath = dirname($config->get('vendor-dir'));
>         $composerJsonPath = $rootPath . '/composer.json';
> 
>         $locker = $composer->getLocker();
>         $lockData = $locker->getLockData();
> 
>         $json = json_decode(file_get_contents($composerJsonPath), true);
>         $requireDevPackages = isset($json['require-dev']) ? array_keys($json['require-dev']) : [];
> 
>         $devModules = [];
>         foreach ($lockData['packages-dev'] as $package) {
>             if (in_array($package['name'], $requireDevPackages) && isset($package['type']) && $package['type'] === 'magento2-module') {
>                 $devModules[] = trim(str_replace('\\', '_', array_keys($package['autoload']['psr-4'])[0]), '_');
>             }
>         }
> 
>         return $devModules;

The only caveat I see is that when the dev module has a sequence configured and removing it will cause the config.php to re-order. This does not take that into account.

Output will be;

$ bin/magento module:config:status 
Ignoring dev module Yireo_Whoops for this check.
The modules configuration is up to date.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Magento 2 Recipe: Use roles to execute DB tasks only on one server

4 participants