'boolean', 'is_system_wide' => 'boolean', 'type' => 'string', 'runner_group_id' => 'integer', 'runner_group_name' => 'string', 'webhook_events' => 'array', ]; protected $hidden = [ 'client_secret', 'webhook_secret', ]; protected static function booted(): void { static::deleting(function (GithubApp $github_app) { $applications_count = Application::where('source_id', $github_app->id)->count(); if ($applications_count > 0) { throw new \Exception('You cannot delete this GitHub App because it is in use by '.$applications_count.' application(s). Delete them first.'); } $privateKey = $github_app->privateKey; if ($privateKey) { // Check if key is used by anything EXCEPT this GitHub app $isUsedElsewhere = $privateKey->servers()->exists() || $privateKey->applications()->exists() || $privateKey->githubApps()->where('id', '!=', $github_app->id)->exists() || $privateKey->gitlabApps()->exists(); if (! $isUsedElsewhere) { $privateKey->delete(); } else { } } }); } public static function ownedByCurrentTeam() { return GithubApp::where(function ($query) { $query->where('team_id', currentTeam()->id) ->orWhere('is_system_wide', true); }); } public function team() { return $this->belongsTo(Team::class); } public function applications() { return $this->morphMany(Application::class, 'source'); } public function privateKey() { return $this->belongsTo(PrivateKey::class); } public function runnerConfigs() { return $this->hasMany(GithubRunnerConfig::class); } public function requiredWebhookEvents(): array { $events = ['push']; if ($this->pull_requests === 'write') { $events[] = 'pull_request'; } if ($this->runnerConfigs()->exists()) { $events[] = 'workflow_job'; } return $events; } public function missingWebhookEvents(): array { $current = $this->webhook_events ?? []; return array_values(array_diff($this->requiredWebhookEvents(), $current)); } public function type(): Attribute { return Attribute::make( get: function () { if ($this->getMorphClass() === GithubApp::class) { return 'github'; } }, ); } }