From e1906deaa0704383aa792e5ca2f1237b44017847 Mon Sep 17 00:00:00 2001 From: Michael Heilmann Date: Sat, 18 Jan 2025 15:13:45 -0500 Subject: [PATCH] convert CI compat jobs into single matrix job (#45) * convert CI compat jobs into single matrix job * update matrix with version pairs * flatten the lists, nesting doesn't work like that * whoops, use variables in the right places * erlang setup limits older versions on latest ubuntu runtime * don't use env vars to flag latest * pin down flaky equivalence in test * bump non-release deps * fixup plt caching * cleanup * error on CI after successfull cache, tweak config path * cleanup plt paths in config * include ex_unit now that we are configuring dialyzer --- .github/workflows/ci.yml | 94 ++++++++++++++++++---------------------- .gitignore | 3 ++ mix.exs | 12 ++++- mix.lock | 22 +++++----- test/builder_test.exs | 9 ++-- 5 files changed, 74 insertions(+), 66 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7ad482c..3af2619 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,8 +12,36 @@ env: MIX_ENV: test jobs: - validate_1_13: - name: Validate PR against 1.13 + elixir_compatibility: + name: "Check elixir+otp versions" + strategy: + matrix: + runtime: [ + # https://hexdocs.pm/elixir/compatibility-and-deprecations.html + # running latest ubuntu, OTP >= 24 only + # 1.13.x + { elixir: 1.13.x, otp: 24.3.x }, + { elixir: 1.13.x, otp: 25.3.x }, + # 1.14.x + { elixir: 1.14.x, otp: 24.3.x }, + { elixir: 1.14.x, otp: 25.3.x }, + # 1.15.x + { elixir: 1.15.x, otp: 24.3.x }, + { elixir: 1.15.x, otp: 25.3.x }, + { elixir: 1.15.x, otp: 26.2.x }, + # 1.16.x + { elixir: 1.16.x, otp: 24.3.x }, + { elixir: 1.16.x, otp: 25.3.x }, + { elixir: 1.16.x, otp: 26.2.x }, + # 1.17.x + { elixir: 1.17.x, otp: 25.3.x }, + { elixir: 1.17.x, otp: 26.2.x }, + { elixir: 1.17.x, otp: 27.2.x }, + # 1.18.x + { elixir: 1.18.x, otp: 25.3.x }, + { elixir: 1.18.x, otp: 26.2.x }, + { elixir: 1.18.x, otp: 27.2.x }, + ] runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -22,8 +50,8 @@ jobs: id: beam uses: erlef/setup-beam@v1 with: - otp-version: 25.1.x - elixir-version: 1.13.x + otp-version: ${{ matrix.runtime.otp }} + elixir-version: ${{ matrix.runtime.elixir }} - name: Restore dependencies cache id: mix_cache @@ -43,8 +71,9 @@ jobs: - name: Run test run: mix test - validate_1_14: - name: Validate PR against 1.14 + # run extra steps on latest supported + Linting: + name: Linting on latest runtime runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -53,8 +82,8 @@ jobs: id: beam uses: erlef/setup-beam@v1 with: - otp-version: 25.1.x - elixir-version: 1.14.x + otp-version: 27.2.x + elixir-version: 1.18.x - name: Restore dependencies cache id: mix_cache @@ -71,39 +100,6 @@ jobs: mix deps.get mix deps.compile - - name: Run test - run: mix test - - # run all steps on latest supported - validate_1_15: - name: Validate PR against 1.15 - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - - name: Set up Elixir - id: beam - uses: erlef/setup-beam@v1 - with: - otp-version: 25.1.x - elixir-version: 1.15.x - - - name: Restore dependencies cache - id: mix_cache - uses: actions/cache@v4 - with: - path: | - deps - _build - key: mix-${{ runner.os }}-${{ steps.beam.outputs.otp-version }}-${{ steps.beam.outputs.elixir-version }}-${{ hashFiles('**/mix.lock') }} - restore-keys: mix-${{ runner.os }}-${{ steps.beam.outputs.otp-version }}-${{ steps.beam.outputs.elixir-version }}- - - - name: Install Dependencies - run: | - mix deps.get - mix deps.compile - MIX_ENV=dev mix deps.compile - - name: Restore PLT cache id: plt_cache uses: actions/cache/restore@v4 @@ -114,11 +110,10 @@ jobs: - name: Create PLTs if: steps.plt_cache.outputs.cache-hit != 'true' - run: MIX_ENV=dev mix dialyzer --plt + run: mix dialyzer --plt # By default, the GitHub Cache action will only save the cache if all - # steps in the job succeed, so we separate the cache restore and save - # steps in case running dialyzer fails. + # steps pass, so we manually save after PLT building to keep the cache - name: Save PLT cache id: plt_cache_save uses: actions/cache/save@v4 @@ -133,15 +128,12 @@ jobs: - name: Run credo run: mix credo - - name: Run test - run: mix test - # dialyzer takes longer to run, let others fail faster. - name: Run dialyzer - run: MIX_ENV=dev mix dialyzer --format github + run: mix dialyzer --format github validate_unlocked: - name: Validate Code With Unlocked Dependencies + name: Run with deps-unlocked runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -150,8 +142,8 @@ jobs: id: beam uses: erlef/setup-beam@v1 with: - otp-version: 25.1.x - elixir-version: 1.15.x + otp-version: 27.2.x + elixir-version: 1.18.x - name: Restore dependencies cache id: mix_cache diff --git a/.gitignore b/.gitignore index a4fe27d..d331e4d 100644 --- a/.gitignore +++ b/.gitignore @@ -24,3 +24,6 @@ grpc_reflection-*.tar # Temporary files, for example, from tests. /tmp/ + +# Ignore dialyzer PLT files +priv/plts diff --git a/mix.exs b/mix.exs index ae752f9..f4e1f2f 100644 --- a/mix.exs +++ b/mix.exs @@ -26,7 +26,8 @@ defmodule GrpcReflection.MixProject do GrpcReflection.TestEndpoint, GrpcReflection.TestEndpoint.Endpoint ] - ] + ], + dialyzer: dialyzer() ] end @@ -115,4 +116,13 @@ defmodule GrpcReflection.MixProject do formatters: ["html"] ] end + + defp dialyzer do + [ + plt_local_path: "priv/plts/project", + plt_core_path: "priv/plts/core", + plt_add_apps: [:ex_unit], + list_unused_filters: true + ] + end end diff --git a/mix.lock b/mix.lock index f4548db..df5c17b 100644 --- a/mix.lock +++ b/mix.lock @@ -2,22 +2,22 @@ "bunt": {:hex, :bunt, "1.0.0", "081c2c665f086849e6d57900292b3a161727ab40431219529f13c4ddcf3e7a44", [:mix], [], "hexpm", "dc5f86aa08a5f6fa6b8096f0735c4e76d54ae5c9fa2c143e5a1fc7c1cd9bb6b5"}, "cowboy": {:hex, :cowboy, "2.12.0", "f276d521a1ff88b2b9b4c54d0e753da6c66dd7be6c9fca3d9418b561828a3731", [:make, :rebar3], [{:cowlib, "2.13.0", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "1.8.0", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "8a7abe6d183372ceb21caa2709bec928ab2b72e18a3911aa1771639bef82651e"}, "cowlib": {:hex, :cowlib, "2.13.0", "db8f7505d8332d98ef50a3ef34b34c1afddec7506e4ee4dd4a3a266285d282ca", [:make, :rebar3], [], "hexpm", "e1e1284dc3fc030a64b1ad0d8382ae7e99da46c3246b815318a4b848873800a4"}, - "credo": {:hex, :credo, "1.7.5", "643213503b1c766ec0496d828c90c424471ea54da77c8a168c725686377b9545", [:mix], [{:bunt, "~> 0.2.1 or ~> 1.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "f799e9b5cd1891577d8c773d245668aa74a2fcd15eb277f51a0131690ebfb3fd"}, - "dialyxir": {:hex, :dialyxir, "1.4.3", "edd0124f358f0b9e95bfe53a9fcf806d615d8f838e2202a9f430d59566b6b53b", [:mix], [{:erlex, ">= 0.2.6", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "bf2cfb75cd5c5006bec30141b131663299c661a864ec7fbbc72dfa557487a986"}, - "earmark_parser": {:hex, :earmark_parser, "1.4.39", "424642f8335b05bb9eb611aa1564c148a8ee35c9c8a8bba6e129d51a3e3c6769", [:mix], [], "hexpm", "06553a88d1f1846da9ef066b87b57c6f605552cfbe40d20bd8d59cc6bde41944"}, - "erlex": {:hex, :erlex, "0.2.6", "c7987d15e899c7a2f34f5420d2a2ea0d659682c06ac607572df55a43753aa12e", [:mix], [], "hexpm", "2ed2e25711feb44d52b17d2780eabf998452f6efda104877a3881c2f8c0c0c75"}, - "ex_doc": {:hex, :ex_doc, "0.34.0", "ab95e0775db3df71d30cf8d78728dd9261c355c81382bcd4cefdc74610bef13e", [:mix], [{:earmark_parser, "~> 1.4.39", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_c, ">= 0.1.0", [hex: :makeup_c, repo: "hexpm", optional: true]}, {:makeup_elixir, "~> 0.14 or ~> 1.0", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1 or ~> 1.0", [hex: :makeup_erlang, repo: "hexpm", optional: false]}, {:makeup_html, ">= 0.1.0", [hex: :makeup_html, repo: "hexpm", optional: true]}], "hexpm", "60734fb4c1353f270c3286df4a0d51e65a2c1d9fba66af3940847cc65a8066d7"}, - "file_system": {:hex, :file_system, "1.0.0", "b689cc7dcee665f774de94b5a832e578bd7963c8e637ef940cd44327db7de2cd", [:mix], [], "hexpm", "6752092d66aec5a10e662aefeed8ddb9531d79db0bc145bb8c40325ca1d8536d"}, + "credo": {:hex, :credo, "1.7.11", "d3e805f7ddf6c9c854fd36f089649d7cf6ba74c42bc3795d587814e3c9847102", [:mix], [{:bunt, "~> 0.2.1 or ~> 1.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "56826b4306843253a66e47ae45e98e7d284ee1f95d53d1612bb483f88a8cf219"}, + "dialyxir": {:hex, :dialyxir, "1.4.5", "ca1571ac18e0f88d4ab245f0b60fa31ff1b12cbae2b11bd25d207f865e8ae78a", [:mix], [{:erlex, ">= 0.2.7", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "b0fb08bb8107c750db5c0b324fa2df5ceaa0f9307690ee3c1f6ba5b9eb5d35c3"}, + "earmark_parser": {:hex, :earmark_parser, "1.4.42", "f23d856f41919f17cd06a493923a722d87a2d684f143a1e663c04a2b93100682", [:mix], [], "hexpm", "6915b6ca369b5f7346636a2f41c6a6d78b5af419d61a611079189233358b8b8b"}, + "erlex": {:hex, :erlex, "0.2.7", "810e8725f96ab74d17aac676e748627a07bc87eb950d2b83acd29dc047a30595", [:mix], [], "hexpm", "3ed95f79d1a844c3f6bf0cea61e0d5612a42ce56da9c03f01df538685365efb0"}, + "ex_doc": {:hex, :ex_doc, "0.36.1", "4197d034f93e0b89ec79fac56e226107824adcce8d2dd0a26f5ed3a95efc36b1", [:mix], [{:earmark_parser, "~> 1.4.42", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_c, ">= 0.1.0", [hex: :makeup_c, repo: "hexpm", optional: true]}, {:makeup_elixir, "~> 0.14 or ~> 1.0", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1 or ~> 1.0", [hex: :makeup_erlang, repo: "hexpm", optional: false]}, {:makeup_html, ">= 0.1.0", [hex: :makeup_html, repo: "hexpm", optional: true]}], "hexpm", "d7d26a7cf965dacadcd48f9fa7b5953d7d0cfa3b44fa7a65514427da44eafd89"}, + "file_system": {:hex, :file_system, "1.1.0", "08d232062284546c6c34426997dd7ef6ec9f8bbd090eb91780283c9016840e8f", [:mix], [], "hexpm", "bfcf81244f416871f2a2e15c1b515287faa5db9c6bcf290222206d120b3d43f6"}, "google_protos": {:hex, :google_protos, "0.4.0", "93e1be2c1a07517ffed761f69047776caf35e4acd385aac4f5ce4fedd07f3660", [:mix], [{:protobuf, "~> 0.10", [hex: :protobuf, repo: "hexpm", optional: false]}], "hexpm", "4c54983d78761a3643e2198adf0f5d40a5a8b08162f3fc91c50faa257f3fa19f"}, "grpc": {:hex, :grpc, "0.8.1", "a8a5884a0d41fc30679c269d0332571cebb43cbfd6eb3d4819169778e866343e", [:mix], [{:castore, "~> 0.1 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:cowboy, "~> 2.10", [hex: :cowboy, repo: "hexpm", optional: false]}, {:cowlib, "~> 2.12", [hex: :cowlib, repo: "hexpm", optional: false]}, {:gun, "~> 2.0", [hex: :gun, repo: "hexpm", optional: false]}, {:jason, ">= 0.0.0", [hex: :jason, repo: "hexpm", optional: true]}, {:mint, "~> 1.5", [hex: :mint, repo: "hexpm", optional: false]}, {:protobuf, "~> 0.11", [hex: :protobuf, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "1cccd9fd83547a562f315cc0e1ee1879546f0a44193b5c8eb8d68dae0bb2065b"}, "gun": {:hex, :gun, "2.1.0", "b4e4cbbf3026d21981c447e9e7ca856766046eff693720ba43114d7f5de36e87", [:make, :rebar3], [{:cowlib, "2.13.0", [hex: :cowlib, repo: "hexpm", optional: false]}], "hexpm", "52fc7fc246bfc3b00e01aea1c2854c70a366348574ab50c57dfe796d24a0101d"}, "hpax": {:hex, :hpax, "0.2.0", "5a58219adcb75977b2edce5eb22051de9362f08236220c9e859a47111c194ff5", [:mix], [], "hexpm", "bea06558cdae85bed075e6c036993d43cd54d447f76d8190a8db0dc5893fa2f1"}, - "jason": {:hex, :jason, "1.4.1", "af1504e35f629ddcdd6addb3513c3853991f694921b1b9368b0bd32beb9f1b63", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "fbb01ecdfd565b56261302f7e1fcc27c4fb8f32d56eab74db621fc154604a7a1"}, - "makeup": {:hex, :makeup, "1.1.2", "9ba8837913bdf757787e71c1581c21f9d2455f4dd04cfca785c70bbfff1a76a3", [:mix], [{:nimble_parsec, "~> 1.2.2 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "cce1566b81fbcbd21eca8ffe808f33b221f9eee2cbc7a1706fc3da9ff18e6cac"}, - "makeup_elixir": {:hex, :makeup_elixir, "0.16.2", "627e84b8e8bf22e60a2579dad15067c755531fea049ae26ef1020cad58fe9578", [: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", "41193978704763f6bbe6cc2758b84909e62984c7752b3784bd3c218bb341706b"}, - "makeup_erlang": {:hex, :makeup_erlang, "1.0.0", "6f0eff9c9c489f26b69b61440bf1b238d95badae49adac77973cbacae87e3c2e", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "ea7a9307de9d1548d2a72d299058d1fd2339e3d398560a0e46c27dab4891e4d2"}, + "jason": {:hex, :jason, "1.4.4", "b9226785a9aa77b6857ca22832cffa5d5011a667207eb2a0ad56adb5db443b8a", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "c5eb0cab91f094599f94d55bc63409236a8ec69a21a67814529e8d5f6cc90b3b"}, + "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.1", "c7f58c120b2b5aa5fd80d540a89fdf866ed42f1f3994e4fe189abebeab610839", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "8a89a1eeccc2d798d6ea15496a6e4870b75e014d1af514b1b71fa33134f57814"}, "mint": {:hex, :mint, "1.6.0", "88a4f91cd690508a04ff1c3e28952f322528934be541844d54e0ceb765f01d5e", [:mix], [{:castore, "~> 0.1.0 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:hpax, "~> 0.1.1 or ~> 0.2.0", [hex: :hpax, repo: "hexpm", optional: false]}], "hexpm", "3c5ae85d90a5aca0a49c0d8b67360bbe407f3b54f1030a111047ff988e8fefaa"}, - "nimble_parsec": {:hex, :nimble_parsec, "1.4.0", "51f9b613ea62cfa97b25ccc2c1b4216e81df970acd8e16e8d1bdc58fef21370d", [:mix], [], "hexpm", "9c565862810fb383e9838c1dd2d7d2c437b3d13b267414ba6af33e50d2d1cf28"}, + "nimble_parsec": {:hex, :nimble_parsec, "1.4.1", "f41275a0354c736db4b1d255b5d2a27c91028e55c21ea3145b938e22649ffa3f", [:mix], [], "hexpm", "605e44204998f138d6e13be366c8e81af860e726c8177caf50067e1b618fe522"}, "protobuf": {:hex, :protobuf, "0.12.0", "58c0dfea5f929b96b5aa54ec02b7130688f09d2de5ddc521d696eec2a015b223", [:mix], [{:jason, "~> 1.2", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm", "75fa6cbf262062073dd51be44dd0ab940500e18386a6c4e87d5819a58964dc45"}, "ranch": {:hex, :ranch, "1.8.0", "8c7a100a139fd57f17327b6413e4167ac559fbc04ca7448e9be9057311597a1d", [:make, :rebar3], [], "hexpm", "49fbcfd3682fab1f5d109351b61257676da1a2fdbe295904176d5e521a2ddfe5"}, "telemetry": {:hex, :telemetry, "1.2.1", "68fdfe8d8f05a8428483a97d7aab2f268aaff24b49e0f599faa091f1d4e7f61c", [:rebar3], [], "hexpm", "dad9ce9d8effc621708f99eac538ef1cbe05d6a874dd741de2e689c47feafed5"}, diff --git a/test/builder_test.exs b/test/builder_test.exs index 3acbc85..9424c87 100644 --- a/test/builder_test.exs +++ b/test/builder_test.exs @@ -73,9 +73,12 @@ defmodule GrpcReflection.BuilderTest do "testserviceV2.TestService.CallFunction" ] - assert tree.extensions == %{ - "testserviceV2.TestRequest" => [10, 11] - } + assert %{ + "testserviceV2.TestRequest" => extensions + } = tree.extensions + + # this is a bitstring that may contain whitespace characters + assert extensions |> to_string() |> String.trim() == "" (Map.values(tree.files) ++ Map.values(tree.symbols)) |> Enum.flat_map(&Map.get(&1, :file_descriptor_proto))