Skip to content

Bring installers up to date with Phoenix 1.8.13 - #9

Open
joshprice wants to merge 10 commits into
mainfrom
chore/phoenix-1.8.13-update
Open

joshprice wants to merge 10 commits into
mainfrom
chore/phoenix-1.8.13-update

Conversation

@joshprice

Copy link
Copy Markdown
Member

Updates the installers to match Phoenix 1.8.13 (from 1.8.4-era output) and moves every generated dependency to its current release.

Scope was derived by diffing the phx_new 1.8.4 and 1.8.13 templates, so the structural changes mirror upstream exactly. Version pins deliberately go past what phx.new ships where upstream lags.

Dependency versions

Dep Before After
phoenix ~> 1.7 ~> 1.8 1.8.13
phoenix_live_view ~> 1.0 ~> 1.2 1.2.11
phoenix_html ~> 4.1 ~> 4.3
phoenix_live_dashboard ~> 0.8 ~> 0.9 phx.new pins 0.8.3
ecto_sql ~> 3.10 ~> 3.14 phx.new pins 3.13
gettext ~> 0.26 ~> 1.0 major bump
swoosh ~> 1.5 ~> 1.28 phx.new pins 1.16
bandit ~> 1.5 ~> 1.12
dns_cluster ~> 0.1 ~> 0.3 phx.new pins 0.2.0
telemetry_metrics ~> 1.0 ~> 1.2
telemetry_poller ~> 1.0 ~> 1.3
tailwind ~> 0.3 ~> 0.5
tailwind binary 4.1.12 4.3.3 phx.new pins 4.3.0
esbuild binary 0.25.4 0.28.2
daisyUI 5.5.19 5.7.37 phx.new pins 5.5.20

Where a pin goes beyond phx.new, compatibility was checked against hex metadata — e.g. phoenix_live_dashboard 0.9.1 only requires phoenix_live_view ~> 1.0, and swoosh's req ~> 0.6 constraint admits req 0.7.x.

Dependencies phx.new generates that were missing entirely: phoenix_ecto ~> 4.7 (changeset form handling), jason ~> 1.4 (asserted by the acceptance test but never generated), req ~> 0.7 (Swoosh API client), and lazy_html (LiveView 1.2 test helpers).

Behavioural changes

daisyUI is now a dependency, not vendored. Upstream dropped assets/vendor/daisyui.js / daisyui-theme.js in favour of a sparse git dep. @plugin paths move to daisyui/packages/bundle/… and the tailwind config gains NODE_PATH so the build resolves it. Installing no longer performs its own network fetch.

Colocated CSS support (new). Phoenix.LiveView.ColocatedCSS extracts styles into _build/<env>/phoenix-colocated/<app>; nothing wired that up, so colocated styles were silently dropped from the build. Adds assets/css/phx-colocated.css and the root_tag_attribute: "phx-r" config. Gated on --live.

live_reload moves to runtime.exs under a config_env() == :dev guard. Igniter.Project.Config.configure/6 can't express a conditional block, so the task now inserts via the AST ahead of the existing prod block, and is a no-op on re-run.

Bug fixes

force_ssl: exclude was generated as a sibling of force_ssl rather than nested inside it. Phoenix ignores it at the top level, so excluded hosts were still force-redirected to https.

Flash disconnect handlers: JS.remove_attribute/2 defaults to the event target, which isn't the flash element — the client/server error flashes never un-hid on disconnect. Now passes to: explicitly.

Theme switching: choosing "system" removed data-theme entirely, so the toggle couldn't distinguish system from light and the page stopped following the OS theme after load. "system" now resolves to a concrete theme and records its origin in data-theme-source, with a prefers-color-scheme listener keeping it current.

Toolchain

.tool-versions moves to Erlang 29.0.6 / Elixir 1.20.4. The previous pin (erlang 27.2) hits an OTP ssl regression that rejects hex.pm's certificate chain with key_usage_mismatch, breaking mix deps.get and mix local.hex outright. Confirmed by testing the handshake across all locally installed OTP releases: 26.x, 27.0–27.1.2 and 27.3+ connect; only 27.2 and 27.2.1 fail. Fixed upstream in 27.3.

Reviewers: this changes the project-wide toolchain pin, so flag it if anything else depends on 27.2 specifically.

Verification

mix test --include acceptance188 passed, up from 174, with the acceptance suite now running against real phx.new 1.8.13. mix format --check-formatted, mix credo and mix hex.audit all clean.

New coverage accompanies each behavioural change, including the four previously-missing deps, colocated CSS paths, live_reload placement and idempotency, and the daisyUI dep. The force_ssl test was verified to fail against the old output before being committed — the obvious content =~ "force_ssl:" assertion passes either way.

OTP 27.2 and 27.2.1 reject hex.pm's certificate chain with
`key_usage_mismatch`, breaking `mix deps.get` and `mix local.hex`:

    TLS client: ... Fatal - Unsupported Certificate
    {key_usage_mismatch,
     {{'Extension',{2,5,29,15},true,[keyCertSign,cRLSign]},
      {'Extension',{2,5,29,37},false,[{1,3,6,1,5,5,7,3,1},
                                      {1,3,6,1,5,5,7,3,2}]}}}

The `ssl` app cross-checks a CA certificate's extKeyUsage against its
keyUsage and wrongly rejects a CA cert carrying both
`keyUsage = [keyCertSign, cRLSign]` and an extKeyUsage of
serverAuth/clientAuth. hex.pm's chain contains such a cert. OpenSSL
does not apply this check to CA certs, which is why `curl` works.

Verified across locally installed OTP releases: 26.x, 27.0-27.1.2 and
27.3+ all connect; only 27.2 and 27.2.1 fail. Fixed upstream in 27.3.

Move to the current releases rather than the minimum viable bump.
No API changes were required; the full suite passes unchanged (174 tests).
Track the latest release of each dependency rather than the pins
`phx.new` ships, which lag upstream in several places.

Version bumps:
- phoenix              ~> 1.7  -> ~> 1.8   (1.8.13)
- phoenix_live_view    ~> 1.0  -> ~> 1.2   (1.2.11)
- phoenix_html         ~> 4.1  -> ~> 4.3   (4.3.0)
- phoenix_live_dashboard ~> 0.8 -> ~> 0.9  (0.9.1, phx.new still pins 0.8.3)
- ecto_sql             ~> 3.10 -> ~> 3.14  (phx.new pins 3.13)
- gettext              ~> 0.26 -> ~> 1.0   (1.0.2)
- swoosh               ~> 1.5  -> ~> 1.28  (phx.new pins 1.16)
- bandit               ~> 1.5  -> ~> 1.12  (1.12.5)
- dns_cluster          ~> 0.1  -> ~> 0.3   (phx.new pins 0.2.0)
- telemetry_metrics    ~> 1.0  -> ~> 1.2   (1.2.0)
- telemetry_poller     ~> 1.0  -> ~> 1.3   (1.3.0)
- tailwind             ~> 0.3  -> ~> 0.5   (0.5.1)
- tailwind binary      4.1.12  -> 4.3.3    (phx.new pins 4.3.0)
- esbuild binary       0.25.4  -> 0.28.2
- phx_new (test dep)   ~> 1.7  -> ~> 1.8

Dependencies `phx.new` generates that were missing entirely:
- phoenix_ecto ~> 4.7 — Ecto/Phoenix integration, needed for changeset
  form handling
- jason ~> 1.4 — asserted by the acceptance test but never generated
- req ~> 0.7 — the Swoosh API client (phx.new pins 0.5; swoosh's own
  `req ~> 0.6` constraint admits 0.7)
- lazy_html >= 0.1.0, only: :test — LiveView 1.2 test helpers

Compatibility verified against hex metadata: phoenix_live_dashboard
0.9.1 only requires phoenix_live_view ~> 1.0, so its phx.new pin is lag
rather than a constraint.
`exclude` is an option of `force_ssl`, not a sibling endpoint key.
Phoenix ignores it when it sits at the top level, so excluded hosts
were still force-redirected to https.

Generated config changes from:

    force_ssl: [rewrite_on: [:x_forwarded_proto]],
    exclude: [hosts: ["localhost", "127.0.0.1"]]

to:

    force_ssl: [
      rewrite_on: [:x_forwarded_proto],
      exclude: [
        # paths: ["/health"],
        hosts: ["localhost", "127.0.0.1"]
      ]
    ]

Matches the same correction made upstream in phx.new. The existing test
only asserted that `force_ssl:` appeared, which passed either way; the
new test asserts the nesting and fails against the previous output.
Transitive refresh from the igniter update and dependency fetches. All
entries are dev/test tooling; no generated-output dependency changes.

    credo          1.7.16 -> 1.7.19
    decimal         2.4.1 -> 3.1.1
    dialyxir        1.4.7 -> 1.4.8
    doctor         0.22.0 -> 0.23.0
    earmark_parser 1.4.44 -> 1.4.46
    erlex           0.2.8 -> 0.2.9
    ex_doc         0.40.0 -> 0.40.4
    git_ops         2.9.2 -> 2.12.3
    makeup          1.2.1 -> 1.2.2
    makeup_erlang   1.0.3 -> 1.1.0
    yaml_elixir    2.12.1 -> 2.12.2

`mix hex.audit` reports no retired or advisory packages.
Phoenix 1.8.5 moved the `live_reload` endpoint config out of
`config/dev.exs` and into `config/runtime.exs`, guarded by
`config_env() == :dev`. Follow suit.

`Igniter.Project.Config.configure/6` writes top-level config calls and
cannot express a conditional block, so the task now updates
`config/runtime.exs` directly via the AST: it inserts the dev block
ahead of the existing `config_env() == :prod` block to match phx.new's
ordering, falling back to appending when no prod block is present.

Re-running the task is a no-op once `live_reload:` is present, and
`:newlines` metadata on the inserted node keeps a blank line separating
it from the config above.

Tests now assert the config lands in runtime.exs behind the dev guard,
that it no longer appears in dev.exs, that the dev block precedes the
prod block, and that a second run does not duplicate it.
Phoenix 1.8.10 stopped vendoring `assets/vendor/daisyui.js` and
`assets/vendor/daisyui-theme.js`, shipping daisyUI as a sparse git
dependency instead. Follow suit.

- add `{:daisyui, github: "saadeghi/daisyui", sparse: "packages/bundle"}`
  at v5.7.37 (phx.new pins v5.5.20; the bundle layout is unchanged)
- point `@plugin` at `daisyui/packages/bundle/daisyui` and
  `daisyui/packages/bundle/daisyui-theme`
- set `NODE_PATH` on the tailwind config so the CSS build resolves the
  plugin out of `deps/`

Removes `download_vendor_file/2`, `fetch_and_create_vendor_file/3` and
the `:httpc` helper, so installing no longer performs a network fetch of
its own or needs a fallback notice when GitHub is unreachable.
`Phoenix.LiveView.ColocatedCSS` extracts styles from components into
`_build/<env>/phoenix-colocated/<app>`. Nothing in the installer wired
that up, so colocated styles were silently dropped from the build.

`phx.install.live` now:
- creates `assets/css/phx-colocated.css` importing the generated
  stylesheet and adding an `@source` for the build directory so Tailwind
  picks up changes in dev
- appends its `@import` to `app.css`, following the per-task CSS file
  convention
- configures `root_tag_attribute: "phx-r"`, the attribute LiveView sets
  on root tags for colocated CSS to key off

The `@import` resolves through the `NODE_PATH` added to the tailwind
config alongside the daisyUI dependency change.

Gated on `--live`, so non-LiveView installs are unaffected.
Three corrections made upstream between Phoenix 1.8.4 and 1.8.13.

Flash disconnect handlers: `JS.remove_attribute/2` targets the event
target by default, which is not the flash element, so the attribute was
never removed and the client/server error flashes stayed hidden on
disconnect. Pass the selector explicitly via `to:`.

Theme handling: selecting "system" removed `data-theme` entirely, which
left the toggle unable to distinguish "system" from "light" and meant
the page did not follow the OS theme after load. "system" now resolves
to a concrete theme, records its origin in `data-theme-source`, and a
`prefers-color-scheme` listener keeps it current while the source stays
"system". The toggle gained the matching
`[[data-theme-source=system]_&]:!left-0` variant.

Documentation links move to per-package hexdocs subdomains
(`hexdocs.pm/phoenix/x` -> `phoenix.hexdocs.pm/x`).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant