Unverified Commit 7e08ad43 authored by zapashcanon's avatar zapashcanon
Browse files

add github action support

parent 1b0e3b55
Pipeline #15703 failed with stages
in 4 minutes and 10 seconds
......@@ -8,3 +8,9 @@
You can generate a badge with an URL of the form: ```/badge?label=build&color=green&style=classic&label_color=black&status=passing&scale=2.0```.
Preview: [![the result](/badge?label=build&color=green&style=classic&label_color=black&status=passing&scale=2.0)](/badge?label=build&color=green&style=classic&label_color=black&status=passing&scale=2.0).
We also support fetching GitHub actions status with an URL of the form: ```/badge/github/workflow/status/OCamlPro/swhid/build.yml```, note that you have to provide the **full filename** (or the identifier) of your workflow because the GitHub API is not that great...
Preview: [![the result](/badge/github/workflow/status/OCamlPro/swhid/build.yml)](/badge/github/workflow/status/OCamlPro/swhid/build.yml).
Even when using this, you can override any parameter, here's the same URL but with a `?color=blue` added: [![the result](/badge/github/workflow/status/OCamlPro/swhid/build.yml?color=blue)](/badge/github/workflow/status/OCamlPro/swhid/build.yml?color=blue).
(executable
(name server)
(modules content server template)
(libraries dream ocb omd))
(libraries dream ezcurl ocb omd))
(rule
(targets template.ml)
......
......@@ -11,6 +11,41 @@ let page path =
| None -> None
| Some page -> Some (Omd.of_string page |> Omd.to_html)
(** This takes a lot of parameter but overrides any of them if provided in
request. *)
let mk_badge ~label ~color ~style ~label_color ~status ~scale request =
let q field = Dream.query field request in
Dream.respond
~headers:[ ("Content-Type", "image/svg+xml") ]
(let open Ocb in
let module Option = Stdlib.Option in
let label = Option.value (q "label") ~default:label in
let color =
Option.value (Option.map Color.of_string (q "color")) ~default:color
in
let style =
Option.value (Option.map Style.of_string (q "style")) ~default:style
in
let label_color =
match Dream.query "label_color" request with
| None -> label_color
| Some label_color -> Color.of_string label_color
in
let status = Option.value (q "status") ~default:status in
let scale =
match Dream.query "scale" request with
| None -> scale
| Some scale' -> begin
match float_of_string_opt scale' with
| None -> scale
| Some scale -> scale
end
in
Format.asprintf "%a"
(Gen.mk ~label ~color ~style ~label_color ~status ~icon:None
~icon_width:0. ~scale )
())
let () =
Dream.run ~interface:"0.0.0.0"
@@ Dream.logger
......@@ -23,46 +58,52 @@ let () =
Dream.html
(Template.render_unsafe ~title:"Osh by OCamlPro" ~content) )
; Dream.get "/badge" (fun request ->
Dream.respond
~headers:[ ("Content-Type", "image/svg+xml") ]
(let open Ocb in
let label =
match Dream.query "label" request with
| None -> "Label"
| Some label -> label
in
let color =
match Dream.query "color" request with
| None -> Color.Blue
| Some color -> Color.of_string color
in
let style =
match Dream.query "style" request with
| None -> Style.Flat
| Some style -> Style.of_string style
in
let label_color =
match Dream.query "label_color" request with
| None -> Color.Black
| Some label_color -> Color.of_string label_color
in
let status =
match Dream.query "status" request with
| None -> "Status"
| Some status -> status
let open Ocb in
mk_badge ~label:"Label" ~color:Color.Blue ~style:Style.Flat
~label_color:Color.Black ~status:"Status" ~scale:1. request )
; Dream.get "/badge/github/workflow/status/:user/:repo/:workflow"
(fun request ->
let url =
Format.sprintf
"https://api.github.com/repos/%s/%s/actions/workflows/%s/runs"
(Dream.param "user" request)
(Dream.param "repo" request)
(Dream.param "workflow" request)
in
match Ezcurl.get ~url () with
| Error (_code, msg) ->
Dream.respond
(Format.sprintf "Failed to query the API: curl error: %s" msg)
| Ok response -> (
let open Yojson.Basic in
let response = from_string response.body in
let response =
response |> Util.member "workflow_runs" |> Util.to_list
in
let scale =
match Dream.query "scale" request with
| None -> 1.
| Some scale -> begin
match float_of_string_opt scale with
| None -> 1.
| Some scale -> scale
end
let latest_run =
List.find_opt
(fun x ->
let event = x |> Util.member "event" |> Util.to_string in
let status = x |> Util.member "status" |> Util.to_string in
status = "completed" && event = "push" )
response
in
Format.asprintf "%a"
(Gen.mk ~label ~color ~style ~label_color ~status ~icon:None
~icon_width:0. ~scale )
()) )
match latest_run with
| None -> Dream.respond "Invalid JSON answer"
| Some x ->
let s = x |> Util.member "conclusion" |> Util.to_string in
let open Ocb in
let status, color =
match s with
| "success" -> ("Success", Color.Green)
| "failure" -> ("Failure", Color.Red)
| "neutral" -> ("Neutral", Color.Grey)
| "cancelled" -> ("Cancelled", Color.Red)
| "skipped" -> ("Cancelled", Color.Red)
| "timed_out" -> ("Timed out", Color.Red)
| unknown -> (unknown, Color.Grey)
in
mk_badge ~label:"Build" ~color ~style:Style.Flat
~label_color:Color.Black ~status ~scale:1. request ) )
]
@@ Dream.not_found
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment