ci.scm 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. ;;; GNU Guix --- Functional package management for GNU
  2. ;;; Copyright © 2018, 2019, 2020 Ludovic Courtès <ludo@gnu.org>
  3. ;;; Copyright © 2020 Mathieu Othacehe <othacehe@gnu.org>
  4. ;;;
  5. ;;; This file is part of GNU Guix.
  6. ;;;
  7. ;;; GNU Guix is free software; you can redistribute it and/or modify it
  8. ;;; under the terms of the GNU General Public License as published by
  9. ;;; the Free Software Foundation; either version 3 of the License, or (at
  10. ;;; your option) any later version.
  11. ;;;
  12. ;;; GNU Guix is distributed in the hope that it will be useful, but
  13. ;;; WITHOUT ANY WARRANTY; without even the implied warranty of
  14. ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. ;;; GNU General Public License for more details.
  16. ;;;
  17. ;;; You should have received a copy of the GNU General Public License
  18. ;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
  19. (define-module (guix ci)
  20. #:use-module (guix http-client)
  21. #:use-module (json)
  22. #:use-module (srfi srfi-1)
  23. #:use-module (ice-9 match)
  24. #:export (build-product?
  25. build-product-id
  26. build-product-type
  27. build-product-file-size
  28. build-product-path
  29. build?
  30. build-id
  31. build-derivation
  32. build-system
  33. build-status
  34. build-timestamp
  35. build-products
  36. checkout?
  37. checkout-commit
  38. checkout-input
  39. evaluation?
  40. evaluation-id
  41. evaluation-spec
  42. evaluation-complete?
  43. evaluation-checkouts
  44. %query-limit
  45. queued-builds
  46. latest-builds
  47. latest-evaluations
  48. evaluations-for-commit))
  49. ;;; Commentary:
  50. ;;;
  51. ;;; This module provides a client to the HTTP interface of the Hydra and
  52. ;;; Cuirass continuous integration (CI) tools.
  53. ;;;
  54. ;;; Code:
  55. (define-json-mapping <build-product> make-build-product
  56. build-product?
  57. json->build-product
  58. (id build-product-id) ;integer
  59. (type build-product-type) ;string
  60. (file-size build-product-file-size) ;integer
  61. (path build-product-path)) ;string
  62. (define-json-mapping <build> make-build build?
  63. json->build
  64. (id build-id "id") ;integer
  65. (derivation build-derivation) ;string | #f
  66. (system build-system) ;string
  67. (status build-status "buildstatus" ) ;integer
  68. (timestamp build-timestamp) ;integer
  69. (products build-products "buildproducts" ;<build-product>*
  70. (lambda (products)
  71. (map json->build-product
  72. ;; Before Cuirass 3db603c1, #f is always returned.
  73. (if (vector? products)
  74. (vector->list products)
  75. '())))))
  76. (define-json-mapping <checkout> make-checkout checkout?
  77. json->checkout
  78. (commit checkout-commit) ;string (SHA1)
  79. (input checkout-input)) ;string (name)
  80. (define-json-mapping <evaluation> make-evaluation evaluation?
  81. json->evaluation
  82. (id evaluation-id) ;integer
  83. (spec evaluation-spec "specification") ;string
  84. (complete? evaluation-complete? "in-progress"
  85. (match-lambda
  86. (0 #t)
  87. (_ #f))) ;Boolean
  88. (checkouts evaluation-checkouts "checkouts" ;<checkout>*
  89. (lambda (checkouts)
  90. (map json->checkout
  91. (vector->list checkouts)))))
  92. (define %query-limit
  93. ;; Max number of builds requested in queries.
  94. 1000)
  95. (define (json-fetch url)
  96. (let* ((port (http-fetch url))
  97. (json (json->scm port)))
  98. (close-port port)
  99. json))
  100. (define* (queued-builds url #:optional (limit %query-limit))
  101. "Return the list of queued derivations on URL."
  102. (let ((queue (json-fetch (string-append url "/api/queue?nr="
  103. (number->string limit)))))
  104. (map json->build (vector->list queue))))
  105. (define* (latest-builds url #:optional (limit %query-limit)
  106. #:key evaluation system job status)
  107. "Return the latest builds performed by the CI server at URL. If EVALUATION
  108. is an integer, restrict to builds of EVALUATION. If SYSTEM is true (a system
  109. string such as \"x86_64-linux\"), restrict to builds for SYSTEM."
  110. (define* (option name value #:optional (->string identity))
  111. (if value
  112. (string-append "&" name "=" (->string value))
  113. ""))
  114. (let ((latest (json-fetch (string-append url "/api/latestbuilds?nr="
  115. (number->string limit)
  116. (option "evaluation" evaluation
  117. number->string)
  118. (option "system" system)
  119. (option "job" job)
  120. (option "status" status
  121. number->string)))))
  122. ;; Note: Hydra does not provide a "derivation" field for entries in
  123. ;; 'latestbuilds', but Cuirass does.
  124. (map json->build (vector->list latest))))
  125. (define* (latest-evaluations url #:optional (limit %query-limit))
  126. "Return the latest evaluations performed by the CI server at URL."
  127. (map json->evaluation
  128. (vector->list
  129. (json->scm
  130. (http-fetch (string-append url "/api/evaluations?nr="
  131. (number->string limit)))))))
  132. (define* (evaluations-for-commit url commit #:optional (limit %query-limit))
  133. "Return the evaluations among the latest LIMIT evaluations that have COMMIT
  134. as one of their inputs."
  135. (filter (lambda (evaluation)
  136. (find (lambda (checkout)
  137. (string=? (checkout-commit checkout) commit))
  138. (evaluation-checkouts evaluation)))
  139. (latest-evaluations url limit)))