feat: watch paths

This commit is contained in:
Andras Bacsai 2024-03-28 15:05:12 +01:00
parent 971b17b364
commit 51d716253f
7 changed files with 91 additions and 15 deletions

View File

@ -204,6 +204,7 @@ public function manual(Request $request)
} }
public function normal(Request $request) public function normal(Request $request)
{ {
ray('asdf');
try { try {
$return_payloads = collect([]); $return_payloads = collect([]);
$id = null; $id = null;
@ -266,6 +267,10 @@ public function normal(Request $request)
if (Str::isMatch('/refs\/heads\/*/', $branch)) { if (Str::isMatch('/refs\/heads\/*/', $branch)) {
$branch = Str::after($branch, 'refs/heads/'); $branch = Str::after($branch, 'refs/heads/');
} }
$added_files = data_get($payload, 'commits.*.added');
$removed_files = data_get($payload, 'commits.*.removed');
$modified_files = data_get($payload, 'commits.*.modified');
$changed_files = collect($added_files)->concat($removed_files)->concat($modified_files)->unique()->flatten();
ray('Webhook GitHub Push Event: ' . $id . ' with branch: ' . $branch); ray('Webhook GitHub Push Event: ' . $id . ' with branch: ' . $branch);
} }
if ($x_github_event === 'pull_request') { if ($x_github_event === 'pull_request') {
@ -306,19 +311,32 @@ public function normal(Request $request)
} }
if ($x_github_event === 'push') { if ($x_github_event === 'push') {
if ($application->isDeployable()) { if ($application->isDeployable()) {
ray('Deploying ' . $application->name . ' with branch ' . $branch); $watch_files_trigger = $application->watchPathCheck($changed_files);
$deployment_uuid = new Cuid2(7); if (!$watch_files_trigger) {
queue_application_deployment( $return_payloads->push([
application: $application, 'application' => $application->name,
deployment_uuid: $deployment_uuid, 'status' => 'failed',
force_rebuild: false, 'message' => 'Watch paths does not have the changed files. Deployment ignored.',
is_webhook: true 'details' => [
); 'changed_files' => $changed_files,
$return_payloads->push([ 'watch_paths' => $application->watch_paths,
'application' => $application->name, ],
'status' => 'success', ]);
'message' => 'Deployment queued.', } else {
]); ray('Deploying ' . $application->name . ' with branch ' . $branch);
$deployment_uuid = new Cuid2(7);
queue_application_deployment(
application: $application,
deployment_uuid: $deployment_uuid,
force_rebuild: false,
is_webhook: true,
);
$return_payloads->push([
'application' => $application->name,
'status' => 'success',
'message' => 'Deployment queued.',
]);
}
} else { } else {
$return_payloads->push([ $return_payloads->push([
'application' => $application->name, 'application' => $application->name,

View File

@ -73,6 +73,7 @@ class General extends Component
'application.settings.is_static' => 'boolean|required', 'application.settings.is_static' => 'boolean|required',
'application.settings.is_raw_compose_deployment_enabled' => 'boolean|required', 'application.settings.is_raw_compose_deployment_enabled' => 'boolean|required',
'application.settings.is_build_server_enabled' => 'boolean|required', 'application.settings.is_build_server_enabled' => 'boolean|required',
'application.watch_paths' => 'nullable',
]; ];
protected $validationAttributes = [ protected $validationAttributes = [
'application.name' => 'name', 'application.name' => 'name',
@ -108,6 +109,7 @@ class General extends Component
'application.settings.is_static' => 'Is static', 'application.settings.is_static' => 'Is static',
'application.settings.is_raw_compose_deployment_enabled' => 'Is raw compose deployment enabled', 'application.settings.is_raw_compose_deployment_enabled' => 'Is raw compose deployment enabled',
'application.settings.is_build_server_enabled' => 'Is build server enabled', 'application.settings.is_build_server_enabled' => 'Is build server enabled',
'application.watch_paths' => 'Watch paths',
]; ];
public function mount() public function mount()
{ {

View File

@ -6,6 +6,7 @@
use Illuminate\Database\Eloquent\Casts\Attribute; use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\SoftDeletes; use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Collection;
use Spatie\Activitylog\Models\Activity; use Spatie\Activitylog\Models\Activity;
use Illuminate\Support\Str; use Illuminate\Support\Str;
use RuntimeException; use RuntimeException;
@ -903,4 +904,24 @@ public function fqdns(): Attribute
: explode(',', $this->fqdn), : explode(',', $this->fqdn),
); );
} }
public function watchPaths(): Attribute
{
return Attribute::make(
set: function ($value) {
if ($value) {
return trim($value);
}
}
);
}
public function watchPathCheck(Collection $modified_files): bool
{
$watch_paths = collect(explode("\n", $this->watch_paths));
$matches = $modified_files->filter(function ($file) use ($watch_paths) {
return $watch_paths->contains(function ($glob) use ($file) {
return fnmatch($glob, $file);
});
});
return $matches->count() > 0;
}
} }

View File

@ -6,6 +6,7 @@
use App\Models\ApplicationDeploymentQueue; use App\Models\ApplicationDeploymentQueue;
use App\Models\Server; use App\Models\Server;
use App\Models\StandaloneDocker; use App\Models\StandaloneDocker;
use Illuminate\Support\Collection;
use Spatie\Url\Url; use Spatie\Url\Url;
function queue_application_deployment(Application $application, string $deployment_uuid, int | null $pull_request_id = 0, string $commit = 'HEAD', bool $force_rebuild = false, bool $is_webhook = false, bool $restart_only = false, ?string $git_type = null, bool $no_questions_asked = false, Server $server = null, StandaloneDocker $destination = null, bool $only_this_server = false) function queue_application_deployment(Application $application, string $deployment_uuid, int | null $pull_request_id = 0, string $commit = 'HEAD', bool $force_rebuild = false, bool $is_webhook = false, bool $restart_only = false, ?string $git_type = null, bool $no_questions_asked = false, Server $server = null, StandaloneDocker $destination = null, bool $only_this_server = false)

View File

@ -0,0 +1,28 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('applications', function (Blueprint $table) {
$table->longText('watch_paths')->nullable();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('applications', function (Blueprint $table) {
$table->dropColumn('watch_paths');
});
}
};

View File

@ -13,7 +13,7 @@ body {
.input, .input,
.select { .select {
@apply text-black dark:bg-coolgray-100 dark:text-white ring-neutral-300 dark:ring-coolgray-300; @apply text-black dark:bg-coolgray-100 dark:text-white ring-neutral-200 dark:ring-coolgray-300;
} }
/* Readonly */ /* Readonly */

View File

@ -148,7 +148,8 @@ class="underline" href="https://coolify.io/docs/knowledge-base/docker/registry"
id="application.start_command" label="Start Command" /> id="application.start_command" label="Start Command" />
</div> </div>
<div>Nixpacks will detect the required configuration automatically. <div>Nixpacks will detect the required configuration automatically.
<a class="underline" href="https://coolify.io/docs/resources/introduction">Framework Specific Docs</a> <a class="underline" href="https://coolify.io/docs/resources/introduction">Framework
Specific Docs</a>
</div> </div>
@endif @endif
@endif @endif
@ -201,7 +202,12 @@ class="underline" href="https://coolify.io/docs/knowledge-base/docker/registry"
label="Publish Directory" /> label="Publish Directory" />
@endif @endif
@endif @endif
</div> </div>
@if ($this->application->is_github_based())
<x-forms.textarea helper="Gitignore-style rules to filter Git based webhook deployments."
placeholder="src/pages/**" id="application.watch_paths" label="Watch Paths" />
@endif
<div>The following options are for advanced use cases. Only modify them if you <div>The following options are for advanced use cases. Only modify them if you
know what are know what are
you doing.</div> you doing.</div>