From 9f56b879e7421a6245846d3b9a61dc81756d6afd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Jan=20Niemier?= Date: Fri, 28 Jun 2024 15:23:16 +0200 Subject: [PATCH] chore: split Elixir tasks (#375) Split CI tasks related to Elixir to improve build times by parallelizing different steps. --- .dialyzer_ignore.exs | 3 + .github/workflows/elixir.yml | 234 +++++++++++++++++++++++++++ .github/workflows/prod.yml | 10 +- .github/workflows/stage.yml | 10 +- .github/workflows/staging_linter.yml | 61 ------- VERSION | 2 +- mix.exs | 10 +- mix.lock | 8 +- 8 files changed, 259 insertions(+), 79 deletions(-) create mode 100644 .dialyzer_ignore.exs create mode 100644 .github/workflows/elixir.yml delete mode 100644 .github/workflows/staging_linter.yml diff --git a/.dialyzer_ignore.exs b/.dialyzer_ignore.exs new file mode 100644 index 00000000..b36f7ac5 --- /dev/null +++ b/.dialyzer_ignore.exs @@ -0,0 +1,3 @@ +[ + ~r(test/support/[^.]*\.ex) +] diff --git a/.github/workflows/elixir.yml b/.github/workflows/elixir.yml new file mode 100644 index 00000000..7c9c7352 --- /dev/null +++ b/.github/workflows/elixir.yml @@ -0,0 +1,234 @@ +name: Elixir tests +on: + pull_request: + branches: + - main + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +env: + SECRET_KEY_BASE: ${{ secrets.SECRET_KEY_BASE }} + LANG: C.UTF-8 + LC_ALL: C.UTF-8 + MIX_ENV: test + +jobs: + deps: + name: Fetch deps + runs-on: u22-arm-runner + + steps: + - uses: actions/checkout@v4 + - name: Setup Elixir + id: beam + uses: erlef/setup-beam@v1 + with: + otp-version: '25.3.2.7' + elixir-version: '1.14.5' + - name: Cache Mix + uses: actions/cache@v4 + with: + path: deps + key: ${{ runner.os }}-mix-${{ hashFiles(format('{0}{1}', github.workspace, '/mix.lock')) }} + restore-keys: | + ${{ runner.os }}-mix- + - name: Install dependencies + run: mix deps.get + + compile: + name: Compile project in test env + runs-on: u22-arm-runner + needs: [deps] + + steps: + - uses: actions/checkout@v4 + - name: Setup Elixir + id: beam + uses: erlef/setup-beam@v1 + with: + otp-version: '25.3.2.7' + elixir-version: '1.14.5' + - name: Cache Mix + uses: actions/cache@v4 + with: + path: deps + key: ${{ runner.os }}-mix-${{ hashFiles(format('{0}{1}', github.workspace, '/mix.lock')) }} + restore-keys: | + ${{ runner.os }}-mix- + - name: Cache Build + uses: actions/cache@v4 + with: + path: | + _build/${{ env.MIX_ENV }} + key: ${{ runner.os }}-build-${{ env.MIX_ENV }}-${{ steps.beam.outputs.otp-version }}-${{ steps.beam.outputs.elixir-version }}-${{ hashFiles(format('{0}{1}', github.workspace, '/mix.lock')) }}-${{ github.sha }} + restore-keys: | + ${{ runner.os }}-build-${{ env.MIX_ENV }}- + - name: Cache native + uses: actions/cache@v4 + id: native-cache + with: + path: | + priv/native + key: ${{ runner.os }}-build-native-${{ steps.beam.outputs.otp-version }}-${{ steps.beam.outputs.elixir-version }}-${{ hashFiles(format('{0}{1}', github.workspace, '/native/**/*')) }} + - name: Set up Rust + uses: dtolnay/rust-toolchain@v1 + if: steps.native-cache.outputs.cache-hit != 'true' || steps.elixir-cache.output.cache-hit != 'true' + with: + toolchain: stable + - name: Compile + run: mix compile + + format: + name: Formatting checks + runs-on: u22-arm-runner + needs: [deps] + + steps: + - uses: actions/checkout@v4 + - name: Setup Elixir + id: beam + uses: erlef/setup-beam@v1 + with: + otp-version: '25.3.2.7' + elixir-version: '1.17' + - name: Cache Mix + uses: actions/cache@v4 + with: + path: deps + key: ${{ runner.os }}-mix-${{ hashFiles(format('{0}{1}', github.workspace, '/mix.lock')) }} + restore-keys: | + ${{ runner.os }}-mix- + - name: Run format check + run: mix format --check-formatted + + credo: + name: Code style + runs-on: u22-arm-runner + needs: [compile] + + steps: + - uses: actions/checkout@v4 + - name: Setup Elixir + id: beam + uses: erlef/setup-beam@v1 + with: + otp-version: '25.3.2.7' + elixir-version: '1.14.5' + - name: Cache Mix + uses: actions/cache@v4 + with: + path: deps + key: ${{ runner.os }}-mix-${{ hashFiles(format('{0}{1}', github.workspace, '/mix.lock')) }} + restore-keys: | + ${{ runner.os }}-mix- + - name: Cache Build + uses: actions/cache@v4 + with: + path: | + _build/${{ env.MIX_ENV }} + key: ${{ runner.os }}-build-${{ env.MIX_ENV }}-${{ steps.beam.outputs.otp-version }}-${{ steps.beam.outputs.elixir-version }}-${{ hashFiles(format('{0}{1}', github.workspace, '/mix.lock')) }}-${{ github.sha }} + restore-keys: | + ${{ runner.os }}-build-${{ env.MIX_ENV }}- + - name: Credo checks + run: mix credo --strict --mute-exit-status + + tests: + name: Run tests + runs-on: u22-arm-runner + needs: [compile] + + steps: + - uses: actions/checkout@v4 + - name: Setup Elixir + id: beam + uses: erlef/setup-beam@v1 + with: + otp-version: '25.3.2.7' + elixir-version: '1.14.5' + - name: Set up Rust + uses: dtolnay/rust-toolchain@v1 + if: steps.native-cache.outputs.cache-hit != 'true' || steps.elixir-cache.output.cache-hit != 'true' + with: + toolchain: stable + - name: Cache Mix + uses: actions/cache@v4 + with: + path: deps + key: ${{ runner.os }}-mix-${{ hashFiles(format('{0}{1}', github.workspace, '/mix.lock')) }} + restore-keys: | + ${{ runner.os }}-mix- + - name: Cache Build + uses: actions/cache@v4 + with: + path: | + _build/${{ env.MIX_ENV }} + key: ${{ runner.os }}-build-${{ env.MIX_ENV }}-${{ steps.beam.outputs.otp-version }}-${{ steps.beam.outputs.elixir-version }}-${{ hashFiles(format('{0}{1}', github.workspace, '/mix.lock')) }}-${{ github.sha }} + restore-keys: | + ${{ runner.os }}-build-${{ env.MIX_ENV }}- + - name: Cache native + uses: actions/cache@v4 + with: + path: | + priv/native + key: ${{ runner.os }}-build-native-${{ steps.beam.outputs.otp-version }}-${{ steps.beam.outputs.elixir-version }}-${{ hashFiles(format('{0}{1}', github.workspace, '/native/**/*')) }} + - name: Set up Postgres + run: docker-compose -f ./docker-compose.db.yml up -d + - name: Start epmd + run: epmd -daemon + - name: Run tests + run: mix test + + dialyzer: + name: Dialyze + runs-on: u22-arm-runner + needs: [compile] + + steps: + - uses: actions/checkout@v4 + - name: Setup Elixir + id: beam + uses: erlef/setup-beam@v1 + with: + otp-version: '25.3.2.7' + elixir-version: '1.14.5' + - name: Set up Rust + uses: dtolnay/rust-toolchain@v1 + if: steps.native-cache.outputs.cache-hit != 'true' || steps.elixir-cache.output.cache-hit != 'true' + with: + toolchain: stable + - name: Cache Mix + uses: actions/cache@v4 + with: + path: deps + key: ${{ runner.os }}-mix-${{ hashFiles(format('{0}{1}', github.workspace, '/mix.lock')) }} + restore-keys: | + ${{ runner.os }}-mix- + - name: Cache Build + uses: actions/cache@v4 + with: + path: | + _build/${{ env.MIX_ENV }} + key: ${{ runner.os }}-build-${{ env.MIX_ENV }}-${{ steps.beam.outputs.otp-version }}-${{ steps.beam.outputs.elixir-version }}-${{ hashFiles(format('{0}{1}', github.workspace, '/mix.lock')) }}-${{ github.sha }} + restore-keys: | + ${{ runner.os }}-build-${{ env.MIX_ENV }}- + - name: Cache native + uses: actions/cache@v4 + with: + path: | + priv/native + key: ${{ runner.os }}-build-native-${{ steps.beam.outputs.otp-version }}-${{ steps.beam.outputs.elixir-version }}-${{ hashFiles(format('{0}{1}', github.workspace, '/native/**/*')) }} + - name: Retrieve PLT Cache + uses: actions/cache@v4 + id: plt-cache + with: + path: _build/${{ env.MIX_ENV }}/*.plt + key: ${{ runner.os }}-${{ steps.beam.outputs.otp-version }}-${{ steps.beam.outputs.elixir-version }}-plts-${{ hashFiles(format('{0}{1}', github.workspace, '/mix.lock')) }} + - name: Create PLTs + if: steps.plt-cache.outputs.cache-hit != 'true' + run: | + mkdir -p priv/plts + mix dialyzer.build + - name: Run dialyzer + run: mix dialyzer diff --git a/.github/workflows/prod.yml b/.github/workflows/prod.yml index 48dfa754..86d56174 100644 --- a/.github/workflows/prod.yml +++ b/.github/workflows/prod.yml @@ -14,13 +14,13 @@ jobs: permissions: contents: write packages: write - id-token: write + id-token: write steps: - name: Checkout code uses: actions/checkout@v4 - name: Set upgrade variables run: | - elixir ./deploy/upgrade/handler.exs all_keys ./deploy/upgrade/prod.config + elixir ./deploy/upgrade/handler.exs all_keys ./deploy/upgrade/prod.config echo "RELEASE_FROM=$(elixir ./deploy/upgrade/handler.exs upgrade_from ./deploy/upgrade/prod.config)" >> $GITHUB_ENV echo "RELEASE_TO=$(elixir ./deploy/upgrade/handler.exs upgrade_to ./deploy/upgrade/prod.config)" >> $GITHUB_ENV echo "NAME=$(elixir ./deploy/upgrade/handler.exs name ./deploy/upgrade/prod.config)" >> $GITHUB_ENV @@ -33,9 +33,9 @@ jobs: - name: Set up Rust uses: dtolnay/rust-toolchain@v1 with: - toolchain: stable + toolchain: stable - name: Get git tags - run: git fetch --tags origin + run: git fetch --tags origin - name: Checkout RELEASE_FROM run: git checkout v${{ env.RELEASE_FROM }} - name: Cache Mix @@ -51,7 +51,7 @@ jobs: mix local.rebar --force mix deps.get - name: Make old release - run: mix release supavisor + run: mix release supavisor - name: Checkout RELEASE_TO run: git checkout v${{ env.RELEASE_TO }} - name: Cache Mix diff --git a/.github/workflows/stage.yml b/.github/workflows/stage.yml index c079005e..83f5b01e 100644 --- a/.github/workflows/stage.yml +++ b/.github/workflows/stage.yml @@ -14,13 +14,13 @@ jobs: permissions: contents: write packages: write - id-token: write + id-token: write steps: - name: Checkout code uses: actions/checkout@v4 - name: Set upgrade variables run: | - elixir ./deploy/upgrade/handler.exs all_keys ./deploy/upgrade/staging.config + elixir ./deploy/upgrade/handler.exs all_keys ./deploy/upgrade/staging.config echo "RELEASE_FROM=$(elixir ./deploy/upgrade/handler.exs upgrade_from ./deploy/upgrade/staging.config)" >> $GITHUB_ENV echo "RELEASE_TO=$(elixir ./deploy/upgrade/handler.exs upgrade_to ./deploy/upgrade/staging.config)" >> $GITHUB_ENV echo "NAME=$(elixir ./deploy/upgrade/handler.exs name ./deploy/upgrade/staging.config)" >> $GITHUB_ENV @@ -33,9 +33,9 @@ jobs: - name: Set up Rust uses: dtolnay/rust-toolchain@v1 with: - toolchain: stable + toolchain: stable - name: Get git tags - run: git fetch --tags origin + run: git fetch --tags origin - name: Checkout RELEASE_FROM run: git checkout v${{ env.RELEASE_FROM }} - name: Cache Mix @@ -51,7 +51,7 @@ jobs: mix local.rebar --force mix deps.get - name: Make old release - run: mix release supavisor + run: mix release supavisor - name: Checkout RELEASE_TO run: git checkout v${{ env.RELEASE_TO }} - name: Cache Mix diff --git a/.github/workflows/staging_linter.yml b/.github/workflows/staging_linter.yml deleted file mode 100644 index 70806ab3..00000000 --- a/.github/workflows/staging_linter.yml +++ /dev/null @@ -1,61 +0,0 @@ -name: Staging Formatting Checks -on: - pull_request: - branches: - - main -env: - SECRET_KEY_BASE: ${{ secrets.SECRET_KEY_BASE }} -jobs: - format: - name: Formatting Checks - runs-on: u22-arm-runner - - steps: - - uses: actions/checkout@v4 - - name: Setup Elixir - run: | - . ~/.asdf/asdf.sh - echo 'elixir v1.14.5-otp-25' >> ~/.tool-versions - echo 'erlang 25.3.2.7' >> ~/.tool-versions - elixir -v - - name: Set up Rust - uses: dtolnay/rust-toolchain@v1 - with: - toolchain: stable - - name: Cache Mix - uses: actions/cache@v3 - with: - path: deps - key: ${{ runner.os }}-mix-${{ hashFiles(format('{0}{1}', github.workspace, '/mix.lock')) }} - restore-keys: | - ${{ runner.os }}-mix- - - name: Install dependencies - run: | - mix local.hex --force - mix local.rebar --force - mix deps.get - - name: Set up Postgres - run: docker-compose -f ./docker-compose.db.yml up -d - - name: Run main database migrations - run: mix ecto.migrate --prefix _supavisor --log-migrator-sql - - name: Run format check - run: mix format --check-formatted - - name: Credo checks - run: mix credo --strict --mute-exit-status - - name: Retrieve PLT Cache - uses: actions/cache@v3 - id: plt-cache - with: - path: priv/plts - key: ${{ runner.os }}-${{ steps.beam.outputs.otp-version }}-${{ steps.beam.outputs.elixir-version }}-plts-${{ hashFiles(format('{0}{1}', github.workspace, '/mix.lock')) }} - - name: Create PLTs - if: steps.plt-cache.outputs.cache-hit != 'true' - run: | - mkdir -p priv/plts - mix dialyzer.build - - name: Run dialyzer - run: mix dialyzer - - name: Start epmd - run: epmd -daemon - - name: Run tests - run: mix test diff --git a/VERSION b/VERSION index 0041a435..470abefa 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.1.66 +1.1.67 diff --git a/mix.exs b/mix.exs index b079454b..111b3ab1 100644 --- a/mix.exs +++ b/mix.exs @@ -21,10 +21,14 @@ defmodule Supavisor.MixProject do def application do [ mod: {Supavisor.Application, []}, - extra_applications: [:logger, :runtime_tools, :os_mon, :ssl, :partisan] + extra_applications: + [:logger, :runtime_tools, :os_mon, :ssl, :partisan] ++ extra_applications(Mix.env()) ] end + defp extra_applications(:test), do: [:common_test] + defp extra_applications(_), do: [] + # Specifies which paths to compile per environment. defp elixirc_paths(:test), do: ["lib", "test/support"] defp elixirc_paths(_), do: ["lib"] @@ -50,8 +54,8 @@ defmodule Supavisor.MixProject do {:joken, "~> 2.5.0"}, {:cloak_ecto, "~> 1.2.0"}, {:meck, "~> 0.9.2", only: :test}, - {:credo, "~> 1.6.4", only: [:dev, :test], runtime: false}, - {:dialyxir, "~> 1.1.0", only: [:dev], runtime: false}, + {:credo, "~> 1.7", only: [:dev, :test], runtime: false}, + {:dialyxir, "~> 1.4", only: [:dev, :test], runtime: false}, {:benchee, "~> 1.1.0", only: :dev}, {:prom_ex, "~> 1.8.0"}, {:open_api_spex, "~> 3.16"}, diff --git a/mix.lock b/mix.lock index 8cab290a..6bc3bbe7 100644 --- a/mix.lock +++ b/mix.lock @@ -4,7 +4,7 @@ "backoff": {:hex, :backoff, "1.1.6", "83b72ed2108ba1ee8f7d1c22e0b4a00cfe3593a67dbc792799e8cce9f42f796b", [:rebar3], [], "hexpm", "cf0cfff8995fb20562f822e5cc47d8ccf664c5ecdc26a684cbe85c225f9d7c39"}, "benchee": {:hex, :benchee, "1.1.0", "f3a43817209a92a1fade36ef36b86e1052627fd8934a8b937ac9ab3a76c43062", [:mix], [{:deep_merge, "~> 1.0", [hex: :deep_merge, repo: "hexpm", optional: false]}, {:statistex, "~> 1.0", [hex: :statistex, repo: "hexpm", optional: false]}], "hexpm", "7da57d545003165a012b587077f6ba90b89210fd88074ce3c60ce239eb5e6d93"}, "bertex": {:hex, :bertex, "1.3.0", "0ad0df9159b5110d9d2b6654f72fbf42a54884ef43b6b651e6224c0af30ba3cb", [:mix], [], "hexpm", "0a5d5e478bb5764b7b7bae37cae1ca491200e58b089df121a2fe1c223d8ee57a"}, - "bunt": {:hex, :bunt, "0.2.1", "e2d4792f7bc0ced7583ab54922808919518d0e57ee162901a16a1b6664ef3b14", [:mix], [], "hexpm", "a330bfb4245239787b15005e66ae6845c9cd524a288f0d141c148b02603777a5"}, + "bunt": {:hex, :bunt, "1.0.0", "081c2c665f086849e6d57900292b3a161727ab40431219529f13c4ddcf3e7a44", [:mix], [], "hexpm", "dc5f86aa08a5f6fa6b8096f0735c4e76d54ae5c9fa2c143e5a1fc7c1cd9bb6b5"}, "burrito": {:git, "https://github.com/burrito-elixir/burrito.git", "a60c6ab21156fc4c788907d33bfd0c546a022272", []}, "cachex": {:hex, :cachex, "3.6.0", "14a1bfbeee060dd9bec25a5b6f4e4691e3670ebda28c8ba2884b12fe30b36bf8", [:mix], [{:eternal, "~> 1.2", [hex: :eternal, repo: "hexpm", optional: false]}, {:jumper, "~> 1.0", [hex: :jumper, repo: "hexpm", optional: false]}, {:sleeplocks, "~> 1.1", [hex: :sleeplocks, repo: "hexpm", optional: false]}, {:unsafe, "~> 1.0", [hex: :unsafe, repo: "hexpm", optional: false]}], "hexpm", "ebf24e373883bc8e0c8d894a63bbe102ae13d918f790121f5cfe6e485cc8e2e2"}, "castore": {:hex, :castore, "1.0.4", "ff4d0fb2e6411c0479b1d965a814ea6d00e51eb2f58697446e9c41a97d940b28", [:mix], [], "hexpm", "9418c1b8144e11656f0be99943db4caf04612e3eaecefb5dae9a2a87565584f8"}, @@ -13,15 +13,15 @@ "cowboy": {:hex, :cowboy, "2.10.0", "ff9ffeff91dae4ae270dd975642997afe2a1179d94b1887863e43f681a203e26", [:make, :rebar3], [{:cowlib, "2.12.1", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "1.8.0", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "3afdccb7183cc6f143cb14d3cf51fa00e53db9ec80cdcd525482f5e99bc41d6b"}, "cowboy_telemetry": {:hex, :cowboy_telemetry, "0.4.0", "f239f68b588efa7707abce16a84d0d2acf3a0f50571f8bb7f56a15865aae820c", [:rebar3], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "7d98bac1ee4565d31b62d59f8823dfd8356a169e7fcbb83831b8a5397404c9de"}, "cowlib": {:hex, :cowlib, "2.12.1", "a9fa9a625f1d2025fe6b462cb865881329b5caff8f1854d1cbc9f9533f00e1e1", [:make, :rebar3], [], "hexpm", "163b73f6367a7341b33c794c4e88e7dbfe6498ac42dcd69ef44c5bc5507c8db0"}, - "credo": {:hex, :credo, "1.6.7", "323f5734350fd23a456f2688b9430e7d517afb313fbd38671b8a4449798a7854", [:mix], [{:bunt, "~> 0.2.1", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2.8", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "41e110bfb007f7eda7f897c10bf019ceab9a0b269ce79f015d54b0dcf4fc7dd3"}, + "credo": {:hex, :credo, "1.7.7", "771445037228f763f9b2afd612b6aa2fd8e28432a95dbbc60d8e03ce71ba4446", [: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", "8bc87496c9aaacdc3f90f01b7b0582467b69b4bd2441fe8aae3109d843cc2f2e"}, "db_connection": {:hex, :db_connection, "2.6.0", "77d835c472b5b67fc4f29556dee74bf511bbafecdcaf98c27d27fa5918152086", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "c2f992d15725e721ec7fbc1189d4ecdb8afef76648c746a8e1cad35e3b8a35f3"}, "decimal": {:hex, :decimal, "2.1.1", "5611dca5d4b2c3dd497dec8f68751f1f1a54755e8ed2a966c2633cf885973ad6", [:mix], [], "hexpm", "53cfe5f497ed0e7771ae1a475575603d77425099ba5faef9394932b35020ffcc"}, "deep_merge": {:hex, :deep_merge, "1.0.0", "b4aa1a0d1acac393bdf38b2291af38cb1d4a52806cf7a4906f718e1feb5ee961", [:mix], [], "hexpm", "ce708e5f094b9cd4e8f2be4f00d2f4250c4095be93f8cd6d018c753894885430"}, - "dialyxir": {:hex, :dialyxir, "1.1.0", "c5aab0d6e71e5522e77beff7ba9e08f8e02bad90dfbeffae60eaf0cb47e29488", [:mix], [{:erlex, ">= 0.2.6", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "07ea8e49c45f15264ebe6d5b93799d4dd56a44036cf42d0ad9c960bc266c0b9a"}, + "dialyxir": {:hex, :dialyxir, "1.4.3", "edd0124f358f0b9e95bfe53a9fcf806d615d8f838e2202a9f430d59566b6b53b", [:mix], [{:erlex, ">= 0.2.6", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "bf2cfb75cd5c5006bec30141b131663299c661a864ec7fbbc72dfa557487a986"}, "distillery": {:hex, :distillery, "2.1.1", "f9332afc2eec8a1a2b86f22429e068ef35f84a93ea1718265e740d90dd367814", [:mix], [{:artificery, "~> 0.2", [hex: :artificery, repo: "hexpm", optional: false]}], "hexpm", "bbc7008b0161a6f130d8d903b5b3232351fccc9c31a991f8fcbf2a12ace22995"}, "ecto": {:hex, :ecto, "3.10.3", "eb2ae2eecd210b4eb8bece1217b297ad4ff824b4384c0e3fdd28aaf96edd6135", [:mix], [{:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "44bec74e2364d491d70f7e42cd0d690922659d329f6465e89feb8a34e8cd3433"}, "ecto_sql": {:hex, :ecto_sql, "3.10.2", "6b98b46534b5c2f8b8b5f03f126e75e2a73c64f3c071149d32987a5378b0fdbd", [:mix], [{:db_connection, "~> 2.4.1 or ~> 2.5", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.10.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:myxql, "~> 0.6.0", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.16.0 or ~> 0.17.0 or ~> 1.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:tds, "~> 2.1.1 or ~> 2.2", [hex: :tds, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "68c018debca57cb9235e3889affdaec7a10616a4e3a80c99fa1d01fdafaa9007"}, - "erlex": {:hex, :erlex, "0.2.6", "c7987d15e899c7a2f34f5420d2a2ea0d659682c06ac607572df55a43753aa12e", [:mix], [], "hexpm", "2ed2e25711feb44d52b17d2780eabf998452f6efda104877a3881c2f8c0c0c75"}, + "erlex": {:hex, :erlex, "0.2.7", "810e8725f96ab74d17aac676e748627a07bc87eb950d2b83acd29dc047a30595", [:mix], [], "hexpm", "3ed95f79d1a844c3f6bf0cea61e0d5612a42ce56da9c03f01df538685365efb0"}, "eternal": {:hex, :eternal, "1.2.2", "d1641c86368de99375b98d183042dd6c2b234262b8d08dfd72b9eeaafc2a1abd", [:mix], [], "hexpm", "2c9fe32b9c3726703ba5e1d43a1d255a4f3f2d8f8f9bc19f094c7cb1a7a9e782"}, "file_system": {:hex, :file_system, "0.2.10", "fb082005a9cd1711c05b5248710f8826b02d7d1784e7c3451f9c1231d4fc162d", [:mix], [], "hexpm", "41195edbfb562a593726eda3b3e8b103a309b733ad25f3d642ba49696bf715dc"}, "finch": {:hex, :finch, "0.16.0", "40733f02c89f94a112518071c0a91fe86069560f5dbdb39f9150042f44dcfb1a", [:mix], [{:castore, "~> 0.1 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: false]}, {:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 1.3", [hex: :mint, repo: "hexpm", optional: false]}, {:nimble_options, "~> 0.4 or ~> 1.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 0.2.6 or ~> 1.0", [hex: :nimble_pool, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "f660174c4d519e5fec629016054d60edd822cdfe2b7270836739ac2f97735ec5"},