Files
keystone/app/Actions/Environments/ResolveEnvironmentCommit.php

62 lines
1.9 KiB
PHP

<?php
namespace App\Actions\Environments;
use App\Models\Environment;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Process;
use RuntimeException;
class ResolveEnvironmentCommit
{
public function execute(Environment $environment): string
{
$environment->loadMissing('application');
$application = $environment->application;
if (! $application->deploy_key_private) {
throw new RuntimeException('Application does not have a deploy key.');
}
$directory = storage_path('app/private/operations/resolve-'.$environment->id.'-'.str()->random(8));
$keyPath = $directory.'/deploy_key';
File::ensureDirectoryExists($directory, 0700);
File::put($keyPath, $application->deploy_key_private);
File::chmod($keyPath, 0600);
try {
$result = Process::path($directory)
->env([
'GIT_SSH_COMMAND' => 'ssh -i '.$keyPath.' -o IdentitiesOnly=yes -o StrictHostKeyChecking=no',
])
->run([
'git',
'ls-remote',
$application->repository_url,
'refs/heads/'.$environment->branch,
]);
if ($result->failed()) {
throw new RuntimeException(trim($result->errorOutput()) ?: 'Unable to resolve environment commit.');
}
return $this->commitFromOutput($result->output(), $environment->branch);
} finally {
rescue(fn () => File::deleteDirectory($directory), report: false);
}
}
private function commitFromOutput(string $output, string $branch): string
{
$commit = str($output)->before("\t")->trim()->value();
if (preg_match('/^[a-f0-9]{40}$/i', $commit) !== 1) {
throw new RuntimeException("Unable to resolve commit for branch {$branch}.");
}
return strtolower($commit);
}
}