mirror of
https://github.com/coollabsio/coolify.git
synced 2026-11-04 10:42:23 +00:00
171 lines
6.9 KiB
PHP
171 lines
6.9 KiB
PHP
<?php
|
|
|
|
use App\Models\Application;
|
|
use App\Models\ApplicationSetting;
|
|
use App\Models\GiteaApp;
|
|
use App\Models\PrivateKey;
|
|
use Illuminate\Database\Eloquent\Model;
|
|
use Illuminate\Encryption\Encrypter;
|
|
use Illuminate\Support\Collection;
|
|
|
|
beforeEach(function () {
|
|
Model::encryptUsing(new Encrypter(str_repeat('a', 32), 'AES-256-CBC'));
|
|
});
|
|
|
|
afterEach(function () {
|
|
Model::encryptUsing(null);
|
|
});
|
|
|
|
function giteaCommandsAsString(array|Collection|string $commands): string
|
|
{
|
|
if (is_string($commands)) {
|
|
return $commands;
|
|
}
|
|
|
|
return collect($commands)->map(fn ($command) => data_get($command, 'command') ?? $command[0] ?? $command)->implode(' && ');
|
|
}
|
|
|
|
/**
|
|
* A non-expired token short-circuits refreshGiteaToken(), so no HTTP call is made.
|
|
*/
|
|
function giteaConnectedSource(string $htmlUrl = 'https://gitea.example.test'): GiteaApp
|
|
{
|
|
$source = new GiteaApp;
|
|
$source->forceFill([
|
|
'html_url' => $htmlUrl,
|
|
'api_url' => $htmlUrl.'/api/v1',
|
|
'is_public' => false,
|
|
'custom_port' => 22,
|
|
'custom_user' => 'git',
|
|
'team_id' => 1,
|
|
]);
|
|
$source->access_token = 'gt-token/with+sym';
|
|
$source->refresh_token = 'gt-refresh-token';
|
|
$source->expires_at = time() + 3600;
|
|
|
|
return $source;
|
|
}
|
|
|
|
function giteaApplicationFor(GiteaApp $source, string $repository = 'owner/private-app', bool $submodules = false): Application
|
|
{
|
|
$application = new Application;
|
|
$application->forceFill([
|
|
'uuid' => 'test-app-uuid',
|
|
'git_repository' => $repository,
|
|
'git_branch' => 'main',
|
|
'git_commit_sha' => 'HEAD',
|
|
]);
|
|
|
|
$settings = new ApplicationSetting;
|
|
$settings->is_git_shallow_clone_enabled = false;
|
|
$settings->is_git_submodules_enabled = $submodules;
|
|
$settings->is_git_lfs_enabled = false;
|
|
$application->setRelation('settings', $settings);
|
|
$application->setRelation('source', $source);
|
|
|
|
return $application;
|
|
}
|
|
|
|
it('clones a connected Gitea source over HTTPS with the OAuth token and per-command submodule credentials', function () {
|
|
$application = giteaApplicationFor(giteaConnectedSource(), submodules: true);
|
|
|
|
$result = $application->generateGitImportCommands(deployment_uuid: 'test-deployment', exec_in_docker: false);
|
|
|
|
$expectedConfig = "git -c 'url.https://oauth2:gt-token%2Fwith%2Bsym@gitea.example.test/.insteadOf=https://gitea.example.test/'";
|
|
|
|
expect($result['fullRepoUrl'])->toBe('https://oauth2:gt-token%2Fwith%2Bsym@gitea.example.test/owner/private-app.git');
|
|
expect($result['commands'])
|
|
->not->toContain('git config --global')
|
|
->toContain("{$expectedConfig} clone --recurse-submodules -b 'main' 'https://oauth2:gt-token%2Fwith%2Bsym@gitea.example.test/owner/private-app.git'")
|
|
->toContain("{$expectedConfig} submodule update --init --recursive");
|
|
});
|
|
|
|
it('fetches the Gitea pull request ref through the OAuth git config', function () {
|
|
$application = giteaApplicationFor(giteaConnectedSource(), submodules: true);
|
|
|
|
$result = $application->generateGitImportCommands(
|
|
deployment_uuid: 'test-deployment',
|
|
pull_request_id: 7,
|
|
exec_in_docker: false,
|
|
only_checkout: true,
|
|
custom_base_dir: '/artifacts/test',
|
|
);
|
|
|
|
expect($result['branch'])->toBe('pull/7/head:pr-7-coolify');
|
|
expect($result['commands'])
|
|
->toContain(".insteadOf=https://gitea.example.test/' fetch origin 'pull/7/head:pr-7-coolify'")
|
|
->not->toContain('merge-requests');
|
|
});
|
|
|
|
it('runs ls-remote for a connected Gitea source with the OAuth token and custom port', function () {
|
|
$application = giteaApplicationFor(giteaConnectedSource('http://gitea.example.test:3000'));
|
|
|
|
$result = $application->generateGitLsRemoteCommands('test-deployment', false);
|
|
|
|
expect($result['fullRepoUrl'])->toBe('http://oauth2:gt-token%2Fwith%2Bsym@gitea.example.test:3000/owner/private-app.git');
|
|
expect($result['commands'])->toContain("git ls-remote 'http://oauth2:gt-token%2Fwith%2Bsym@gitea.example.test:3000/owner/private-app.git'");
|
|
});
|
|
|
|
it('falls back to the Gitea source private key only when it belongs to the source team', function (int $keyTeamId, bool $expectKey) {
|
|
$privateKey = new PrivateKey;
|
|
$privateKey->forceFill(['team_id' => $keyTeamId, 'private_key' => 'fake-private-key']);
|
|
|
|
$source = new GiteaApp;
|
|
$source->forceFill(['html_url' => 'https://gitea.example.test', 'custom_port' => 2222, 'team_id' => 1]);
|
|
$source->setRelation('privateKey', $privateKey);
|
|
|
|
$application = giteaApplicationFor($source, 'git@gitea.example.test:owner/private-app.git');
|
|
|
|
$lsRemote = giteaCommandsAsString($application->generateGitLsRemoteCommands('test-deployment', false)['commands']);
|
|
$import = $application->generateGitImportCommands(deployment_uuid: 'test-deployment', pull_request_id: 3, exec_in_docker: false);
|
|
$importCommands = giteaCommandsAsString($import['commands']);
|
|
|
|
foreach ([$lsRemote, $importCommands] as $commands) {
|
|
expect($commands)->not->toContain('oauth2:');
|
|
$expectKey
|
|
? expect($commands)->toContain('id_rsa_coolify_')->toContain('-p 2222')
|
|
: expect($commands)->not->toContain('id_rsa_coolify_');
|
|
}
|
|
if ($expectKey) {
|
|
expect($import['branch'])->toBe('pull/3/head:pr-3-coolify');
|
|
}
|
|
})->with([
|
|
'same team' => [1, true],
|
|
'other team' => [2, false],
|
|
]);
|
|
|
|
it('clones a disconnected Gitea source without a key as a public repository', function () {
|
|
$source = new GiteaApp;
|
|
$source->forceFill(['html_url' => 'https://gitea.example.test', 'team_id' => 1]);
|
|
$source->setRelation('privateKey', null);
|
|
|
|
$application = giteaApplicationFor($source, 'https://gitea.example.test/owner/public-app.git');
|
|
|
|
$result = $application->generateGitImportCommands(deployment_uuid: 'test-deployment', exec_in_docker: false);
|
|
|
|
expect($result['fullRepoUrl'])->toBe('https://gitea.example.test/owner/public-app.git');
|
|
expect(giteaCommandsAsString($result['commands']))
|
|
->toContain("'https://gitea.example.test/owner/public-app.git'")
|
|
->not->toContain('oauth2:')
|
|
->not->toContain('id_rsa_coolify_');
|
|
});
|
|
|
|
it('links Gitea branches and commits with Gitea URL paths', function () {
|
|
$application = giteaApplicationFor(giteaConnectedSource());
|
|
$application->base_directory = '/app';
|
|
|
|
expect($application->git_branch_location)->toBe('https://gitea.example.test/owner/private-app/src/branch/main/app');
|
|
expect($application->git_commits)->toBe('https://gitea.example.test/owner/private-app/commits/branch/main');
|
|
expect($application->gitCommitLink('abc123'))->toBe('https://gitea.example.test/owner/private-app/commit/abc123');
|
|
});
|
|
|
|
it('converts a Gitea HTTP repository to SSH for deploy keys', function () {
|
|
$source = new GiteaApp;
|
|
$source->forceFill(['html_url' => 'https://gitea.example.test', 'custom_port' => 2222, 'custom_user' => 'git']);
|
|
|
|
expect(convertGitUrl('owner/repo', 'deploy_key', $source))->toBe([
|
|
'repository' => 'ssh://git@gitea.example.test:2222/owner/repo',
|
|
'port' => '2222',
|
|
]);
|
|
});
|