iwink / gitlab-webhook-bundle

一个用于处理GitLab webhooks的Symfony扩展包。

安装: 343

依赖者: 0

建议者: 0

安全: 0

星星: 6

关注者: 5

分支: 3

开放问题: 1

类型:symfony-bundle

v1.2.2 2023-07-26 12:45 UTC

This package is auto-updated.

Last update: 2024-09-26 15:21:00 UTC


README

License Tag Build Status

一个用于处理GitLab webhooks的Symfony扩展包。

安装

要使用此扩展包,请使用Composer进行安装:composer require iwink/gitlab-webhook-bundle。如果您的项目使用Symfony Flex,则已完成。如果没有,请确保在项目的config/bundles.php中启用扩展包。

用法

要将控制器标记为GitLab webhook,您可以在控制器上方使用@Webhook(event="event")注释,并在方法中定义一个Iwink\GitLabWebhookBundle\Event\WebhookEvent参数

<?php

namespace App\Controller;

use Iwink\GitLabWebhookBundle\Annotation\Webhook;
use Iwink\GitLabWebhookBundle\Event\PipelineEvent;
use Iwink\GitLabWebhookBundle\Scheduler;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\Routing\Annotation\Route;

/**
 * @Route("/webhook", name="webhook_")
 */
class WebhookController {
    /**
     * @Route("/pipeline", name="pipeline")
     * @Webhook("pipeline")
     */
    public function pipeline(PipelineEvent $event, Scheduler $scheduler): JsonResponse {
        $status = $event->getObjectAttributes()['status'];
        if ('success' === $status) {
            $scheduler->schedule([$this, 'expensiveOperation'], ['one', true]);
        }

        return new JsonResponse();
    }

    public function expensiveOperation(string $name, bool $valid): void {
        // Does something expensive
    }
}

上面的示例使用@Webhook("pipeline")注释将pipeline方法标记为webhook,该webhook接收一个Pipeline Hook事件。事件通过方法参数的$event注入,注入基于参数的类型提示(PipelineEvent),参数名称不重要。因为GitLab期望尽快得到响应,所以webhook的昂贵部分在发送响应后由Iwink\GitLabWebhookBundle\Scheduler::schedule()方法调度和执行。

安全的webhooks

GitLab可以选择使用secret token来保护webhook。您可以在webhook注释中定义这些secret tokens

<?php

namespace App\Controller;

use Iwink\GitLabWebhookBundle\Annotation\Webhook;
use Iwink\GitLabWebhookBundle\Event\PipelineEvent;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\Routing\Annotation\Route;

/**
 * @Route("/webhook", name="webhook_")
 */
class WebhookController {
    /**
     * @Route("/pipeline", name="pipeline")
     * @Webhook("pipeline", tokens={"secret_token"})
     */
    public function pipeline(PipelineEvent $event): JsonResponse {
        // Handle request
    }
}

现在接收到的Pipeline Hook请求应包含secret token(由X-GitLab-Token头提供),否则请求失败。由于可能为同一注释定义多个tokens(因为多个GitLab项目可能触发相同的webhook),因此tokens应定义为数组。tokens也可以使用%parameter.name%格式作为配置参数定义:@Webhook("pipeline", tokens={"%gitlab.secret_token%"})。由于参数可以包含环境变量,因此配置秘密非常灵活。

注意事项

由于Symfony缓存注释,并且定义注释的文件在更新参数时没有改变,因此在更改秘密参数值后,您应该手动清除缓存。这只会发生在dev环境中,因为在prod环境中容器始终被缓存(每次您的代码更改,您都需要清除缓存)。

多个webhooks

可以使用多个@Webhook注释将多个webhooks注册到单个控制器中

<?php

namespace App\Controller;

use Iwink\GitLabWebhookBundle\Annotation\Webhook;
use Iwink\GitLabWebhookBundle\Event\MergeRequestEvent;
use Iwink\GitLabWebhookBundle\Event\PushEvent;
use Iwink\GitLabWebhookBundle\Event\WebhookEvent;
use Iwink\GitLabWebhookBundle\Scheduler;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\Routing\Annotation\Route;

/**
 * @Route("/webhook", name="webhook_")
 */
class WebhookController {
    /**
     * @Route("/pipeline", name="pipeline")
     * @Webhook("push")
     * @Webhook(event="merge request")
     */
    public function pipeline(WebhookEvent $event, Scheduler $scheduler): JsonResponse {
        if (
            ($event instanceof PushEvent && 'some/project' === $event->getProject()['name'])
            || ($event instanceof MergeRequestEvent && 'success' === $event->getObjectAttributes()['status'])
        ) {
            $scheduler->schedule([$this, 'expensiveOperation']);
        }

        return new JsonResponse();
    }

    public function expensiveOperation(): void {
        // Does something expensive
    }
}

注入的$event现在是Iwink\GitLabWebhookBundle\Event\PushEventIwink\GitLabWebhookBundle\Event\MergeRequestEvent。注意两个@Webhook注释之间的区别,短(@Webhook("push"))和长(@Webhook(event="merge request"))语法给出相同的结果,所以使用哪种语法都无关紧要。

支持的webhooks

以下webhooks被支持