fix(deployments): validate git refs before queueing

Use the existing git ref validator when a deployment is queued and
when a queued deployment starts, so only well-formed commit values
are stored and used.
This commit is contained in:
Andras Bacsai
2026-09-21 13:32:16 +02:00
parent 9bae1530bf
commit c00bf15463
3 changed files with 49 additions and 1 deletions
+1 -1
View File
@@ -237,7 +237,7 @@ class ApplicationDeploymentJob implements ShouldBeEncrypted, ShouldQueue
$this->deployment_uuid = $this->application_deployment_queue->deployment_uuid;
$this->pull_request_id = $this->application_deployment_queue->pull_request_id;
$this->commit = $this->application_deployment_queue->commit;
$this->commit = validateGitRef($this->application_deployment_queue->commit, 'deployment commit');
$this->rollback = $this->application_deployment_queue->rollback;
$this->disableBuildCache = $this->application->settings->disable_build_cache;
$this->force_rebuild = $this->application_deployment_queue->force_rebuild;
+1
View File
@@ -14,6 +14,7 @@ use Spatie\Url\Url;
function queue_application_deployment(Application $application, string $deployment_uuid, ?int $pull_request_id = 0, ?string $commit = null, bool $force_rebuild = false, bool $is_webhook = false, bool $is_api = false, bool $restart_only = false, ?string $git_type = null, bool $no_questions_asked = false, ?Server $server = null, ?StandaloneDocker $destination = null, bool $only_this_server = false, bool $rollback = false, ?string $docker_registry_image_tag = null)
{
$commit = $commit ?: ($application->git_commit_sha ?: 'HEAD');
$commit = validateGitRef($commit, 'deployment commit');
$application_id = $application->id;
$deployment_link = Url::fromString($application->link()."/deployment/{$deployment_uuid}");
$deployment_url = $deployment_link->getPath();
@@ -45,6 +45,53 @@ function makeApplication(int $environmentId, int $destinationId, ?string $gitCom
}
describe('queue_application_deployment commit resolution', function () {
test('rejects a commit with disallowed characters before creating a deployment', function () {
$application = makeApplication($this->environment->id, $this->destination->id, 'HEAD');
expect(fn () => queue_application_deployment(
application: $application,
deployment_uuid: 'invalid-queued-commit',
commit: 'abc;not-a-ref',
is_webhook: true,
))->toThrow(Exception::class, 'Invalid deployment commit');
$this->assertDatabaseMissing('application_deployment_queue', [
'deployment_uuid' => 'invalid-queued-commit',
]);
Bus::assertNotDispatched(ApplicationDeploymentJob::class);
});
test('validates the application fallback commit before creating a deployment', function () {
$application = makeApplication(
$this->environment->id,
$this->destination->id,
'$(not-a-ref)',
);
expect(fn () => queue_application_deployment(
application: $application,
deployment_uuid: 'invalid-fallback-commit',
))->toThrow(Exception::class, 'Invalid deployment commit');
$this->assertDatabaseMissing('application_deployment_queue', [
'deployment_uuid' => 'invalid-fallback-commit',
]);
Bus::assertNotDispatched(ApplicationDeploymentJob::class);
});
test('rejects a stored queue commit with disallowed characters', function () {
$application = makeApplication($this->environment->id, $this->destination->id, 'HEAD');
queue_application_deployment($application, 'stored-invalid-commit');
$deployment = ApplicationDeploymentQueue::query()
->where('deployment_uuid', 'stored-invalid-commit')
->sole();
$deployment->update(['commit' => "abc\nnot-a-ref"]);
expect(fn () => new ApplicationDeploymentJob($deployment->id))
->toThrow(Exception::class, 'Invalid deployment commit');
});
test('records a team audit event when a user queues a deployment', function () {
$user = User::factory()->create();
$this->team->members()->attach($user, ['role' => 'owner']);