diff --git a/app/Http/Livewire/Project/Application/Deploy.php b/app/Http/Livewire/Project/Application/Deploy.php
index 23d6bdbee..fc64dc3ce 100644
--- a/app/Http/Livewire/Project/Application/Deploy.php
+++ b/app/Http/Livewire/Project/Application/Deploy.php
@@ -23,7 +23,7 @@ class Deploy extends Component
public function mount()
{
- $this->parameters = Route::current()->parameters();
+ $this->parameters = saveParameters();
$this->application = Application::where('id', $this->applicationId)->first();
$this->destination = $this->application->destination->getMorphClass()::where('id', $this->application->destination->id)->first();
}
diff --git a/app/Http/Livewire/Project/Application/EnvironmentVariable/Add.php b/app/Http/Livewire/Project/Application/EnvironmentVariable/Add.php
index cde5876fd..1947da9dc 100644
--- a/app/Http/Livewire/Project/Application/EnvironmentVariable/Add.php
+++ b/app/Http/Livewire/Project/Application/EnvironmentVariable/Add.php
@@ -23,7 +23,7 @@ class Add extends Component
];
public function mount()
{
- $this->parameters = Route::current()->parameters();
+ $this->parameters = saveParameters();
}
public function submit()
{
diff --git a/app/Http/Livewire/Project/Application/EnvironmentVariable/Show.php b/app/Http/Livewire/Project/Application/EnvironmentVariable/Show.php
index 8c855e8f4..e01caf139 100644
--- a/app/Http/Livewire/Project/Application/EnvironmentVariable/Show.php
+++ b/app/Http/Livewire/Project/Application/EnvironmentVariable/Show.php
@@ -20,7 +20,7 @@ class Show extends Component
];
public function mount()
{
- $this->parameters = Route::current()->parameters();
+ $this->parameters = saveParameters();
}
public function submit()
{
diff --git a/app/Http/Livewire/Project/Application/Storages/Add.php b/app/Http/Livewire/Project/Application/Storages/Add.php
index 8e2c9a384..4c03551b1 100644
--- a/app/Http/Livewire/Project/Application/Storages/Add.php
+++ b/app/Http/Livewire/Project/Application/Storages/Add.php
@@ -23,7 +23,7 @@ class Add extends Component
];
public function mount()
{
- $this->parameters = Route::current()->parameters();
+ $this->parameters = saveParameters();
}
public function submit()
{
diff --git a/app/Http/Livewire/Project/New/GithubPrivateRepository.php b/app/Http/Livewire/Project/New/GithubPrivateRepository.php
new file mode 100644
index 000000000..e7418e2c9
--- /dev/null
+++ b/app/Http/Livewire/Project/New/GithubPrivateRepository.php
@@ -0,0 +1,142 @@
+page);
+ $response = Http::withToken($this->token)->get("{$this->github_app->api_url}/installation/repositories?per_page=100&page={$this->page}");
+ $json = $response->json();
+ if ($response->status() !== 200) {
+ return $this->emit('error', $json['message']);
+ }
+
+ if ($json['total_count'] === 0) {
+ return;
+ }
+ $this->total_repositories_count = $json['total_count'];
+ $this->repositories = $this->repositories->concat(collect($json['repositories']));
+ }
+ protected function loadBranchByPage()
+ {
+ Log::info('Loading page ' . $this->page);
+ $response = Http::withToken($this->token)->get("{$this->github_app->api_url}/repos/{$this->selected_repository_owner}/{$this->selected_repository_repo}/branches?per_page=100&page={$this->page}");
+ $json = $response->json();
+ if ($response->status() !== 200) {
+ return $this->emit('error', $json['message']);
+ }
+
+ $this->total_branches_count = count($json);
+ $this->branches = $this->branches->concat(collect($json));
+ }
+ public function loadRepositories($github_app_id)
+ {
+ $this->repositories = collect();
+ $this->page = 1;
+ $this->github_app = GithubApp::where('id', $github_app_id)->first();
+ $this->token = generate_github_token($this->github_app);
+ $this->loadRepositoryByPage();
+ if ($this->repositories->count() < $this->total_repositories_count) {
+ while ($this->repositories->count() < $this->total_repositories_count) {
+ $this->page++;
+ $this->loadRepositoryByPage();
+ }
+ }
+ $this->selected_repository_id = $this->repositories[0]['id'];
+ }
+ public function loadBranches()
+ {
+ $this->selected_repository_owner = $this->repositories->where('id', $this->selected_repository_id)->first()['owner']['login'];
+ $this->selected_repository_repo = $this->repositories->where('id', $this->selected_repository_id)->first()['name'];
+ $this->branches = collect();
+ $this->page = 1;
+ $this->loadBranchByPage();
+ if ($this->total_branches_count === 100) {
+ while ($this->total_branches_count === 100) {
+ $this->page++;
+ $this->loadBranchByPage();
+ }
+ }
+ }
+ public function loadServers()
+ {
+ $this->servers = Server::validated();
+ $this->selected_server_id = $this->servers[0]['id'];
+ }
+ public function loadDestinations()
+ {
+ $server = $this->servers->where('id', $this->selected_server_id)->first();
+ $this->destinations = $server->standaloneDockers->merge($server->swarmDockers);
+ $this->selected_destination_id = $this->destinations[0]['id'];
+ $this->selected_destination_class = $this->destinations[0]->getMorphClass();
+ }
+ public function submit()
+ {
+ try {
+ $project = Project::where('uuid', $this->parameters['project_uuid'])->first();
+ $environment = $project->load(['environments'])->environments->where('name', $this->parameters['environment_name'])->first();
+ $application = Application::create([
+ 'name' => "{$this->selected_repository_owner}/{$this->selected_repository_repo}:{$this->selected_branch_name}",
+ 'git_repository' => "{$this->selected_repository_owner}/{$this->selected_repository_repo}",
+ 'git_branch' => $this->selected_branch_name,
+ 'build_pack' => 'nixpacks',
+ 'ports_exposes' => '3000',
+ 'environment_id' => $environment->id,
+ 'destination_id' => $this->selected_destination_id,
+ 'destination_type' => $this->selected_destination_class,
+ 'source_id' => $this->github_app->id,
+ 'source_type' => GithubApp::class,
+ ]);
+ redirect()->route('project.application.configuration', [
+ 'application_uuid' => $application->uuid,
+ 'project_uuid' => $project->uuid,
+ 'environment_name' => $environment->name
+ ]);
+ } catch (\Exception $e) {
+ $this->emit('error', $e->getMessage());
+ }
+ }
+ public function mount()
+ {
+ $this->parameters = saveParameters();
+ $this->repositories = $this->branches = $this->servers = $this->destinations = collect();
+ $this->github_apps = GithubApp::private();
+ }
+}
diff --git a/app/Http/Livewire/Project/New/PublicGitRepository.php b/app/Http/Livewire/Project/New/PublicGitRepository.php
index bd7f18a41..da49c195d 100644
--- a/app/Http/Livewire/Project/New/PublicGitRepository.php
+++ b/app/Http/Livewire/Project/New/PublicGitRepository.php
@@ -42,7 +42,7 @@ class PublicGitRepository extends Component
$this->public_repository_url = 'https://github.com/coollabsio/coolify-examples/tree/nodejs-fastify';
$this->port = 3000;
}
- $this->parameters = Route::current()->parameters();
+ $this->parameters = saveParameters();
$this->servers = session('currentTeam')->load(['servers'])->servers;
}
public function chooseServer($server)
diff --git a/app/Http/Livewire/Server/PrivateKey.php b/app/Http/Livewire/Server/PrivateKey.php
index 6e57f4ad2..f70c3d502 100644
--- a/app/Http/Livewire/Server/PrivateKey.php
+++ b/app/Http/Livewire/Server/PrivateKey.php
@@ -20,7 +20,7 @@ class PrivateKey extends Component
}
public function mount()
{
- $this->parameters = Route::current()->parameters();
+ $this->parameters = saveParameters();
$this->private_keys = ModelsPrivateKey::where('team_id', session('currentTeam')->id)->get();
}
}
diff --git a/app/Jobs/DeployApplicationJob.php b/app/Jobs/DeployApplicationJob.php
index e6cfbe37d..752485fcf 100644
--- a/app/Jobs/DeployApplicationJob.php
+++ b/app/Jobs/DeployApplicationJob.php
@@ -372,29 +372,6 @@ COPY --from={$this->application->uuid}:{$this->git_commit}-build /app/{$this->ap
return implode(' ', $generated_healthchecks_commands);
}
- private function generate_jwt_token_for_github()
- {
- $signingKey = InMemory::plainText($this->source->privateKey->private_key);
- $algorithm = new Sha256();
- $tokenBuilder = (new Builder(new JoseEncoder(), ChainedFormatter::default()));
- $now = new DateTimeImmutable();
- $now = $now->setTime($now->format('H'), $now->format('i'));
- $issuedToken = $tokenBuilder
- ->issuedBy($this->source->app_id)
- ->issuedAt($now)
- ->expiresAt($now->modify('+10 minutes'))
- ->getToken($algorithm, $signingKey)
- ->toString();
- $token = Http::withHeaders([
- 'Authorization' => "Bearer $issuedToken",
- 'Accept' => 'application/vnd.github.machine-man-preview+json'
- ])->post("{$this->source->api_url}/app/installations/{$this->source->installation_id}/access_tokens");
- if ($token->failed()) {
- throw new \Exception("Failed to get access token for $this->application->name from " . $this->source->name . " with error: " . $token->json()['message']);
- }
- return $token->json()['token'];
- }
-
private function set_labels_for_applications()
{
$labels = [];
@@ -472,8 +449,7 @@ COPY --from={$this->application->uuid}:{$this->git_commit}-build /app/{$this->ap
$source_html_url_scheme = $url['scheme'];
$git_clone_command = "git clone -q -b {$this->application->git_branch}";
-
- if ($this->application->source->getMorphClass() == 'App\Models\GithubApp') {
+ if ($this->source->getMorphClass() == 'App\Models\GithubApp') {
if ($this->source->is_public) {
$git_clone_command = "{$git_clone_command} {$this->source->html_url}/{$this->application->git_repository} {$this->workdir}";
$git_clone_command = $this->setGitImportSettings($git_clone_command);
@@ -481,12 +457,11 @@ COPY --from={$this->application->uuid}:{$this->git_commit}-build /app/{$this->ap
$this->execute_in_builder($git_clone_command)
];
} else {
- if (!$this->application->source->app_id) {
- $private_key = base64_encode($this->application->source->privateKey->private_key);
+ if (!$this->source->app_id) {
+ $private_key = base64_encode($this->source->privateKey->private_key);
$git_clone_command = "GIT_SSH_COMMAND=\"ssh -o LogLevel=ERROR -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i /root/.ssh/id_rsa\" {$git_clone_command} git@$source_html_url_host:{$this->application->git_repository}.git {$this->workdir}";
$git_clone_command = $this->setGitImportSettings($git_clone_command);
-
return [
$this->execute_in_builder("mkdir -p /root/.ssh"),
$this->execute_in_builder("echo '{$private_key}' | base64 -d > /root/.ssh/id_rsa"),
@@ -494,7 +469,7 @@ COPY --from={$this->application->uuid}:{$this->git_commit}-build /app/{$this->ap
$this->execute_in_builder($git_clone_command)
];
} else {
- $github_access_token = $this->generate_jwt_token_for_github();
+ $github_access_token = generate_github_token($this->source);
return [
$this->execute_in_builder("git clone -q -b {$this->application->git_branch} $source_html_url_scheme://x-access-token:$github_access_token@$source_html_url_host/{$this->application->git_repository}.git {$this->workdir}")
];
diff --git a/app/Models/GithubApp.php b/app/Models/GithubApp.php
index 5e16fa574..b7a624b5b 100644
--- a/app/Models/GithubApp.php
+++ b/app/Models/GithubApp.php
@@ -15,4 +15,12 @@ class GithubApp extends BaseModel
{
return $this->belongsTo(PrivateKey::class);
}
+ static public function public()
+ {
+ return GithubApp::where('team_id', session('currentTeam')->id)->where('is_public', true)->get();
+ }
+ static public function private()
+ {
+ return GithubApp::where('team_id', session('currentTeam')->id)->where('is_public', false)->get();
+ }
}
diff --git a/bootstrap/helpers.php b/bootstrap/helpers.php
index d913fb94f..71505312a 100644
--- a/bootstrap/helpers.php
+++ b/bootstrap/helpers.php
@@ -2,6 +2,7 @@
use App\Actions\CoolifyTask\PrepareCoolifyTask;
use App\Data\CoolifyTaskArgs;
+use App\Models\GithubApp;
use App\Models\Server;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\QueryException;
@@ -9,6 +10,7 @@ use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Process;
+use Illuminate\Support\Facades\Route;
use Illuminate\Support\Facades\Storage;
use Spatie\Activitylog\Contracts\Activity;
@@ -174,3 +176,40 @@ if (!function_exists('generateRandomName')) {
return $generator->getName();
}
}
+
+use Lcobucci\JWT\Encoding\ChainedFormatter;
+use Lcobucci\JWT\Encoding\JoseEncoder;
+use Lcobucci\JWT\Signer\Key\InMemory;
+use Lcobucci\JWT\Signer\Rsa\Sha256;
+use Lcobucci\JWT\Token\Builder;
+
+if (!function_exists('generate_github_token')) {
+ function generate_github_token(GithubApp $source)
+ {
+ $signingKey = InMemory::plainText($source->privateKey->private_key);
+ $algorithm = new Sha256();
+ $tokenBuilder = (new Builder(new JoseEncoder(), ChainedFormatter::default()));
+ $now = new DateTimeImmutable();
+ $now = $now->setTime($now->format('H'), $now->format('i'));
+ $issuedToken = $tokenBuilder
+ ->issuedBy($source->app_id)
+ ->issuedAt($now)
+ ->expiresAt($now->modify('+10 minutes'))
+ ->getToken($algorithm, $signingKey)
+ ->toString();
+ $token = Http::withHeaders([
+ 'Authorization' => "Bearer $issuedToken",
+ 'Accept' => 'application/vnd.github.machine-man-preview+json'
+ ])->post("{$source->api_url}/app/installations/{$source->installation_id}/access_tokens");
+ if ($token->failed()) {
+ throw new \Exception("Failed to get access token for " . $source->name . " with error: " . $token->json()['message']);
+ }
+ return $token->json()['token'];
+ }
+}
+if (!function_exists('saveParameters')) {
+ function saveParameters()
+ {
+ return Route::current()->parameters();
+ }
+}
diff --git a/database/seeders/ApplicationSeeder.php b/database/seeders/ApplicationSeeder.php
index 2a03a7911..2c6fb736e 100644
--- a/database/seeders/ApplicationSeeder.php
+++ b/database/seeders/ApplicationSeeder.php
@@ -24,7 +24,7 @@ class ApplicationSeeder extends Seeder
$github_public_source = GithubApp::where('name', 'Public GitHub')->first();
Application::create([
- 'name' => 'Public application (from GitHub)',
+ 'name' => 'coollabsio/coolify-examples:nodejs-fastify',
'git_repository' => 'coollabsio/coolify-examples',
'git_branch' => 'nodejs-fastify',
'build_pack' => 'nixpacks',
diff --git a/database/seeders/GithubAppSeeder.php b/database/seeders/GithubAppSeeder.php
index 9e468f913..8a980b91c 100644
--- a/database/seeders/GithubAppSeeder.php
+++ b/database/seeders/GithubAppSeeder.php
@@ -31,7 +31,7 @@ class GithubAppSeeder extends Seeder
'html_url' => 'https://github.com',
'is_public' => false,
'app_id' => 292941,
- 'installation_id' => 34157139,
+ 'installation_id' => 37267016,
'client_id' => 'Iv1.220e564d2b0abd8c',
'client_secret' => '96b1b31f36ce0a34386d11798ff35b9b6d8aba3a',
'webhook_secret' => '326a47b49054f03288f800d81247ec9414d0abf3',
diff --git a/database/seeders/LocalPersistentVolumeSeeder.php b/database/seeders/LocalPersistentVolumeSeeder.php
index 61f0f7ae5..79c105ed3 100644
--- a/database/seeders/LocalPersistentVolumeSeeder.php
+++ b/database/seeders/LocalPersistentVolumeSeeder.php
@@ -13,11 +13,10 @@ class LocalPersistentVolumeSeeder extends Seeder
*/
public function run(): void
{
- $application = Application::where('name', 'Public application (from GitHub)')->first();
LocalPersistentVolume::create([
'name' => 'test-pv',
'mount_path' => '/data',
- 'resource_id' => $application->id,
+ 'resource_id' => 1,
'resource_type' => Application::class,
]);
}
diff --git a/resources/views/livewire/project/application/general.blade.php b/resources/views/livewire/project/application/general.blade.php
index a0d25e4bb..6ed6b5343 100644
--- a/resources/views/livewire/project/application/general.blade.php
+++ b/resources/views/livewire/project/application/general.blade.php
@@ -11,12 +11,13 @@