diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6685cb92c2..b5f606694d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,17 +13,8 @@ jobs: strategy: matrix: include: - - elixir: 1.11.4 - otp: 24.3 - - - elixir: 1.12.3 - otp: 24.3 - - - elixir: 1.14.5 - otp: 25.3.2.9 - - - elixir: 1.15.x - otp: 25.x + - elixir: 1.15.8 + otp: 24.3.4.17 - elixir: 1.17.3 otp: 27.2 @@ -33,43 +24,43 @@ jobs: runs-on: ubuntu-20.04 steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Set up Elixir - uses: erlef/setup-beam@v1 - with: - elixir-version: ${{ matrix.elixir }} - otp-version: ${{ matrix.otp }} - - - name: Restore deps and _build cache - uses: actions/cache@v4 - with: - path: | - deps - _build - key: deps-${{ runner.os }}-${{ matrix.otp }}-${{ matrix.elixir }}-${{ hashFiles('**/mix.lock') }} - restore-keys: | - deps-${{ runner.os }}-${{ matrix.otp }}-${{ matrix.elixir }} - - - name: Install dependencies - run: mix deps.get --only test - - - name: Remove compiled application files - run: mix clean - - - name: Compile & lint dependencies - run: mix compile --warnings-as-errors - if: ${{ matrix.lint }} - - - name: Run tests - run: mix test - - - name: Run installer test - run: | - cd installer - mix test - if: ${{ matrix.installer }} + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up Elixir + uses: erlef/setup-beam@v1 + with: + elixir-version: ${{ matrix.elixir }} + otp-version: ${{ matrix.otp }} + + - name: Restore deps and _build cache + uses: actions/cache@v4 + with: + path: | + deps + _build + key: deps-${{ runner.os }}-${{ matrix.otp }}-${{ matrix.elixir }}-${{ hashFiles('**/mix.lock') }} + restore-keys: | + deps-${{ runner.os }}-${{ matrix.otp }}-${{ matrix.elixir }} + + - name: Install dependencies + run: mix deps.get --only test + + - name: Remove compiled application files + run: mix clean + + - name: Compile & lint dependencies + run: mix compile --warnings-as-errors + if: ${{ matrix.lint }} + + - name: Run tests + run: mix test + + - name: Run installer test + run: | + cd installer + mix test + if: ${{ matrix.installer }} npm_test: name: npm test diff --git a/lib/phoenix/code_reloader/server.ex b/lib/phoenix/code_reloader/server.ex index 49169f97dc..66913c9154 100644 --- a/lib/phoenix/code_reloader/server.ex +++ b/lib/phoenix/code_reloader/server.ex @@ -182,15 +182,6 @@ defmodule Phoenix.CodeReloader.Server do end end - if Version.match?(System.version(), "< 1.15.0-dev") do - defp purge_protocols(path) do - purge_modules(path) - Code.delete_path(path) - end - else - defp purge_protocols(_path), do: :ok - end - if Version.match?(System.version(), ">= 1.18.0-dev") do defp warn_missing_mix_listener do if Mix.Project.get() != Phoenix.MixProject do @@ -226,11 +217,6 @@ defmodule Phoenix.CodeReloader.Server do config = Mix.Project.config() path = Mix.Project.consolidation_path(config) - # TODO: Remove this conditional when requiring Elixir v1.15+ - if config[:consolidate_protocols] do - purge_protocols(path) - end - mix_compile_deps( Mix.Dep.cached(), apps_to_reload, @@ -364,7 +350,7 @@ defmodule Phoenix.CodeReloader.Server do exit({:shutdown, 1}) result == :ok && config[:consolidate_protocols] -> - # TODO: Calling compile.protocols may no longer be required from Elixir v1.18 + # TODO: Calling compile.protocols is no longer be required from Elixir v1.19 Mix.Task.reenable("compile.protocols") Mix.Task.run("compile.protocols", []) :ok diff --git a/lib/phoenix/router.ex b/lib/phoenix/router.ex index 84b5afd793..35d869e0c3 100644 --- a/lib/phoenix/router.ex +++ b/lib/phoenix/router.ex @@ -523,15 +523,7 @@ defmodule Phoenix.Router do """ def call(conn, _opts) do %{method: method, path_info: path_info, host: host} = conn = prepare(conn) - - # TODO: Remove try/catch on Elixir v1.13 as decode no longer raises - decoded = - try do - Enum.map(path_info, &URI.decode/1) - rescue - ArgumentError -> - raise MalformedURIError, "malformed URI path: #{inspect(conn.request_path)}" - end + decoded = Enum.map(path_info, &URI.decode/1) case __match_route__(decoded, method, host) do {metadata, prepare, pipeline, plug_opts} -> diff --git a/lib/phoenix/socket/pool_supervisor.ex b/lib/phoenix/socket/pool_supervisor.ex index a3297867fc..80cb8b510f 100644 --- a/lib/phoenix/socket/pool_supervisor.ex +++ b/lib/phoenix/socket/pool_supervisor.ex @@ -45,7 +45,6 @@ defmodule Phoenix.Socket.PoolSupervisor do @impl true def init({endpoint, name, partitions}) do - # TODO: Use persistent term on Elixir v1.12+ ref = :ets.new(name, [:public, read_concurrency: true]) :ets.insert(ref, {:partitions, partitions}) Phoenix.Config.permanent(endpoint, {:socket, name}, ref) @@ -115,8 +114,7 @@ defmodule Phoenix.Socket.PoolDrainer do end for {pids, index} <- - collection |> Stream.concat() |> Stream.chunk_every(size) |> Stream.with_index(1) do - + collection |> Stream.concat() |> Stream.chunk_every(size) |> Stream.with_index(1) do spawn(fn -> for pid <- pids do send(pid, %Phoenix.Socket.Broadcast{event: "phx_drain"}) diff --git a/mix.exs b/mix.exs index 759e8076c4..d1a83cf1d1 100644 --- a/mix.exs +++ b/mix.exs @@ -14,7 +14,7 @@ defmodule Phoenix.MixProject do # If the elixir requirement is updated, we need to make the installer # use at least the minimum requirement used here. Although often the # installer is ahead of Phoenix itself. - @elixir_requirement "~> 1.11" + @elixir_requirement "~> 1.15" def project do [ @@ -86,9 +86,9 @@ defmodule Phoenix.MixProject do {:phoenix_template, "~> 1.0"}, {:websock_adapter, "~> 0.5.3"}, - # TODO drop phoenix_view as an optional dependency in Phoenix v2.0 + # TODO Drop phoenix_view as an optional dependency in Phoenix v2.0 {:phoenix_view, "~> 2.0", optional: true}, - # TODO drop castore when we require OTP 25+ + # TODO Drop castore when we require OTP 25+ / Elixir v1.17+ {:castore, ">= 0.0.0"}, # Optional deps