Created
July 24, 2026 06:00
-
-
Save ryanzidago/3f4151196b20db7c1f0b4ca0d819d42a to your computer and use it in GitHub Desktop.
Parallel Mix quality checks with readable output and aggregated failures
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| defmodule Mix.Tasks.Qa.Run do | |
| @shortdoc "Run the server quality checks in parallel" | |
| use Mix.Task | |
| @mix_runner_prefix ["--erl", "-elixir ansi_enabled true", "-S", "mix"] | |
| @checks [ | |
| {"format", ["format", "--check-formatted"]}, | |
| {"credo", ["credo", "--strict"]}, | |
| {"sobelow", ["sobelow", "--exit"]}, | |
| {"dependency audit", ["deps.audit"]}, | |
| {"dialyzer", ["dialyzer", "--no-compile"]}, | |
| {"tests", ["test", "--no-compile"]} | |
| ] | |
| @impl Mix.Task | |
| def run([]) do | |
| run_command!("dependencies", ["deps.get"]) | |
| run_command!("compile", ["compile", "--warnings-as-errors"]) | |
| results = | |
| @checks | |
| |> Task.async_stream(&run_check/1, | |
| max_concurrency: Enum.count(@checks), | |
| ordered: false, | |
| timeout: :infinity | |
| ) | |
| |> Enum.map(fn {:ok, result} -> result end) | |
| Enum.each(results, &print_result/1) | |
| failures = Enum.reject(results, &match?({_, _, 0}, &1)) | |
| if Enum.any?(failures) do | |
| failed_labels = | |
| Enum.map_join(failures, ", ", fn {label, _, _} -> label end) | |
| Mix.raise("QA checks failed: #{failed_labels}") | |
| end | |
| end | |
| def run(_args), do: Mix.raise("mix qa does not accept arguments") | |
| defp run_check({label, args}) do | |
| {output, exit_code} = run_command(args) | |
| {label, output, exit_code} | |
| end | |
| defp run_command!(label, args) do | |
| {output, exit_code} = run_command(args) | |
| print_result({label, output, exit_code}) | |
| if exit_code != 0 do | |
| Mix.raise("QA preparation failed: #{label}") | |
| end | |
| end | |
| defp run_command(args) do | |
| System.cmd(elixir_executable(), @mix_runner_prefix ++ args, | |
| cd: File.cwd!(), | |
| env: [{"MIX_ENV", "test"}], | |
| stderr_to_stdout: true | |
| ) | |
| end | |
| defp print_result({label, output, exit_code}) do | |
| status = if exit_code == 0, do: "ok", else: "failed" | |
| Mix.shell().info("==> #{label} (#{status})") | |
| if output != "" do | |
| Mix.shell().info(String.trim_trailing(output)) | |
| end | |
| end | |
| defp elixir_executable do | |
| System.find_executable("elixir") || | |
| Mix.raise("could not find the elixir executable") | |
| end | |
| end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment