Skip to content

Commit

Permalink
Merge branch 'main' into reserved-app-names
Browse files Browse the repository at this point in the history
  • Loading branch information
almirsarajcic committed Dec 23, 2024
2 parents 7a410e4 + 61cbfeb commit 2b41237
Show file tree
Hide file tree
Showing 8 changed files with 37 additions and 252 deletions.
5 changes: 4 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,11 @@ jobs:
- elixir: 1.14.5
otp: 25.3.2.9

- elixir: 1.15.x
otp: 25.x

- elixir: 1.17.3
otp: 27.1
otp: 27.2
lint: true
installer: true

Expand Down
242 changes: 3 additions & 239 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,241 +1,5 @@
# Changelog for v1.7
# Changelog for v1.8

See the [upgrade guide](https://gist.github.com/chrismccord/00a6ea2a96bc57df0cce526bd20af8a7) to upgrade from Phoenix 1.6.x.
## v1.7

Phoenix v1.7 requires Elixir v1.11+ & Erlang v22.1+.

## Introduction of Verified Routes

Phoenix 1.7 includes a new `Phoenix.VerifiedRoutes` feature which provides `~p`
for route generation with compile-time verification.

Use of the `sigil_p` macro allows paths and URLs throughout your
application to be compile-time verified against your Phoenix router(s).
For example the following path and URL usages:

<.link href={~p"/sessions/new"} method="post">Log in</.link>

redirect(to: url(~p"/posts/#{post}"))

Will be verified against your standard `Phoenix.Router` definitions:

get "/posts/:post_id", PostController, :show
post "/sessions/new", SessionController, :create

Unmatched routes will issue compiler warnings:

warning: no route path for AppWeb.Router matches "/postz/#{post}"
lib/app_web/controllers/post_controller.ex:100: AppWeb.PostController.show/2

*Note: Elixir v1.14+ is required for comprehensive warnings. Older versions
will work properly and warn on new compilations, but changes to the router file
will not issue new warnings.*

This feature replaces the `Helpers` module generated in your Phoenix router, but helpers
will continue to work and be generated. You can disable router helpers by passing the
`helpers: false` option to `use Phoenix.Router`.

## phx.new revamp

The `phx.new` application generator has been improved to rely on function components for
both Controller and LiveView rendering, ultimately simplifying the rendering stack of
Phoenix applications and providing better reuse.

New applications come with a collection of well-documented and accessible core components,
styled with Tailwind CSS by default. You can opt-out of Tailwind CSS with the `--no-tailwind`
flag (the Tailwind CSS classes are kept in the generated components as reference for
future styling).

## 1.7.14 (2024-06-18)

### Bug fixes
* Revert "Add `follow_redirect/2` to Phoenix.ConnTest" (#5797) as this conflicts with `follow_redirect/2` in LiveView, which is imported with ConnTest by default

## 1.7.13 (2024-06-18)

### Bug fixes
* Fix Elixir 1.17 warning in Cowboy2Adapter
* Fix verified routes emitting diagnostics without file and position

### JavaScript Client Bug Fixes
* Fix error when `sessionStorage` is not available on global namespace

### Enhancements
* Add `follow_redirect/2` to Phoenix.ConnTest
* Use LiveView 1.0.0-rc for newly generated applications
* Use new `Phoenix.Component.used_input?` for form errors in generated `core_components.ex`
* Allow `mix ecto.setup` from the umbrella root
* Bump Endpoint static cache manifest on `config_change` callback

## 1.7.12 (2024-04-11)

### JavaScript Client Bug Fixes
* Fix all unjoined channels from being removed from the socket when channel leave is called on any single unjoined channel instance

### Enhancements
* [phx.gen.auth] Add enhanced session fixation protection.
For applications which previously used `phx.gen.auth`, the following line can be added to the `renew_session` function in the auth module:

```diff
defp renew_session(conn) do
+ delete_csrf_token()

conn
|> configure_session(renew: true)
|> clear_session()
```

*Note*: because the session id is in a http-only cookie by default, the only way to perform this attack prior to this change is if your application was already vulnerable to an XSS attack, which itself grants more escalated "privileges” than the CSRF fixation.

### JavaScript Client Enhancements
* Only memorize longpoll fallback for browser session if WebSocket never had a successful connection

## 1.7.11 (2024-02-01)

### Enhancements
* [phx.new] Default to the [Bandit webserver](https://github.com/mtrudel/bandit) for newly generated applications
* [phx.new] Enable longpoll transport by default and auto fallback when websocket fails for newly generated applications

### JavaScript Client Enhancements
* Support new `longPollFallbackMs` option to auto fallback when websocket fails to connect
* Support new `debug` option to enable verbose logging

### Deprecations
* Deprecate the `c:init/2` callback in endpoints in favor of `config/runtime.exs` or in favor of `{Phoenix.Endpoint, options}`

## 1.7.10 (2023-11-03)

### Bug fixes
* [phx.new] Fix `CoreComponents.flash` generating incorrect id's causing flash messages to fail to be closed when clicked

### Enhancements
* [Phoenix.Endpoint] Support dynamic port for `Endpoint.url/0`

## 1.7.9 (2023-10-11)

### Bug fixes
* [Phoenix.CodeReloader] - Fix error in code reloader causing compilation errors
* [phx.new] – fix LiveView debug heex configuration being generated when `--no-html` pas passed

## 1.7.8 (2023-10-09)

### Bug fixes
* [Phoenix.ChannelTest] Stringify lists when pushing data
* [Phoenix.Controller] Fix filename when sending downloads with non-ascii names
* [Phoenix.CodeReloader] Remove duplicate warnings on recent Elixir versions
* [Phoenix.CodeReloader] Do not crash code reloader if file information is missing from diagnostic
* [Phoenix.Logger] Do not crash when status is atom
* [phx.gen.release] Fix `mix phx.gen.release --docker` failing with `:http_util` error on Elixir v1.15
* [phx.gen.*] Skip map inputs in generated forms as there is no trivial matching input
* [phx.new] Fix tailwind/esbuild config and paths in umbrella projects
* [phx.new] Do not render `th` for actions if actions are empty

### Enhancements
* [Phoenix] Allow latest `plug_crypto`
* [Phoenix.Endpoint] Support dynamic socket drainer configuration
* [Phoenix.Logger] Change socket serializer/version logs to warning
* [Phoenix.VerifiedRoutes] Add support for static resources with fragments in `~p`
* [phx.gen.schema] Support `--repo` and `--migration-dir` flags
* [phx.new] Allow `<.input type="checkbox">` without `value` attr in core components
* [phx.new] Allow UTC datetimes in the generators
* [phx.new] Automatically migrate when release starts when using sqlite 3
* [phx.new] Allow ID to be assigned in flash component
* [phx.new] Add `--adapter` flag for generating application with bandit
* [phx.new] Include DNSCluster for simple clustering
* [phx.routes] Support `--method` option

## 1.7.7 (2023-07-10)

### Enhancements
* Support incoming binary payloads to channels over longpoll transport

## 1.7.6 (2023-06-16)

### Bug Fixes
* Support websock_adapter 0.5.3

### Enhancements
* Allow using Phoenix.ChannelTest socket/connect in another process

## 1.7.5 (2023-06-15)

### Bug Fixes
* Fix LongPoll error when draining connections

## 1.7.4 (2023-06-15)

### Bug Fixes
* Fix the WebSocket draining sending incorrect close code when draining causing LiveViews to reload the page instead of reconnecting

## 1.7.3 (2023-05-30)

### Enhancements
* Use LiveView 0.19 for new apps

### Bug Fixes
* Fix compilation error page on plug debugger showing obscure error when app fails to compile
* Fix warnings being printed twice in route verification

## 1.7.2 (2023-03-20)

### Enhancements
* [Endpoint] Add socket draining for batched and orchestrated Channel/LiveView socket shutdown
* [code reloader] Improve the compilation error page to remove horizontal scrolling and include all warnings and errors from compilation
* [phx.new] Support the `--no-tailwind` and `--no-esbuild` flags
* [phx.new] Move heroicons to assets/vendor
* [phx.new] Simplify core modal to use the new JS.exec instruction to reduce footprint
* [sockets] Allow custom csrf_token_keys in WebSockets

## 1.7.1 (2023-03-02)

### Enhancements
* [phx.new] Embed heroicons in app.css bundle to optimize usage

## 1.7.0 (2023-02-24)

### Bug Fixes
* Fix race conditions in the longpoll transport by batching messages

## 1.7.0-rc.3 (2023-02-15)

### Enhancements
* Use stream based collections for `phx.gen.live` generators
* Update `phx.gen.live` generators to use `Phoenix.Component.to_form`

## 1.7.0-rc.2 (2023-01-13)

### Bug Fixes
* [Router] Fix routing bug causing incorrect matching order on similar routes
* [phx.new] Fix installation hanging in some cases

## 1.7.0-rc.1 (2023-01-06)

### Enhancements
* Raise if using verified routes outside of functions
* Add tailwind.install/esbuild.install to mix setup

### Bug Fixes
* [Presence] fix task shutdown match causing occasional presence errors
* [VerifiedRoutes] Fix expansion causing more compile-time deps than necessary
* [phx.gen.auth] Add password inputs to password reset edit form
* [phx.gen.embedded] Fixes missing :references generation to phx.gen.embedded
* Fix textarea rendering in core components
* Halt all sockets on intercept to fix longpoll response already sent error

## 1.7.0-rc.0 (2022-11-07)

### Deprecations
* `Phoenix.Controller.get_flash` has been deprecated in favor of the new `Phoenix.Flash` module, which provides unified flash access

### Enhancements
* [Router] Add `Phoenix.VerifiedRoutes` for `~p`-based route generation with compile-time verification.
* [Router] Support `helpers: false` to `use Phoenix.Router` to disable helper generation
* [Router] Add `--info [url]` switch to `phx.routes` to get route information about a url/path
* [Flash] Add `Phoenix.Flash` for unified flash access

### JavaScript Client Bug Fixes
* Fix heartbeat being sent after disconnect and causing abnormal disconnects

## v1.6

The CHANGELOG for v1.6 releases can be found in the [v1.6 branch](https://github.com/phoenixframework/phoenix/blob/v1.6/CHANGELOG.md).
The CHANGELOG for v1.7 releases can be found in the [v1.7 branch](https://github.com/phoenixframework/phoenix/blob/v1.7/CHANGELOG.md).
4 changes: 2 additions & 2 deletions guides/contexts.md
Original file line number Diff line number Diff line change
Expand Up @@ -957,7 +957,7 @@ Next we can create the template at `lib/hello_web/controllers/cart_html/show.htm
<.back navigate={~p"/products"}>Back to products</.back>
```

We started by showing the empty cart message if our preloaded `cart.items` is empty. If we have items, we use the `simple_form` component provided by our `HelloWeb.CoreComponents` to take our cart changeset that we assigned in the `CartController.show/2` action and create a form which maps to our cart controller `update/2` action. Within the form, we use the [`inputs_for`](`Phoenix.Component.inputs_for/1`) component to render inputs for the nested cart items. This will allow us to map item inputs back together when the form is submitted. Next, we display a number input for the item quantity and label it with the product title. We finish the item form by converting the item price to string. We haven't written the `ShoppingCart.total_item_price/1` function yet, but again we employed the idea of clear, descriptive public interfaces for our contexts. After rendering inputs for all the cart items, we show an "update cart" submit button, along with the total price of the entire cart. This is accomplished with another new `ShoppingCart.total_cart_price/1` function which we'll implement in a moment. Finally, we added a `back` component to go back to our products page.
We started by showing the empty cart message if our preloaded `cart.items` is empty. If we have items, we use the `simple_form` component provided by our `HelloWeb.CoreComponents` to take our cart changeset that we assigned in the `CartController.show/2` action and create a form which maps to our cart controller `update/2` action. Within the form, we use the [`inputs_for`](https://hexdocs.pm/phoenix_live_view/Phoenix.Component.html#inputs_for/1) component to render inputs for the nested cart items. This will allow us to map item inputs back together when the form is submitted. Next, we display a number input for the item quantity and label it with the product title. We finish the item form by converting the item price to string. We haven't written the `ShoppingCart.total_item_price/1` function yet, but again we employed the idea of clear, descriptive public interfaces for our contexts. After rendering inputs for all the cart items, we show an "update cart" submit button, along with the total price of the entire cart. This is accomplished with another new `ShoppingCart.total_cart_price/1` function which we'll implement in a moment. Finally, we added a `back` component to go back to our products page.

We're almost ready to try out our cart page, but first we need to implement our new currency calculation functions. Open up your shopping cart context at `lib/hello/shopping_cart.ex` and add these new functions:

Expand Down Expand Up @@ -1027,7 +1027,7 @@ Head back over to your shopping cart context in `lib/hello/shopping_cart.ex` and
end
```

We started much like how our out-of-the-box code started – we take the cart struct and cast the user input to a cart changeset, except this time we use `Ecto.Changeset.cast_assoc/3` to cast the nested item data into `CartItem` changesets. Remember the [`<.inputs_for />`](`Phoenix.Component.inputs_for/1`) call in our cart form template? That hidden ID data is what allows Ecto's `cast_assoc` to map item data back to existing item associations in the cart. Next we use `Ecto.Multi.new/0`, which you may not have seen before. Ecto's `Multi` is a feature that allows lazily defining a chain of named operations to eventually execute inside a database transaction. Each operation in the multi chain receives the values from the previous steps and executes until a failed step is encountered. When an operation fails, the transaction is rolled back and an error is returned, otherwise the transaction is committed.
We started much like how our out-of-the-box code started – we take the cart struct and cast the user input to a cart changeset, except this time we use `Ecto.Changeset.cast_assoc/3` to cast the nested item data into `CartItem` changesets. Remember the [`<.inputs_for />`](https://hexdocs.pm/phoenix_live_view/Phoenix.Component.html#inputs_for/1) call in our cart form template? That hidden ID data is what allows Ecto's `cast_assoc` to map item data back to existing item associations in the cart. Next we use `Ecto.Multi.new/0`, which you may not have seen before. Ecto's `Multi` is a feature that allows lazily defining a chain of named operations to eventually execute inside a database transaction. Each operation in the multi chain receives the values from the previous steps and executes until a failed step is encountered. When an operation fails, the transaction is rolled back and an error is returned, otherwise the transaction is committed.

For our multi operations, we start by issuing an update of our cart, which we named `:cart`. After the cart update is issued, we perform a multi `delete_all` operation, which takes the updated cart and applies our zero-quantity logic. We prune any items in the cart with zero quantity by returning an ecto query that finds all cart items for this cart with an empty quantity. Calling `Repo.transaction/1` with our multi will execute the operations in a new transaction and we return the success or failure result to the caller just like the original function.

Expand Down
17 changes: 14 additions & 3 deletions installer/lib/phx_new/generator.ex
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,8 @@ defmodule Phx.New.Generator do
{adapter_app, adapter_module, adapter_config} =
get_ecto_adapter(db, String.downcase(project.app), project.app_mod)

{web_adapter_app, web_adapter_vsn, web_adapter_module, web_adapter_docs} = get_web_adapter(web_adapter)
{web_adapter_app, web_adapter_vsn, web_adapter_module, web_adapter_docs} =
get_web_adapter(web_adapter)

pubsub_server = get_pubsub_server(project.app_mod)

Expand Down Expand Up @@ -304,8 +305,16 @@ defmodule Phx.New.Generator do
Mix.raise("Unknown database #{inspect(db)}")
end

defp get_web_adapter("cowboy"), do: {:plug_cowboy, "~> 2.7", Phoenix.Endpoint.Cowboy2Adapter, "https://hexdocs.pm/plug_cowboy/Plug.Cowboy.html"}
defp get_web_adapter("bandit"), do: {:bandit, "~> 1.5", Bandit.PhoenixAdapter, "https://hexdocs.pm/bandit/Bandit.html#t:options/0"}
defp get_web_adapter("cowboy"),
do:
{:plug_cowboy, "~> 2.7", Phoenix.Endpoint.Cowboy2Adapter,
"https://hexdocs.pm/plug_cowboy/Plug.Cowboy.html"}

defp get_web_adapter("bandit"),
do:
{:bandit, "~> 1.5", Bandit.PhoenixAdapter,
"https://hexdocs.pm/bandit/Bandit.html#t:options/0"}

defp get_web_adapter(other), do: Mix.raise("Unknown web adapter #{inspect(other)}")

defp fs_db_config(app, module) do
Expand Down Expand Up @@ -380,6 +389,8 @@ defmodule Phx.New.Generator do
# ssl: true,
url: database_url,
pool_size: String.to_integer(System.get_env("POOL_SIZE") || "10"),
# For machines with several cores, consider starting multiple pools of `pool_size`
# pool_count: 4,
socket_options: maybe_ipv6
"""
]
Expand Down
2 changes: 1 addition & 1 deletion installer/mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ end
defmodule Phx.New.MixProject do
use Mix.Project

@version "1.7.14"
@version "1.8.0-dev"
@scm_url "https://github.com/phoenixframework/phoenix"

# If the elixir requirement is updated, we need to update:
Expand Down
2 changes: 1 addition & 1 deletion lib/phoenix/endpoint.ex
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ defmodule Phoenix.Endpoint do
instances of the same app at the same time with code reloading in
development, as they will race each other and only one will effectively
recompile the files. In such cases, tweak your config files so code
reloading is enabled in only one of the apps or set the MIX_BUILD
reloading is enabled in only one of the apps or set the `MIX_BUILD_PATH`
environment variable to give them distinct build directories
* `:debug_errors` - when `true`, uses `Plug.Debugger` functionality for
Expand Down
13 changes: 9 additions & 4 deletions mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ defmodule Phoenix.MixProject do
end
end

@version "1.7.14"
@version "1.8.0-dev"
@scm_url "https://github.com/phoenixframework/phoenix"

# If the elixir requirement is updated, we need to make the installer
Expand All @@ -23,7 +23,6 @@ defmodule Phoenix.MixProject do
elixir: @elixir_requirement,
deps: deps(),
package: package(),
preferred_cli_env: [docs: :docs],
consolidate_protocols: Mix.env() != :test,
xref: [
exclude: [
Expand All @@ -47,6 +46,12 @@ defmodule Phoenix.MixProject do
]
end

def cli do
[
preferred_envs: [docs: :docs]
]
end

defp elixirc_paths(:docs), do: ["lib", "installer/lib"]
defp elixirc_paths(_), do: ["lib"]

Expand Down Expand Up @@ -124,12 +129,12 @@ defmodule Phoenix.MixProject do
main: "overview",
logo: "logo.png",
extra_section: "GUIDES",
assets: "guides/assets",
assets: %{"guides/assets" => "assets"},
formatters: ["html", "epub"],
groups_for_modules: groups_for_modules(),
extras: extras(),
groups_for_extras: groups_for_extras(),
groups_for_functions: [
groups_for_docs: [
Reflection: &(&1[:type] == :reflection)
],
skip_undefined_reference_warnings_on: ["CHANGELOG.md"]
Expand Down
4 changes: 3 additions & 1 deletion priv/templates/phx.gen.auth/schema.ex
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,9 @@ defmodule <%= inspect schema.module %> do
defp validate_email(changeset, opts) do
changeset
|> validate_required([:email])
|> validate_format(:email, ~r/^[^\s]+@[^\s]+$/, message: "must have the @ sign and no spaces")
|> validate_format(:email, ~r/^[^@,;\s]+@[^@,;\s]+$/,
message: "must have the @ sign and no spaces"
)
|> validate_length(:email, max: 160)
|> maybe_validate_unique_email(opts)
end
Expand Down

0 comments on commit 2b41237

Please sign in to comment.