feat: added manual webhook support for bitbucket
This commit is contained in:
parent
2fdf52929c
commit
54d8cb9027
@ -10,9 +10,11 @@ class Webhooks extends Component
|
|||||||
public ?string $deploywebhook = null;
|
public ?string $deploywebhook = null;
|
||||||
public ?string $githubManualWebhook = null;
|
public ?string $githubManualWebhook = null;
|
||||||
public ?string $gitlabManualWebhook = null;
|
public ?string $gitlabManualWebhook = null;
|
||||||
|
public ?string $bitbucketManualWebhook = null;
|
||||||
protected $rules = [
|
protected $rules = [
|
||||||
'resource.manual_webhook_secret_github' => 'nullable|string',
|
'resource.manual_webhook_secret_github' => 'nullable|string',
|
||||||
'resource.manual_webhook_secret_gitlab' => 'nullable|string',
|
'resource.manual_webhook_secret_gitlab' => 'nullable|string',
|
||||||
|
'resource.manual_webhook_secret_bitbucket' => 'nullable|string',
|
||||||
];
|
];
|
||||||
public function saveSecret()
|
public function saveSecret()
|
||||||
{
|
{
|
||||||
@ -29,6 +31,7 @@ class Webhooks extends Component
|
|||||||
$this->deploywebhook = generateDeployWebhook($this->resource);
|
$this->deploywebhook = generateDeployWebhook($this->resource);
|
||||||
$this->githubManualWebhook = generateGitManualWebhook($this->resource, 'github');
|
$this->githubManualWebhook = generateGitManualWebhook($this->resource, 'github');
|
||||||
$this->gitlabManualWebhook = generateGitManualWebhook($this->resource, 'gitlab');
|
$this->gitlabManualWebhook = generateGitManualWebhook($this->resource, 'gitlab');
|
||||||
|
$this->bitbucketManualWebhook = generateGitManualWebhook($this->resource, 'bitbucket');
|
||||||
}
|
}
|
||||||
public function render()
|
public function render()
|
||||||
{
|
{
|
||||||
|
@ -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->string('manual_webhook_secret_bitbucket')->nullable();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::table('applications', function (Blueprint $table) {
|
||||||
|
$table->dropColumn('manual_webhook_secret_bitbucket');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
@ -33,6 +33,10 @@
|
|||||||
helper="Need to set a secret to be able to use this webhook. It should match with the secret in GitLab."
|
helper="Need to set a secret to be able to use this webhook. It should match with the secret in GitLab."
|
||||||
label="GitLab Webhook Secret" id="resource.manual_webhook_secret_gitlab"></x-forms.input>
|
label="GitLab Webhook Secret" id="resource.manual_webhook_secret_gitlab"></x-forms.input>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="flex gap-2">
|
||||||
|
<x-forms.input readonly label="Bitbucket" id="bitbucketManualWebhook"></x-forms.input>
|
||||||
|
<x-forms.input type="password" helper="Need to set a secret to be able to use this webhook. It should match with the secret in Bitbucket." label="Bitbucket Webhook Secret" id="resource.manual_webhook_secret_bitbucket"></x-forms.input>
|
||||||
|
</div>
|
||||||
<x-forms.button type="submit">Save</x-forms.button>
|
<x-forms.button type="submit">Save</x-forms.button>
|
||||||
</form>
|
</form>
|
||||||
@else
|
@else
|
||||||
|
@ -231,6 +231,92 @@ Route::post('/source/gitlab/events/manual', function () {
|
|||||||
return handleError($e);
|
return handleError($e);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
Route::post('/source/bitbucket/events/manual', function () {
|
||||||
|
try {
|
||||||
|
$return_payloads = collect([]);
|
||||||
|
$payload = request()->collect();
|
||||||
|
$headers = request()->headers->all();
|
||||||
|
$x_bitbucket_token = data_get($headers, 'x-hub-signature', [""])[0];
|
||||||
|
$x_bitbucket_event = data_get($headers, 'x-event-key', [""])[0];
|
||||||
|
if ($x_bitbucket_event === 'repo:push') {
|
||||||
|
$branch = data_get($payload, 'push.changes.0.new.name');
|
||||||
|
$name = data_get($payload, 'repository.name');
|
||||||
|
|
||||||
|
if (!$branch) {
|
||||||
|
$return_payloads->push([
|
||||||
|
'status' => 'failed',
|
||||||
|
'message' => 'Nothing to do. No branch found in the request.',
|
||||||
|
]);
|
||||||
|
return response($return_payloads);
|
||||||
|
}
|
||||||
|
ray('Manual Webhook bitbucket Push Event with branch: ' . $branch);
|
||||||
|
}
|
||||||
|
$applications = Application::where('git_repository', 'like', "%$name%");
|
||||||
|
if ($x_bitbucket_event === 'repo:push') {
|
||||||
|
$applications = $applications->where('git_branch', $branch)->get();
|
||||||
|
if ($applications->isEmpty()) {
|
||||||
|
$return_payloads->push([
|
||||||
|
'status' => 'failed',
|
||||||
|
'message' => "Nothing to do. No applications found with deploy key set, branch is '$branch' and Git Repository name has $name.",
|
||||||
|
]);
|
||||||
|
return response($return_payloads);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foreach ($applications as $application) {
|
||||||
|
$webhook_secret = data_get($application, 'manual_webhook_secret_bitbucket');
|
||||||
|
$payload = request()->getContent();
|
||||||
|
|
||||||
|
fwrite(STDOUT, $payload);
|
||||||
|
|
||||||
|
list($algo, $hash) = explode('=', $x_bitbucket_token, 2);
|
||||||
|
|
||||||
|
$payloadHash = hash_hmac($algo, $payload, $webhook_secret);
|
||||||
|
|
||||||
|
if (!hash_equals($hash, $payloadHash)) {
|
||||||
|
$return_payloads->push([
|
||||||
|
'application' => $application->name,
|
||||||
|
'status' => 'failed',
|
||||||
|
'message' => 'Invalid token.',
|
||||||
|
]);
|
||||||
|
ray('Invalid signature');
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$isFunctional = $application->destination->server->isFunctional();
|
||||||
|
if (!$isFunctional) {
|
||||||
|
$return_payloads->push([
|
||||||
|
'application' => $application->name,
|
||||||
|
'status' => 'failed',
|
||||||
|
'message' => 'Server is not functional',
|
||||||
|
]);
|
||||||
|
ray('Server is not functional: ' . $application->destination->server->name);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ($x_bitbucket_event === 'repo:push') {
|
||||||
|
if ($application->isDeployable()) {
|
||||||
|
ray('Deploying ' . $application->name . ' with branch ' . $branch);
|
||||||
|
$deployment_uuid = new Cuid2(7);
|
||||||
|
queue_application_deployment(
|
||||||
|
application_id: $application->id,
|
||||||
|
deployment_uuid: $deployment_uuid,
|
||||||
|
force_rebuild: false,
|
||||||
|
is_webhook: true
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
$return_payloads->push([
|
||||||
|
'application' => $application->name,
|
||||||
|
'status' => 'failed',
|
||||||
|
'message' => 'Deployments disabled',
|
||||||
|
]);
|
||||||
|
ray('Deployments disabled for ' . $application->name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return response($return_payloads);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
ray($e->getMessage());
|
||||||
|
return handleError($e);
|
||||||
|
}
|
||||||
|
});
|
||||||
Route::post('/source/github/events/manual', function () {
|
Route::post('/source/github/events/manual', function () {
|
||||||
try {
|
try {
|
||||||
$x_github_event = Str::lower(request()->header('X-GitHub-Event'));
|
$x_github_event = Str::lower(request()->header('X-GitHub-Event'));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user