fix(team): transfer instance-wide sources to root team on deletion

Instead of nullifying source references on applications when a team is
deleted, transfer instance-wide GitHub/GitLab apps to the root team
(team_id=0) so they remain available to other teams that depend on them.

Non-instance-wide sources are still deleted along with the team.
This commit is contained in:
Andras Bacsai committed 2026-04-09 14:51:52 +02:00
1 parent ad662e5560
commit 7d2c776ae7
3 files changed
+88 -48

No files matched your search

+16 -11
View File
@@ -71,27 +71,31 @@ class Team extends Model implements SendsDiscord, SendsEmail, SendsPushover, Sen
}
});
static::deleting(function ($team) {
$keys = $team->privateKeys;
foreach ($keys as $key) {
static::deleting(function (Team $team) {
foreach ($team->privateKeys as $key) {
$key->delete();
}
// Only delete sources owned by this team, not system-wide ones from other teams
// Transfer instance-wide sources to root team so they remain available
GithubApp::where('team_id', $team->id)->where('is_system_wide', true)->update(['team_id' => 0]);
GitlabApp::where('team_id', $team->id)->where('is_system_wide', true)->update(['team_id' => 0]);
// Delete non-instance-wide sources owned by this team
$teamSources = GithubApp::where('team_id', $team->id)->get()
->merge(GitlabApp::where('team_id', $team->id)->get());
foreach ($teamSources as $source) {
$source->delete();
}
$tags = Tag::whereTeamId($team->id)->get();
foreach ($tags as $tag) {
foreach (Tag::whereTeamId($team->id)->get() as $tag) {
$tag->delete();
}
$shared_variables = $team->environment_variables();
foreach ($shared_variables as $shared_variable) {
$shared_variable->delete();
foreach ($team->environment_variables()->get() as $sharedVariable) {
$sharedVariable->delete();
}
$s3s = $team->s3s;
foreach ($s3s as $s3) {
foreach ($team->s3s as $s3) {
$s3->delete();
}
});
@@ -340,4 +344,5 @@ class Team extends Model implements SendsDiscord, SendsEmail, SendsPushover, Sen
{
return $this->hasOne(WebhookNotificationSettings::class);
}
}
-17
View File
@@ -176,23 +176,6 @@ class User extends Authenticatable implements SendsEmail
$project->forceDelete();
}
// Detach applications from other teams that reference this team's sources,
// so the GithubApp/GitlabApp deleting guard doesn't block team deletion
$githubAppIds = GithubApp::where('team_id', $team->id)->pluck('id');
$gitlabAppIds = GitlabApp::where('team_id', $team->id)->pluck('id');
if ($githubAppIds->isNotEmpty()) {
Application::where('source_type', GithubApp::class)
->whereIn('source_id', $githubAppIds)
->update(['source_id' => null, 'source_type' => null]);
}
if ($gitlabAppIds->isNotEmpty()) {
Application::where('source_type', GitlabApp::class)
->whereIn('source_id', $gitlabAppIds)
->update(['source_id' => null, 'source_type' => null]);
}
$team->members()->detach($user->id);
$team->delete();
}