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 @@ ...@@ -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```. 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). 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 (executable
(name server) (name server)
(modules content server template) (modules content server template)
(libraries dream ocb omd)) (libraries dream ezcurl ocb omd))
(rule (rule
(targets template.ml) (targets template.ml)
......
...@@ -11,6 +11,41 @@ let page path = ...@@ -11,6 +11,41 @@ let page path =
| None -> None | None -> None
| Some page -> Some (Omd.of_string page |> Omd.to_html) | 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 () = let () =
Dream.run ~interface:"0.0.0.0" Dream.run ~interface:"0.0.0.0"
@@ Dream.logger @@ Dream.logger
...@@ -23,46 +58,52 @@ let () = ...@@ -23,46 +58,52 @@ let () =
Dream.html Dream.html
(Template.render_unsafe ~title:"Osh by OCamlPro" ~content) ) (Template.render_unsafe ~title:"Osh by OCamlPro" ~content) )
; Dream.get "/badge" (fun request -> ; Dream.get "/badge" (fun request ->
Dream.respond let open Ocb in
~headers:[ ("Content-Type", "image/svg+xml") ] mk_badge ~label:"Label" ~color:Color.Blue ~style:Style.Flat
(let open Ocb in ~label_color:Color.Black ~status:"Status" ~scale:1. request )
let label = ; Dream.get "/badge/github/workflow/status/:user/:repo/:workflow"
match Dream.query "label" request with (fun request ->
| None -> "Label" let url =
| Some label -> label Format.sprintf
in "https://api.github.com/repos/%s/%s/actions/workflows/%s/runs"
let color = (Dream.param "user" request)
match Dream.query "color" request with (Dream.param "repo" request)
| None -> Color.Blue (Dream.param "workflow" request)
| Some color -> Color.of_string color in
in match Ezcurl.get ~url () with
let style = | Error (_code, msg) ->
match Dream.query "style" request with Dream.respond
| None -> Style.Flat (Format.sprintf "Failed to query the API: curl error: %s" msg)
| Some style -> Style.of_string style | Ok response -> (
in let open Yojson.Basic in
let label_color = let response = from_string response.body in
match Dream.query "label_color" request with let response =
| None -> Color.Black response |> Util.member "workflow_runs" |> Util.to_list
| Some label_color -> Color.of_string label_color
in
let status =
match Dream.query "status" request with
| None -> "Status"
| Some status -> status
in in
let scale = let latest_run =
match Dream.query "scale" request with List.find_opt
| None -> 1. (fun x ->
| Some scale -> begin let event = x |> Util.member "event" |> Util.to_string in
match float_of_string_opt scale with let status = x |> Util.member "status" |> Util.to_string in
| None -> 1. status = "completed" && event = "push" )
| Some scale -> scale response
end
in in
Format.asprintf "%a" match latest_run with
(Gen.mk ~label ~color ~style ~label_color ~status ~icon:None | None -> Dream.respond "Invalid JSON answer"
~icon_width:0. ~scale ) | 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 @@ 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