75
									
								
								.github/workflows/remove-labels-and-assignees-on-close.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								.github/workflows/remove-labels-and-assignees-on-close.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,75 @@ | |||||||
|  | name: Remove Labels and Assignees on Issue Close | ||||||
|  |  | ||||||
|  | on: | ||||||
|  |   issues: | ||||||
|  |     types: [closed] | ||||||
|  |   pull_request: | ||||||
|  |     types: [closed] | ||||||
|  |   pull_request_target: | ||||||
|  |     types: [closed] | ||||||
|  |  | ||||||
|  | jobs: | ||||||
|  |   remove-labels-and-assignees: | ||||||
|  |     runs-on: ubuntu-latest | ||||||
|  |     steps: | ||||||
|  |       - name: Remove labels and assignees | ||||||
|  |         uses: actions/github-script@v7 | ||||||
|  |         with: | ||||||
|  |           github-token: ${{ secrets.GITHUB_TOKEN }} | ||||||
|  |           script: | | ||||||
|  |             const { owner, repo } = context.repo; | ||||||
|  |              | ||||||
|  |             async function processIssue(issueNumber) { | ||||||
|  |               try { | ||||||
|  |                 const { data: currentLabels } = await github.rest.issues.listLabelsOnIssue({ | ||||||
|  |                   owner, | ||||||
|  |                   repo, | ||||||
|  |                   issue_number: issueNumber | ||||||
|  |                 }); | ||||||
|  |  | ||||||
|  |                 const labelsToKeep = currentLabels | ||||||
|  |                   .filter(label => label.name === '⏱︎ Stale') | ||||||
|  |                   .map(label => label.name); | ||||||
|  |  | ||||||
|  |                 await github.rest.issues.setLabels({ | ||||||
|  |                   owner, | ||||||
|  |                   repo, | ||||||
|  |                   issue_number: issueNumber, | ||||||
|  |                   labels: labelsToKeep | ||||||
|  |                 }); | ||||||
|  |  | ||||||
|  |                 const { data: issue } = await github.rest.issues.get({ | ||||||
|  |                   owner, | ||||||
|  |                   repo, | ||||||
|  |                   issue_number: issueNumber | ||||||
|  |                 }); | ||||||
|  |  | ||||||
|  |                 if (issue.assignees && issue.assignees.length > 0) { | ||||||
|  |                   await github.rest.issues.removeAssignees({ | ||||||
|  |                     owner, | ||||||
|  |                     repo, | ||||||
|  |                     issue_number: issueNumber, | ||||||
|  |                     assignees: issue.assignees.map(assignee => assignee.login) | ||||||
|  |                   }); | ||||||
|  |                 } | ||||||
|  |               } catch (error) { | ||||||
|  |                 if (error.status !== 404) { | ||||||
|  |                   console.error(`Error processing issue ${issueNumber}:`, error); | ||||||
|  |                 } | ||||||
|  |               } | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             if (context.eventName === 'issues' || context.eventName === 'pull_request' || context.eventName === 'pull_request_target') { | ||||||
|  |               const issue = context.payload.issue || context.payload.pull_request; | ||||||
|  |               await processIssue(issue.number); | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             if (context.eventName === 'pull_request' || context.eventName === 'pull_request_target') { | ||||||
|  |               const { data: closedIssues } = await github.rest.search.issuesAndPullRequests({ | ||||||
|  |                 q: `repo:${owner}/${repo} is:issue is:closed linked:${context.payload.pull_request.number}`, | ||||||
|  |                 per_page: 100 | ||||||
|  |               }); | ||||||
|  |               for (const issue of closedIssues.items) { | ||||||
|  |                 await processIssue(issue.number); | ||||||
|  |               } | ||||||
|  |             } | ||||||
| @@ -20,6 +20,8 @@ class Navbar extends Component | |||||||
| 
 | 
 | ||||||
|     public $isDeploymentProgress = false; |     public $isDeploymentProgress = false; | ||||||
| 
 | 
 | ||||||
|  |     public $title = 'Configuration'; | ||||||
|  | 
 | ||||||
|     public function mount() |     public function mount() | ||||||
|     { |     { | ||||||
|         if (str($this->service->status())->contains('running') && is_null($this->service->config_hash)) { |         if (str($this->service->status())->contains('running') && is_null($this->service->config_hash)) { | ||||||
|   | |||||||
| @@ -33,6 +33,9 @@ class ExecuteContainerCommand extends Component | |||||||
| 
 | 
 | ||||||
|     public function mount() |     public function mount() | ||||||
|     { |     { | ||||||
|  |         if (! auth()->user()->isAdmin()) { | ||||||
|  |             abort(403); | ||||||
|  |         } | ||||||
|         $this->parameters = get_route_parameters(); |         $this->parameters = get_route_parameters(); | ||||||
|         $this->containers = collect(); |         $this->containers = collect(); | ||||||
|         $this->servers = collect(); |         $this->servers = collect(); | ||||||
| @@ -130,7 +133,6 @@ class ExecuteContainerCommand extends Component | |||||||
|     { |     { | ||||||
|         try { |         try { | ||||||
|             $container_name = data_get($this->container, 'container.Names'); |             $container_name = data_get($this->container, 'container.Names'); | ||||||
|             ray($this->container); |  | ||||||
|             if (is_null($container_name)) { |             if (is_null($container_name)) { | ||||||
|                 throw new \RuntimeException('Container not found.'); |                 throw new \RuntimeException('Container not found.'); | ||||||
|             } |             } | ||||||
|   | |||||||
| @@ -14,13 +14,6 @@ class Terminal extends Component | |||||||
| 
 | 
 | ||||||
|         $server = Server::ownedByCurrentTeam()->whereUuid($serverUuid)->firstOrFail(); |         $server = Server::ownedByCurrentTeam()->whereUuid($serverUuid)->firstOrFail(); | ||||||
| 
 | 
 | ||||||
|         // if (auth()->user()) {
 |  | ||||||
|         //     $teams = auth()->user()->teams->pluck('id');
 |  | ||||||
|         //     if (! $teams->contains($server->team_id) && ! $teams->contains(0)) {
 |  | ||||||
|         //         throw new \Exception('User is not part of the team that owns this server');
 |  | ||||||
|         //     }
 |  | ||||||
|         // }
 |  | ||||||
| 
 |  | ||||||
|         if ($isContainer) { |         if ($isContainer) { | ||||||
|             $status = getContainerStatus($server, $identifier); |             $status = getContainerStatus($server, $identifier); | ||||||
|             if ($status !== 'running') { |             if ($status !== 'running') { | ||||||
|   | |||||||
| @@ -7,7 +7,7 @@ return [ | |||||||
| 
 | 
 | ||||||
|     // The release version of your application
 |     // The release version of your application
 | ||||||
|     // Example with dynamic git hash: trim(exec('git --git-dir ' . base_path('.git') . ' log --pretty="%h" -n1 HEAD'))
 |     // Example with dynamic git hash: trim(exec('git --git-dir ' . base_path('.git') . ' log --pretty="%h" -n1 HEAD'))
 | ||||||
|     'release' => '4.0.0-beta.338', |     'release' => '4.0.0-beta.339', | ||||||
|     // When left empty or `null` the Laravel environment will be used
 |     // When left empty or `null` the Laravel environment will be used
 | ||||||
|     'environment' => config('app.env'), |     'environment' => config('app.env'), | ||||||
| 
 | 
 | ||||||
|   | |||||||
| @@ -1,3 +1,3 @@ | |||||||
| <?php | <?php | ||||||
| 
 | 
 | ||||||
| return '4.0.0-beta.338'; | return '4.0.0-beta.339'; | ||||||
|   | |||||||
| @@ -1,10 +1,10 @@ | |||||||
| { | { | ||||||
|     "coolify": { |     "coolify": { | ||||||
|         "v4": { |         "v4": { | ||||||
|             "version": "4.0.0-beta.338" |             "version": "4.0.0-beta.339" | ||||||
|         }, |         }, | ||||||
|         "nightly": { |         "nightly": { | ||||||
|             "version": "4.0.0-beta.339" |             "version": "4.0.0-beta.340" | ||||||
|         }, |         }, | ||||||
|         "helper": { |         "helper": { | ||||||
|             "version": "1.0.1" |             "version": "1.0.1" | ||||||
|   | |||||||
| @@ -23,10 +23,6 @@ | |||||||
|                 @click.prevent="activeTab = 'scheduled-tasks'; window.location.hash = 'scheduled-tasks'" |                 @click.prevent="activeTab = 'scheduled-tasks'; window.location.hash = 'scheduled-tasks'" | ||||||
|                 href="#">Scheduled Tasks |                 href="#">Scheduled Tasks | ||||||
|             </a> |             </a> | ||||||
|             <a class="menu-item sm:min-w-fit" :class="activeTab === 'terminal' && 'menu-item-active'" |  | ||||||
|                 @click.prevent="activeTab = 'terminal';
 |  | ||||||
|                 window.location.hash = 'terminal'" |  | ||||||
|                 href="#">Terminal</a> |  | ||||||
|             <a class="menu-item sm:min-w-fit" :class="activeTab === 'logs' && 'menu-item-active'" |             <a class="menu-item sm:min-w-fit" :class="activeTab === 'logs' && 'menu-item-active'" | ||||||
|                 @click.prevent="activeTab = 'logs';
 |                 @click.prevent="activeTab = 'logs';
 | ||||||
|                 window.location.hash = 'logs'" |                 window.location.hash = 'logs'" | ||||||
| @@ -191,9 +187,6 @@ | |||||||
|             <div x-cloak x-show="activeTab === 'logs'"> |             <div x-cloak x-show="activeTab === 'logs'"> | ||||||
|                 <livewire:project.shared.logs :resource="$service" /> |                 <livewire:project.shared.logs :resource="$service" /> | ||||||
|             </div> |             </div> | ||||||
|             <div x-cloak x-show="activeTab === 'terminal'"> |  | ||||||
|                 <livewire:project.shared.execute-container-command :resource="$service" /> |  | ||||||
|             </div> |  | ||||||
|             <div x-cloak x-show="activeTab === 'environment-variables'"> |             <div x-cloak x-show="activeTab === 'environment-variables'"> | ||||||
|                 <livewire:project.shared.environment-variable.all :resource="$service" /> |                 <livewire:project.shared.environment-variable.all :resource="$service" /> | ||||||
|             </div> |             </div> | ||||||
|   | |||||||
| @@ -6,17 +6,21 @@ | |||||||
|             <livewire:activity-monitor header="Logs" showWaiting fullHeight /> |             <livewire:activity-monitor header="Logs" showWaiting fullHeight /> | ||||||
|         </x-slot:content> |         </x-slot:content> | ||||||
|     </x-slide-over> |     </x-slide-over> | ||||||
|     <h1>Configuration</h1> |     <h1>{{ $title }}</h1> | ||||||
|     <x-resources.breadcrumbs :resource="$service" :parameters="$parameters" /> |     <x-resources.breadcrumbs :resource="$service" :parameters="$parameters" /> | ||||||
|     <div class="navbar-main" x-data> |     <div class="navbar-main" x-data> | ||||||
|         <nav class="flex items-center flex-shrink-0 gap-6 scrollbar min-h-10 whitespace-nowrap"> |         <nav class="flex flex-shrink-0 gap-6 items-center whitespace-nowrap scrollbar min-h-10"> | ||||||
|             <a class="{{ request()->routeIs('project.service.configuration') ? 'dark:text-white' : '' }}" |             <a class="{{ request()->routeIs('project.service.configuration') ? 'dark:text-white' : '' }}" | ||||||
|                 href="{{ route('project.service.configuration', $parameters) }}"> |                 href="{{ route('project.service.configuration', $parameters) }}"> | ||||||
|                 <button>Configuration</button> |                 <button>Configuration</button> | ||||||
|             </a> |             </a> | ||||||
|  |             <a class="{{ request()->routeIs('project.service.command') ? 'dark:text-white' : '' }}" | ||||||
|  |                 href="{{ route('project.service.command', $parameters) }}"> | ||||||
|  |                 <button>Terminal</button> | ||||||
|  |             </a> | ||||||
|             <x-services.links :service="$service" /> |             <x-services.links :service="$service" /> | ||||||
|         </nav> |         </nav> | ||||||
|         <div class="flex flex-wrap items-center order-first gap-2 sm:order-last"> |         <div class="flex flex-wrap order-first gap-2 items-center sm:order-last"> | ||||||
|             @if (str($service->status())->contains('running')) |             @if (str($service->status())->contains('running')) | ||||||
|                 <button @click="$wire.dispatch('restartEvent')" class="gap-2 button"> |                 <button @click="$wire.dispatch('restartEvent')" class="gap-2 button"> | ||||||
|                     <svg class="w-5 h-5 dark:text-warning" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"> |                     <svg class="w-5 h-5 dark:text-warning" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"> | ||||||
| @@ -71,7 +75,7 @@ | |||||||
|                 </x-modal-confirmation> |                 </x-modal-confirmation> | ||||||
|             @elseif (str($service->status())->contains('exited')) |             @elseif (str($service->status())->contains('exited')) | ||||||
|                 <button wire:click='stop(true)' class="gap-2 button"> |                 <button wire:click='stop(true)' class="gap-2 button"> | ||||||
|                     <svg class="w-5 h-5 " viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg"> |                     <svg class="w-5 h-5" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg"> | ||||||
|                         <path fill="red" d="M26 20h-6v-2h6zm4 8h-6v-2h6zm-2-4h-6v-2h6z" /> |                         <path fill="red" d="M26 20h-6v-2h6zm4 8h-6v-2h6zm-2-4h-6v-2h6z" /> | ||||||
|                         <path fill="red" |                         <path fill="red" | ||||||
|                             d="M17.003 20a4.895 4.895 0 0 0-2.404-4.173L22 3l-1.73-1l-7.577 13.126a5.699 5.699 0 0 0-5.243 1.503C3.706 20.24 3.996 28.682 4.01 29.04a1 1 0 0 0 1 .96h14.991a1 1 0 0 0 .6-1.8c-3.54-2.656-3.598-8.146-3.598-8.2Zm-5.073-3.003A3.11 3.11 0 0 1 15.004 20c0 .038.002.208.017.469l-5.9-2.624a3.8 3.8 0 0 1 2.809-.848ZM15.45 28A5.2 5.2 0 0 1 14 25h-2a6.5 6.5 0 0 0 .968 3h-2.223A16.617 16.617 0 0 1 10 24H8a17.342 17.342 0 0 0 .665 4H6c.031-1.836.29-5.892 1.803-8.553l7.533 3.35A13.025 13.025 0 0 0 17.596 28Z" /> |                             d="M17.003 20a4.895 4.895 0 0 0-2.404-4.173L22 3l-1.73-1l-7.577 13.126a5.699 5.699 0 0 0-5.243 1.503C3.706 20.24 3.996 28.682 4.01 29.04a1 1 0 0 0 1 .96h14.991a1 1 0 0 0 .6-1.8c-3.54-2.656-3.598-8.146-3.598-8.2Zm-5.073-3.003A3.11 3.11 0 0 1 15.004 20c0 .038.002.208.017.469l-5.9-2.624a3.8 3.8 0 0 1 2.809-.848ZM15.45 28A5.2 5.2 0 0 1 14 25h-2a6.5 6.5 0 0 0 .968 3h-2.223A16.617 16.617 0 0 1 10 24H8a17.342 17.342 0 0 0 .665 4H6c.031-1.836.29-5.892 1.803-8.553l7.533 3.35A13.025 13.025 0 0 0 17.596 28Z" /> | ||||||
|   | |||||||
| @@ -10,7 +10,7 @@ | |||||||
|         <h1>Terminal</h1> |         <h1>Terminal</h1> | ||||||
|         <livewire:project.database.heading :database="$resource" /> |         <livewire:project.database.heading :database="$resource" /> | ||||||
|     @elseif ($type === 'service') |     @elseif ($type === 'service') | ||||||
|         <h2>Terminal</h2> |         <livewire:project.service.navbar :service="$resource" :parameters="$parameters" title="Terminal" /> | ||||||
|     @endif |     @endif | ||||||
|     <div x-init="$wire.loadContainers"> |     <div x-init="$wire.loadContainers"> | ||||||
|         <div class="pt-4" wire:loading wire:target='loadContainers'> |         <div class="pt-4" wire:loading wire:target='loadContainers'> | ||||||
|   | |||||||
| @@ -69,9 +69,7 @@ | |||||||
|                     }; |                     }; | ||||||
|                     socket.onclose = () => { |                     socket.onclose = () => { | ||||||
|                         console.log('WebSocket connection closed'); |                         console.log('WebSocket connection closed'); | ||||||
|                         setInterval(() => { | 
 | ||||||
|                             $wire.dispatch('error', 'Connection to terminal lost, please refresh the page.'); |  | ||||||
|                         }, 2000); |  | ||||||
|                     }; |                     }; | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
| @@ -118,9 +116,8 @@ | |||||||
|                 socket.send(JSON.stringify({ |                 socket.send(JSON.stringify({ | ||||||
|                     message: data |                     message: data | ||||||
|                 })); |                 })); | ||||||
| 
 |  | ||||||
|                 // Type CTRL + D or exit in the terminal
 |                 // Type CTRL + D or exit in the terminal
 | ||||||
|                 if (data === '\x04' || (data === '\r' && stripAnsiCommands(commandBuffer).trim() === 'exit')) { |                 if (data === '\x04' || (data === '\r' && stripAnsiCommands(commandBuffer).trim().includes('exit'))) { | ||||||
|                     checkIfProcessIsRunningAndKillIt(); |                     checkIfProcessIsRunningAndKillIt(); | ||||||
|                     setTimeout(() => { |                     setTimeout(() => { | ||||||
|                         $data.terminalActive = false; |                         $data.terminalActive = false; | ||||||
| @@ -215,8 +212,8 @@ | |||||||
|                     term.resize(termWidth, termHeight); |                     term.resize(termWidth, termHeight); | ||||||
|                     socket.send(JSON.stringify({ |                     socket.send(JSON.stringify({ | ||||||
|                         resize: { |                         resize: { | ||||||
|                             cols: 600, |                             cols: termWidth, | ||||||
|                             rows: 600 |                             rows: termHeight | ||||||
|                         } |                         } | ||||||
|                     })); |                     })); | ||||||
|                 } |                 } | ||||||
|   | |||||||
| @@ -195,8 +195,8 @@ Route::middleware(['auth', 'verified'])->group(function () { | |||||||
|     }); |     }); | ||||||
|     Route::prefix('project/{project_uuid}/{environment_name}/service/{service_uuid}')->group(function () { |     Route::prefix('project/{project_uuid}/{environment_name}/service/{service_uuid}')->group(function () { | ||||||
|         Route::get('/', ServiceConfiguration::class)->name('project.service.configuration'); |         Route::get('/', ServiceConfiguration::class)->name('project.service.configuration'); | ||||||
|         Route::get('/{stack_service_uuid}', ServiceIndex::class)->name('project.service.index'); |  | ||||||
|         Route::get('/terminal', ExecuteContainerCommand::class)->name('project.service.command'); |         Route::get('/terminal', ExecuteContainerCommand::class)->name('project.service.command'); | ||||||
|  |         Route::get('/{stack_service_uuid}', ServiceIndex::class)->name('project.service.index'); | ||||||
|         Route::get('/tasks/{task_uuid}', ScheduledTaskShow::class)->name('project.service.scheduled-tasks'); |         Route::get('/tasks/{task_uuid}', ScheduledTaskShow::class)->name('project.service.scheduled-tasks'); | ||||||
|     }); |     }); | ||||||
| 
 | 
 | ||||||
|   | |||||||
| @@ -1,10 +1,10 @@ | |||||||
| { | { | ||||||
|     "coolify": { |     "coolify": { | ||||||
|         "v4": { |         "v4": { | ||||||
|             "version": "4.0.0-beta.338" |             "version": "4.0.0-beta.339" | ||||||
|         }, |         }, | ||||||
|         "nightly": { |         "nightly": { | ||||||
|             "version": "4.0.0-beta.339" |             "version": "4.0.0-beta.340" | ||||||
|         }, |         }, | ||||||
|         "helper": { |         "helper": { | ||||||
|             "version": "1.0.1" |             "version": "1.0.1" | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Andras Bacsai
					Andras Bacsai