From 702e41c8240fe7ca92472f15cf5738adac0ac1e2 Mon Sep 17 00:00:00 2001 From: Robert Prehn <3952444+prehnRA@users.noreply.github.com> Date: Thu, 22 Jul 2021 15:39:17 -0500 Subject: [PATCH] feat: Report coverage to gitlab --- .gitignore | 3 + .gitlab-ci.yml | 12 +++- mix.exs | 9 ++- script/cibuild | 2 +- script/coverage-json-to-cobertura | 105 ++++++++++++++++++++++++++++++ script/coverage-json-to-metrics | 30 +++++++++ 6 files changed, 157 insertions(+), 4 deletions(-) create mode 100755 script/coverage-json-to-cobertura create mode 100755 script/coverage-json-to-metrics diff --git a/.gitignore b/.gitignore index 2ffb1c25..170db901 100644 --- a/.gitignore +++ b/.gitignore @@ -44,3 +44,6 @@ config/*.secret.exs # Temporary CI build file build.env + +# CI metrics file +metrics.txt diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index e3ba6690..fe7cfbc9 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -26,7 +26,7 @@ variables: - name: postgres:12 script: script/cibuild -test: +test_1.10.4: <<: *test_template image: "elixir:1.10.4-alpine" @@ -34,9 +34,17 @@ test_1.11.4: <<: *test_template image: "elixir:1.11.4-alpine" -test_1.12.1: +test: <<: *test_template image: "elixir:1.12.1-alpine" + script: + - script/cibuild + - script/coverage-json-to-metrics + - script/coverage-json-to-cobertura + artifacts: + reports: + metrics: metrics.txt + cobertura: cover/cobertura.xml credo: stage: test diff --git a/mix.exs b/mix.exs index 3ee66836..dcc7b0cf 100644 --- a/mix.exs +++ b/mix.exs @@ -13,7 +13,14 @@ defmodule Legendary.Mixfile do deps: deps(), test_coverage: [tool: ExCoveralls], aliases: aliases(), - preferred_cli_env: [coveralls: :test, "coveralls.detail": :test, "coveralls.post": :test, "coveralls.html": :test, "coveralls.json": :test], + preferred_cli_env: [ + coveralls: :test, + "coveralls.detail": :test, + "coveralls.post": :test, + "coveralls.html": :test, + "coveralls.json": :test, + "coveralls.xml": :test + ], ] end diff --git a/script/cibuild b/script/cibuild index a44bc161..89d8c9c1 100755 --- a/script/cibuild +++ b/script/cibuild @@ -12,6 +12,6 @@ mix deps.get mix ecto.create mix ecto.migrate -mix test +mix coveralls.json script/restore-timestamps diff --git a/script/coverage-json-to-cobertura b/script/coverage-json-to-cobertura new file mode 100755 index 00000000..2315f920 --- /dev/null +++ b/script/coverage-json-to-cobertura @@ -0,0 +1,105 @@ +#!/usr/bin/env elixir + +Mix.install([ + {:jason, "~> 1.0"}, + {:xml_builder, "~> 2.1"} +]) + +%{"source_files" => data} = + "cover/excoveralls.json" + |> File.read!() + |> Jason.decode!() + +{total_covered, total_total} = + data + |> Enum.reduce({0,0}, fn %{"coverage" => cover}, {covered, total} -> + file_covered = + cover + |> Enum.reduce(0, &(if is_integer(&1) && &1 > 0, do: &2 + 1, else: &2)) + + file_total = + cover + |> Enum.reduce(0, &(if is_nil(&1), do: &2, else: &2 + 1)) + + {covered + file_covered, total + file_total} + end) + +ratio = total_covered / total_total + +files = + data + |> Enum.map(fn %{"coverage" => cover, "name" => name} -> + file_covered = + cover + |> Enum.reduce(0, &(if is_integer(&1) && &1 > 0, do: &2 + 1, else: &2)) + + file_total = + cover + |> Enum.reduce(0, &(if is_nil(&1), do: &2, else: &2 + 1)) + + lines = + cover + |> Enum.with_index + |> Enum.map(fn + {nil, _index} -> + nil + {line, index} -> + {:line, %{"number" => index, "hits" => line}, []} + end) + |> Enum.reject(&is_nil/1) + + ratio = + if file_total == 0 do + 1.0 + else + file_covered / file_total + end + + { + :class, + %{"filename" => name, "line-rate" => ratio}, + [ + { + :lines, + %{}, + lines + } + ] + } + end) + +buffer = + XmlBuilder.document([ + XmlBuilder.doctype( + "coverage", + system: ["http://cobertura.sourceforge.net/xml/coverage-03.dtd"] + ), + { + :coverage, + %{ + "line-rate" => ratio, + }, + [ + { + :packages, + %{}, + [ + { + :package, + %{"name" => "", "line-rate" => ratio}, + [ + { + :classes, + %{}, + files + } + ] + } + ] + } + ] + } + ]) + |> XmlBuilder.generate + +File.write!("cover/cobertura.xml", buffer) diff --git a/script/coverage-json-to-metrics b/script/coverage-json-to-metrics new file mode 100755 index 00000000..9216b5d9 --- /dev/null +++ b/script/coverage-json-to-metrics @@ -0,0 +1,30 @@ +#!/usr/bin/env elixir + +Mix.install([ + {:jason, "~> 1.0"} +]) + +%{"source_files" => data} = + "cover/excoveralls.json" + |> File.read!() + |> Jason.decode!() + +{total_covered, total_total} = + data + |> Enum.reduce({0,0}, fn %{"coverage" => cover}, {covered, total} -> + file_covered = + cover + |> Enum.reduce(0, &(if is_integer(&1) && &1 > 0, do: &2 + 1, else: &2)) + + file_total = + cover + |> Enum.reduce(0, &(if is_nil(&1), do: &2, else: &2 + 1)) + + {covered + file_covered, total + file_total} + end) + +ratio = + (total_covered / total_total) + |> Float.round(3) + +File.write!("metrics.txt", "coverage #{ratio}")