branch: main
commit 9b9a418e464017562bf152cc8aa631c0d6c4dd28
Author: Romain GARBAGE <[email protected]>
AuthorDate: Fri Apr 4 18:34:39 2025 +0200
forgejo: Add support for notification to Forgejo through reviews.
* src/cuirass/forges/forgejo.scm (forgejo-notification-create-review): New
variable.
(forgejo-handle-notification): Add support for notification to Forgejo
through reviews.
Signed-off-by: Ludovic Courtès <[email protected]>
---
src/cuirass/forges/forgejo.scm | 103 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 103 insertions(+)
diff --git a/src/cuirass/forges/forgejo.scm b/src/cuirass/forges/forgejo.scm
index f5e3cdc..9463f83 100644
--- a/src/cuirass/forges/forgejo.scm
+++ b/src/cuirass/forges/forgejo.scm
@@ -456,6 +456,102 @@ BUILD-RESULTS is a list of build records."
(when message
(update-forgejo-pull-request-from-spec spec message))))
+(define* (forgejo-notification-create-review spec
+ #:key
+ (jobset-created #f)
+ (evaluation-started #f)
+ (evaluation-succeeded #f)
+ (evaluation-failed #f)
+ (build-results #f))
+ "Notify a Forgejo instance of a status change by creating a new review
message.
+SPEC is a specification record, JOBSET-CREATED is a boolean,
+EVALUATION-STARTED, EVALUATION-SUCCEEDED and EVALUATION-FAILED are numbers and
+BUILD-RESULTS is a list of build records."
+ (log-info "preparing Forgejo notification for spec '~a'"
+ (specification-name spec))
+
+ (define (succeeded-builds build-results)
+ (filter-map (lambda (build)
+ (and (= (build-status succeeded)
+ (build-current-status build))
+ (build-nix-name build)))
+ build-results))
+ (define (failed-builds build-results)
+ (filter-map (lambda (build)
+ (and (build-failure?
+ (build-current-status build))
+ (build-nix-name build)))
+ build-results))
+
+ (let* ((name (specification-name spec))
+ (cuirass-url (%cuirass-url))
+ (message (cond
+ (jobset-created
+ (log-debug "forgejo-notification-create-review: ignoring
jobset-created event")
+ #f)
+ (evaluation-started
+ (log-debug "forgejo-notification-create-review: ignoring
evaluation-started event")
+ #f)
+ (evaluation-succeeded
+ (log-debug "forgejo-notification-create-review: ignoring
evaluation-succeeded event")
+ #f)
+ (evaluation-failed
+ (format #f
+ "> Evaluation [~a](~a/eval/~a) of Cuirass jobset
[~a](~a/jobset/~a) failed."
+ evaluation-failed cuirass-url evaluation-failed
+ name cuirass-url name))
+ (build-results
+ (let* ((evaluation-id (apply max
+ (filter-map
build-evaluation-id
+ build-results)))
+ (header
+ (format #f "> Results for evaluation
[~a](~a/eval/~a) of Cuirass jobset [~a](~a/jobset/~a):~%"
+ evaluation-id cuirass-url evaluation-id
+ name cuirass-url name))
+ (succeeded-builds (succeeded-builds build-results))
+ (successes (if (null? succeeded-builds)
+ ""
+ (format #f "> Successfully build ~a
package(s): ~a~%"
+ (length succeeded-builds)
+ (string-join
succeeded-builds ", "))))
+ (failed-builds (failed-builds build-results))
+ (failures (if (null? failed-builds)
+ ""
+ (format #f "> Failed build ~a
package(s): ~a~%"
+ (length failed-builds)
+ (string-join failed-builds ",
")))))
+ (string-append header successes failures)))
+ (#t #f)))
+ (review-state (if (or evaluation-failed
+ (and=> build-results
+ (compose not null? failed-builds)))
+ 'REQUEST_CHANGES
+ 'APPROVED)))
+ ;; XXX: Raise an error when no message has been generated?
+ (when message
+ (log-debug "prepared Forgejo notification for spec '~a': ~a (review
state ~a)"
+ (specification-name spec) message review-state)
+ (let* ((properties (specification-properties spec))
+ (url (string->uri
+ (assoc-ref properties
+ 'pull-request-url)))
+ (server (uri-host url))
+ (token (forge-get-token server
+ (assoc-ref properties
+
'pull-request-target-namespace)))
+ (owner (assoc-ref properties
+ 'pull-request-target-repository-owner))
+ (repository (assoc-ref properties
+ 'pull-request-target-repository-name))
+ (pull-request-index (assoc-ref properties
+ 'pull-request-number)))
+ (forgejo-api-pull-request-create-review server token
+ #:owner owner
+ #:repository repository
+ #:pull-request-index
pull-request-index
+ #:review-message message
+ #:review-state
review-state)))))
+
(define* (forgejo-handle-notification spec
#:key
(jobset-created #f)
@@ -474,6 +570,13 @@ EVALUATION-FAILED are numbers and BUILD-RESULTS is a list
of build records."
#:evaluation-succeeded
evaluation-succeeded
#:evaluation-failed
evaluation-failed
#:build-results build-results))
+ ('create-review
+ (forgejo-notification-create-review spec
+ #:jobset-created jobset-created
+ #:evaluation-started
evaluation-started
+ #:evaluation-succeeded
evaluation-succeeded
+ #:evaluation-failed evaluation-failed
+ #:build-results build-results))
(type
(log-error "forgejo-handle-notification: unsupported notification type ~a"
type))))