From af1231f025ee64c0f282131810749f368ced2675 Mon Sep 17 00:00:00 2001 From: lukinovec Date: Sat, 13 Jun 2026 07:59:50 +0200 Subject: [PATCH 1/3] migrate-fresh can show output with verbose Don't run tenants:migrate silently by default during migrate-fresh; its output is shown when the command is run with -v/--verbose. --------- Co-authored-by: lordofthebrain --- src/Commands/MigrateFresh.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/Commands/MigrateFresh.php b/src/Commands/MigrateFresh.php index d4733552..e53d6a89 100644 --- a/src/Commands/MigrateFresh.php +++ b/src/Commands/MigrateFresh.php @@ -14,6 +14,7 @@ use Stancl\Tenancy\Concerns\ParallelCommand; use Stancl\Tenancy\Database\Contracts\TenantWithDatabase; use Stancl\Tenancy\Database\Exceptions\TenantDatabaseDoesNotExistException; use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Console\Output\NullOutput; use Symfony\Component\Console\Output\OutputInterface as OI; class MigrateFresh extends BaseCommand @@ -72,11 +73,13 @@ class MigrateFresh extends BaseCommand protected function migrateTenant(TenantWithDatabase $tenant): bool { - return $this->callSilently('tenants:migrate', [ + $output = $this->getOutput()->isVerbose() ? $this->output : new NullOutput; + + return $this->runCommand('tenants:migrate', [ '--tenants' => [$tenant->getTenantKey()], '--step' => $this->option('step'), '--force' => true, - ]) === 0; + ], $output) === 0; } protected function childHandle(mixed ...$args): bool From 1f2a017a41c5bf6e8edef4cdfdab6e960dced3db Mon Sep 17 00:00:00 2001 From: lukinovec Date: Sat, 13 Jun 2026 08:28:01 +0200 Subject: [PATCH 2/3] Add test for `tenants:migrate-fresh -v` --- tests/CommandsTest.php | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/tests/CommandsTest.php b/tests/CommandsTest.php index bda3eea9..c8e0bba4 100644 --- a/tests/CommandsTest.php +++ b/tests/CommandsTest.php @@ -366,6 +366,21 @@ test('migrate fresh command works', function () { expect(DB::table('users')->exists())->toBeFalse(); }); +test('migrate fresh command only shows migration output when run with the verbose option', function () { + $tenant = Tenant::create(); + + // pest()->artisan()->expectsOutput() cannot observe the output suppression, + // so use Artisan::call() + Artisan::output() instead. + + // By default the underlying tenants:migrate output is suppressed + Artisan::call('tenants:migrate-fresh'); + expect(Artisan::output())->not()->toContain('Migrating tenant ' . $tenant->getTenantKey()); + + // Underlying tenants:migrate output is shown when the verbose option is passed + Artisan::call('tenants:migrate-fresh -v'); + expect(Artisan::output())->toContain('Migrating tenant ' . $tenant->getTenantKey()); +}); + test('migrate fresh command respects force option in production', function () { // Set environment to production app()->detectEnvironment(fn() => 'production'); From 90ff8d78d9c85bcf5fe4c77b25c1765305fa1660 Mon Sep 17 00:00:00 2001 From: lukinovec Date: Sat, 13 Jun 2026 09:26:34 +0200 Subject: [PATCH 3/3] Try making the verbosity test pass in CI Since CI runs tests with -v, it sets SHELL_VERBOSITY to 1, making the tenants:migrate-fresh output always verbose --- tests/CommandsTest.php | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/tests/CommandsTest.php b/tests/CommandsTest.php index c8e0bba4..f1bea31a 100644 --- a/tests/CommandsTest.php +++ b/tests/CommandsTest.php @@ -368,17 +368,27 @@ test('migrate fresh command works', function () { test('migrate fresh command only shows migration output when run with the verbose option', function () { $tenant = Tenant::create(); + $migratingOutput = 'Migrating tenant ' . $tenant->getTenantKey(); - // pest()->artisan()->expectsOutput() cannot observe the output suppression, - // so use Artisan::call() + Artisan::output() instead. + // CI runs pest with -v, setting SHELL_VERBOSITY to 1, so in CI, the output is verbose by default + $shellVerbosity = getenv('SHELL_VERBOSITY'); + $_ENV['SHELL_VERBOSITY'] = $_SERVER['SHELL_VERBOSITY'] = 0; + putenv('SHELL_VERBOSITY=0'); - // By default the underlying tenants:migrate output is suppressed - Artisan::call('tenants:migrate-fresh'); - expect(Artisan::output())->not()->toContain('Migrating tenant ' . $tenant->getTenantKey()); + try { + Artisan::call('tenants:migrate-fresh'); + $defaultOutput = Artisan::output(); - // Underlying tenants:migrate output is shown when the verbose option is passed - Artisan::call('tenants:migrate-fresh -v'); - expect(Artisan::output())->toContain('Migrating tenant ' . $tenant->getTenantKey()); + Artisan::call('tenants:migrate-fresh -v'); + $verboseOutput = Artisan::output(); + } finally { + unset($_ENV['SHELL_VERBOSITY'], $_SERVER['SHELL_VERBOSITY']); + $shellVerbosity === false ? putenv('SHELL_VERBOSITY') : putenv("SHELL_VERBOSITY=$shellVerbosity"); + } + + // The output is silent by default and only shown with the verbose option + expect($defaultOutput)->not()->toContain($migratingOutput); + expect($verboseOutput)->toContain($migratingOutput); }); test('migrate fresh command respects force option in production', function () {