Fix .env updates for double quotations (#259)

This commit is contained in:
Saeed Vaziry 2024-07-27 17:43:46 +02:00 committed by GitHub
parent 9473d198e1
commit ed8965b92b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 79 additions and 14 deletions

View File

@ -2,10 +2,14 @@
namespace App\Actions\Site;
use App\Exceptions\SSHUploadFailed;
use App\Models\Site;
class UpdateEnv
{
/**
* @throws SSHUploadFailed
*/
public function update(Site $site, array $input): void
{
$site->server->os()->editFile(

View File

@ -0,0 +1,8 @@
<?php
namespace App\Exceptions;
class SSHUploadFailed extends SSHError
{
//
}

View File

@ -16,6 +16,8 @@
* @method static string exec(string $command, string $log = '', int $siteId = null, ?bool $stream = false)
* @method static string assertExecuted(array|string $commands)
* @method static string assertExecutedContains(string $command)
* @method static string assertFileUploaded(string $toPath, ?string $content = null)
* @method static string getUploadedLocalPath()
* @method static disconnect()
*/
class SSH extends FacadeAlias

View File

@ -10,6 +10,7 @@
use App\Exceptions\RepositoryNotFound;
use App\Exceptions\RepositoryPermissionDenied;
use App\Exceptions\SourceControlIsNotConnected;
use App\Exceptions\SSHUploadFailed;
use App\Facades\Toast;
use App\Helpers\HtmxResponse;
use App\Models\Deployment;
@ -81,9 +82,12 @@ public function updateEnv(Server $server, Site $site, Request $request): Redirec
{
$this->authorize('manage', $server);
app(UpdateEnv::class)->update($site, $request->input());
Toast::success('Env updated!');
try {
app(UpdateEnv::class)->update($site, $request->input());
Toast::success('Env updated!');
} catch (SSHUploadFailed) {
Toast::error('Failed to update .env file!');
}
return back();
}

View File

@ -2,9 +2,14 @@
namespace App\SSH\OS;
use App\Exceptions\SSHUploadFailed;
use App\Models\Server;
use App\Models\ServerLog;
use App\SSH\HasScripts;
use Illuminate\Filesystem\FilesystemAdapter;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
use Throwable;
class OS
{
@ -109,14 +114,25 @@ public function reboot(): void
);
}
/**
* @throws SSHUploadFailed
*/
public function editFile(string $path, ?string $content = null): void
{
$this->server->ssh()->exec(
$this->getScript('edit-file.sh', [
'path' => $path,
'content' => $content ?? '',
]),
);
$tmpName = Str::random(10).strtotime('now');
try {
/** @var FilesystemAdapter $storageDisk */
$storageDisk = Storage::disk('local');
$storageDisk->put($tmpName, $content);
$this->server->ssh()->upload(
$storageDisk->path($tmpName),
$path
);
} catch (Throwable) {
throw new SSHUploadFailed();
} finally {
$this->deleteTempFile($tmpName);
}
}
public function readFile(string $path): string
@ -200,4 +216,11 @@ public function resourceInfo(): array
'disk_free' => str($info)->after('disk_free:')->before(PHP_EOL)->toString(),
];
}
private function deleteTempFile(string $name): void
{
if (Storage::disk('local')->exists($name)) {
Storage::disk('local')->delete($name);
}
}
}

View File

@ -1,3 +0,0 @@
if ! echo "__content__" | tee __path__; then
echo 'VITO_SSH_ERROR' && exit 1
fi

View File

@ -17,6 +17,12 @@ class SSHFake extends SSH
protected bool $connectionWillFail = false;
protected string $uploadedLocalPath;
protected string $uploadedRemotePath;
protected string $uploadedContent;
public function __construct(?string $output = null)
{
$this->output = $output;
@ -63,6 +69,9 @@ public function exec(string $command, string $log = '', ?int $siteId = null, ?bo
public function upload(string $local, string $remote): void
{
$this->uploadedLocalPath = $local;
$this->uploadedRemotePath = $remote;
$this->uploadedContent = file_get_contents($local);
$this->log = null;
}
@ -105,4 +114,22 @@ public function assertExecutedContains(string $command): void
}
Assert::assertTrue(true, $executed);
}
public function assertFileUploaded(string $toPath, ?string $content = null): void
{
if (! $this->uploadedLocalPath || ! $this->uploadedRemotePath) {
Assert::fail('File is not uploaded');
}
Assert::assertEquals($toPath, $this->uploadedRemotePath);
if ($content) {
Assert::assertEquals($content, $this->uploadedContent);
}
}
public function getUploadedLocalPath(): string
{
return $this->uploadedLocalPath;
}
}

View File

@ -179,10 +179,10 @@ public function test_update_env_file(): void
'server' => $this->server,
'site' => $this->site,
]), [
'env' => 'APP_ENV=production',
'env' => 'APP_ENV="production"',
])->assertSessionDoesntHaveErrors();
SSH::assertExecutedContains('echo "APP_ENV=production" | tee /home/vito/'.$this->site->domain.'/.env');
SSH::assertFileUploaded('/home/vito/'.$this->site->domain.'/.env', 'APP_ENV="production"');
}
public function test_git_hook_deployment(): void