From 1ffc033390bea88bebdaa4285118c8968e6e68b9 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Cugnet Date: Sun, 26 Oct 2025 09:51:14 +0100 Subject: [PATCH 1/7] build(mix): configure the Mix env for `mix coveralls.lcov` Refs: #49 --- mix.exs | 1 + 1 file changed, 1 insertion(+) diff --git a/mix.exs b/mix.exs index 939994e..91042a5 100644 --- a/mix.exs +++ b/mix.exs @@ -101,6 +101,7 @@ defmodule TypedStruct.MixProject do coveralls: :test, "coveralls.detail": :test, "coveralls.html": :test, + "coveralls.lcov": :test, # Use a custom env for docs. docs: :docs From 7d32f7c7975f85bbf248d48c8e3593c8f8532fd2 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Cugnet Date: Sun, 26 Oct 2025 21:27:58 +0100 Subject: [PATCH 2/7] env: replace `mix-test.watch` by `mix_test_interactive` We need to install it via Nix to avoid a circular dependency on typed_struct. Refs: #49 --- config/config.exs | 16 ---------------- flake.nix | 17 +++++++++++++++++ mix.exs | 4 ---- mix.lock | 1 - 4 files changed, 17 insertions(+), 21 deletions(-) delete mode 100644 config/config.exs diff --git a/config/config.exs b/config/config.exs deleted file mode 100644 index 6761695..0000000 --- a/config/config.exs +++ /dev/null @@ -1,16 +0,0 @@ -import Config - -# This configuration is loaded before any dependency and is restricted to this -# project. If another project depends on this project, this file won’t be loaded -# nor affect the parent project. For this reason, if you want to provide default -# values for your application for 3rd-party users, it should be done in your -# "mix.exs" file. - -if Mix.env() == :test do - # Clear the console before each test run - config :mix_test_watch, clear: true -end - -# # Import environment specific config. This must remain at the bottom of this -# # file so it overrides the configuration defined above. -# import_config "#{Mix.env()}.exs" diff --git a/flake.nix b/flake.nix index 2531eda..83ad9ef 100644 --- a/flake.nix +++ b/flake.nix @@ -104,6 +104,23 @@ env = ideEnv; + + commands = [ + # NOTE: Install `mix_test_interactive` via Nix since we cannot + # depend on in via Mix beauce it depends on `typed_struct`. + { + name = "mti_exec"; + command = '' + #!/usr/bin/env elixir + + Mix.install([ + {:mix_test_interactive, "~> 4.1"} + ]) + + MixTestInteractive.run(System.argv()) + ''; + } + ]; }; ci-committed = { diff --git a/mix.exs b/mix.exs index 91042a5..4f0503b 100644 --- a/mix.exs +++ b/mix.exs @@ -52,7 +52,6 @@ defmodule TypedStruct.MixProject do {:credo, "~> 1.0", only: :dev, runtime: false}, {:dialyxir, "~> 1.0", only: :dev, runtime: false}, {:excoveralls, ">= 0.0.0", only: :test, runtime: false}, - {:mix_test_watch, ">= 0.0.0", only: :test, runtime: false}, {:ex_unit_notifier, ">= 0.0.0", only: :test, runtime: false}, # Project dependencies @@ -94,9 +93,6 @@ defmodule TypedStruct.MixProject do defp cli_env do [ - # Run mix test.watch in `:test` env. - "test.watch": :test, - # Always run Coveralls Mix tasks in `:test` env. coveralls: :test, "coveralls.detail": :test, diff --git a/mix.lock b/mix.lock index a62947b..23ca856 100644 --- a/mix.lock +++ b/mix.lock @@ -13,6 +13,5 @@ "makeup": {:hex, :makeup, "1.2.1", "e90ac1c65589ef354378def3ba19d401e739ee7ee06fb47f94c687016e3713d1", [:mix], [{:nimble_parsec, "~> 1.4", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "d36484867b0bae0fea568d10131197a4c2e47056a6fbe84922bf6ba71c8d17ce"}, "makeup_elixir": {:hex, :makeup_elixir, "1.0.1", "e928a4f984e795e41e3abd27bfc09f51db16ab8ba1aebdba2b3a575437efafc2", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.2.3 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "7284900d412a3e5cfd97fdaed4f5ed389b8f2b4cb49efc0eb3bd10e2febf9507"}, "makeup_erlang": {:hex, :makeup_erlang, "1.0.2", "03e1804074b3aa64d5fad7aa64601ed0fb395337b982d9bcf04029d68d51b6a7", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "af33ff7ef368d5893e4a267933e7744e46ce3cf1f61e2dccf53a111ed3aa3727"}, - "mix_test_watch": {:hex, :mix_test_watch, "1.3.0", "2ffc9f72b0d1f4ecf0ce97b044e0e3c607c3b4dc21d6228365e8bc7c2856dc77", [:mix], [{:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}], "hexpm", "f9e5edca976857ffac78632e635750d158df14ee2d6185a15013844af7570ffe"}, "nimble_parsec": {:hex, :nimble_parsec, "1.4.2", "8efba0122db06df95bfaa78f791344a89352ba04baedd3849593bfce4d0dc1c6", [:mix], [], "hexpm", "4b21398942dda052b403bbe1da991ccd03a053668d147d53fb8c4e0efe09c973"}, } From ccf10abf088bdb24d589725b262d707cad3de895 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Cugnet Date: Sun, 26 Oct 2025 22:48:52 +0100 Subject: [PATCH 3/7] env(devshell): add a command for live coverage Refs: #49 --- flake.nix | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/flake.nix b/flake.nix index 83ad9ef..035decb 100644 --- a/flake.nix +++ b/flake.nix @@ -120,6 +120,10 @@ MixTestInteractive.run(System.argv()) ''; } + { + name = "live-coverage"; + command = "mti_exec --clear --task coveralls.lcov"; + } ]; }; From 76298b013b26a7591078b393f5d76a9b08fd21ac Mon Sep 17 00:00:00 2001 From: Jean-Philippe Cugnet Date: Sun, 26 Oct 2025 21:26:59 +0100 Subject: [PATCH 4/7] ide(vscode): suggest and configure Coverage Gutters Refs: #49 --- .vscode/extensions.json | 1 + .vscode/settings.json | 3 +++ 2 files changed, 4 insertions(+) diff --git a/.vscode/extensions.json b/.vscode/extensions.json index 51fd7b5..e8ec896 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -5,6 +5,7 @@ "editorconfig.editorconfig", "esbenp.prettier-vscode", "jnoortheen.nix-ide", + "ryanluker.vscode-coverage-gutters", "tamasfe.even-better-toml", "tekumara.typos-vscode" ] diff --git a/.vscode/settings.json b/.vscode/settings.json index 4a8a7b7..c41bfa1 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,4 +1,7 @@ { + "coverage-gutters.coverageBaseDir": "cover", + "coverage-gutters.coverageReportFileName": "cover/excoveralls.html", + "coverage-gutters.watchOnActivate": true, "editor.formatOnSave": true, "editor.rulers": [80], "evenBetterToml.taplo.bundled": false, From 65da5ef41dc5e953b055191ac1c71c7e572c9402 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Cugnet Date: Mon, 27 Oct 2025 08:53:44 +0100 Subject: [PATCH 5/7] ci(github): add a coverage job uploading to Codecov Refs: #49 --- .github/workflows/ci.yml | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 52ba208..ee0235a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -114,6 +114,36 @@ jobs: - name: Run the checks run: mix check + coverage: + name: Coverage + runs-on: ubuntu-latest + permissions: + id-token: write + env: + MIX_ENV: test + steps: + - name: Clone the repository + uses: actions/checkout@v4 + - name: Install Nix + uses: DeterminateSystems/nix-installer-action@main + - name: Setup the Nix cache + uses: DeterminateSystems/magic-nix-cache-action@main + - name: Setup the environment + run: nix build -L --no-link .#devShells.x86_64-linux.ci-minimal + - name: Fetch the dependencies + run: nix develop .#ci-minimal -c mix deps.get + - name: Build the dependencies + run: nix develop .#ci-minimal -c mix deps.compile + - name: Generate the test coverage report + run: nix develop .#ci-minimal -c mix coveralls.lcov + - name: Upload the test coverage report + uses: codecov/codecov-action@v5 + with: + disable_search: true + files: ./cover/lcov.info + fail_ci_if_error: true + use_oidc: true + docs: name: Documentation runs-on: ubuntu-latest From 917907458d170ed1a62dba5b97786c63c9349c06 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Cugnet Date: Mon, 27 Oct 2025 09:00:19 +0100 Subject: [PATCH 6/7] ci(codecov): configure Codecov Refs: #49 --- codecov.yml | 15 +++++++++++++++ git-z.toml | 1 + 2 files changed, 16 insertions(+) create mode 100644 codecov.yml diff --git a/codecov.yml b/codecov.yml new file mode 100644 index 0000000..96a5e98 --- /dev/null +++ b/codecov.yml @@ -0,0 +1,15 @@ +codecov: + branch: develop + +coverage: + status: + project: + default: + target: auto + threshold: 1% + patch: + default: + target: 100% + +comment: + layout: "diff, files, components" diff --git a/git-z.toml b/git-z.toml index 0c5c3ec..90f7284 100644 --- a/git-z.toml +++ b/git-z.toml @@ -47,6 +47,7 @@ list = [ "version", # Tools + "codecov", "committed", "credo", "dialyzer", From f3dc7ce8c7dc06f7cbc7d392c26dc120cd34ae34 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Cugnet Date: Mon, 27 Oct 2025 09:03:59 +0100 Subject: [PATCH 7/7] docs(readme): add a badge for test coverage Refs: #49 --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index a9d3d5f..bfe77f9 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,7 @@ [![Hex Docs](https://img.shields.io/badge/hex-docs-lightgreen.svg)](https://hexdocs.pm/typed_struct/) [![Total Download](https://img.shields.io/hexpm/dt/typed_struct.svg)](https://hex.pm/packages/typed_struct) [![License](https://img.shields.io/hexpm/l/typed_struct.svg)](https://github.com/ejpcmac/typed_struct/blob/master/LICENSE.md)
+[![codecov](https://codecov.io/gh/ejpcmac/typed_struct/graph/badge.svg?token=riJ8O4G501)](https://codecov.io/gh/ejpcmac/typed_struct) [![Test Status](https://github.com/ejpcmac/typed_struct/actions/workflows/ci.yml/badge.svg) ](https://github.com/ejpcmac/typed_struct/actions/workflows/ci.yml)