guix-data-service/guix-data-service/web/forgejo/controller.scm
Ludovic Courtès b35c26a74e forgejo: Always return a response and its body.
Fixes the bug reported in
<https://codeberg.org/guix/maintenance/pulls/18#issuecomment-5851510>.

Previously ‘forgejo-controller’ would return a single value in
successful cases, whichever ‘enqueue-job-for-pull-request’ or
‘mark-pull-request-branch-for-deletion’ would return.
2025-07-16 19:11:33 +02:00

90 lines
3.9 KiB
Scheme
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

;;; Guix Data Service -- Information about Guix over time
;;; Copyright © 2024, 2025 Romain Garbage <romain.garbage@inria.fr>
;;; Copyright © 2025 Ludovic Courtès <ludo@gnu.org>
;;;
;;; This program is free software: you can redistribute it and/or
;;; modify it under the terms of the GNU Affero General Public License
;;; as published by the Free Software Foundation, either version 3 of
;;; the License, or (at your option) any later version.
;;;
;;; This program is distributed in the hope that it will be useful,
;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
;;; Affero General Public License for more details.
;;;
;;; You should have received a copy of the GNU Affero General Public
;;; License along with this program. If not, see
;;; <http://www.gnu.org/licenses/>.
(define-module (guix-data-service web forgejo controller)
#:use-module (web http)
#:use-module (web request)
#:use-module (ice-9 match)
#:use-module ((rnrs bytevectors) #:select (utf8->string))
#:use-module (knots resource-pool)
#:use-module (guix-data-service forgejo)
#:use-module (guix-data-service web controller)
#:use-module (guix-data-service web render)
#:export (forgejo-controller))
;;; Commentary:
;;;
;;; This module implements a subset of the Forgejo Webhook API described at
;;; <https://forgejo.org/docs/latest/user/webhooks/> and a subset of the REST
;;; API described at <https://codeberg.org/api/swagger>.
;;;
;;; Code:
;; This declares a specific header for internal consumption, specifically when
;; generating requests during tests.
(declare-opaque-header! "X-Forgejo-Event")
;;;
;;; Webhook.
;;;
(define (forgejo-controller request
method-and-path-components
mime-types
body)
(match method-and-path-components
(('POST "forgejo" "event")
(let* ((params (utf8->string body))
(event-type (assoc-ref (request-headers request) 'x-forgejo-event))
(content-type (assoc-ref (request-headers request) 'content-type))
(json? (equal? (car content-type)
'application/json)))
(if json?
(match event-type
("pull_request"
(let* ((event (json->forgejo-pull-request-event params))
(pull-request (forgejo-pull-request-event-pull-request event))
(action (forgejo-pull-request-event-action event)))
(format #t "received pull request ~a ~s (action: ~a)~%"
(forgejo-pull-request-number pull-request)
(forgejo-pull-request-url pull-request)
action)
(call-with-resource-from-pool (connection-pool)
(lambda (conn)
(match action
((or 'opened 'reopened) ;new pull request
(enqueue-job-for-pull-request conn pull-request)
(render-json '() #:code 200))
('synchronized ;pull request is updated
(enqueue-job-for-pull-request conn pull-request)
(render-json '() #:code 200))
('closed ;closed or merged
(mark-pull-request-branch-for-deletion conn pull-request)
(render-json '() #:code 200))
(_ ;other action
(render-json '((error . "unknown action"))
#:code 404)))))))
(_
(render-json '((error . "unknown event type"))
#:code 404)))
(render-html #:code 400
#:sxml "This HTTP endpoint requires JSON."))))
(_
(render-html #:code 404))))