Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
65d8262
Bump elixir version in asdf config
zoldar Jun 8, 2026
2f532cb
Remove unused module requires
zoldar Jun 8, 2026
a80db02
Avoid generating function body inside `defprotocol`
zoldar Jun 8, 2026
990e251
unused require fixup
zoldar Jun 8, 2026
fce1122
Don't branch on always-true expression
zoldar Jun 8, 2026
df8e4bf
Fix usages of :erlang.phash2 dialyzer trick
zoldar Jun 8, 2026
474d14a
Don't check for expression which is always true
zoldar Jun 8, 2026
2c06bed
Fix faulty `repo.config` -> `repo.config()`
zoldar Jun 8, 2026
d4ecdff
Avoid using `Phoenix.Component` twice
zoldar Jun 8, 2026
8008f97
Bump ExMoney
zoldar Jun 8, 2026
4d844d7
Add `logger_backends` dependency
zoldar Jun 8, 2026
4f9f5c6
Use `LoggerBackends.add` instead of `Logger.add_backend`
zoldar Jun 8, 2026
9f066c4
Remove test assertions already caught by type checker
zoldar Jun 8, 2026
a0ee179
Don't pattern match on regex
zoldar Jun 8, 2026
63ffc91
Avoid passing literal for subscription in `Status.in?` test calls
zoldar Jun 8, 2026
87ba827
Fix a type issue in `Audit.Encoder` reported by dialyzer
zoldar Jun 9, 2026
5351893
Fix `phash2` workaround in `Plausible`
zoldar Jun 9, 2026
8ef2f55
Bump OTP to 29.0.1 in asdf config
zoldar Jun 9, 2026
f454560
Bump patch versions of `x509` and `credo` dependencies
zoldar Jun 9, 2026
c897b56
Remove `Bamboo.SMTPAdapter` as it's no longer maintained and broken o…
zoldar Jun 9, 2026
0d0a824
Make user agent test string larger to trigger ua timeout telemetry event
zoldar Jun 9, 2026
2390849
Fix regex comparison as internal reference is changing now
zoldar Jun 9, 2026
f87dcc4
Add FIXME comments for surfaced cache bugs
zoldar Jun 9, 2026
1a0561e
Downgrade OTP to more proven 28.5.0.1
zoldar Jun 9, 2026
cae0bfc
Use exported regex pattern for stored regex to avoid cache issues
zoldar Jun 9, 2026
443ce40
Bump elixir in asdf to 1.20.1
zoldar Jun 10, 2026
024ec0f
Add dialyzer-ignore file to suppress Ecto.Multi opaque errors
zoldar Jun 10, 2026
717a3cb
Update builder image in Dockerfile
zoldar Jun 10, 2026
6971ff3
Bust CI cache
zoldar Jun 10, 2026
db0d5fd
Fix type errors in CE
zoldar Jun 10, 2026
36d9d6f
Make user agent test string even longer to increase chances of timeout
zoldar Jun 10, 2026
65c0edc
Address credo issues in touched files
zoldar Jun 10, 2026
ac26f1b
Fix another dialyzer regression
zoldar Jun 10, 2026
a17c6ea
Increase credo's max nesting threshold from 2 to 3 because this is bs
zoldar Jun 10, 2026
6effbe2
Allow operators in if condition assignment expressions in credo
zoldar Jun 10, 2026
40b2ce7
Ignore a bogus dialyzer error
zoldar Jun 10, 2026
ef2c6ad
Re-add missing Logger require
zoldar Jun 10, 2026
1736df0
Add changelog entry
zoldar Jun 10, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions .credo.exs
Original file line number Diff line number Diff line change
Expand Up @@ -119,16 +119,15 @@
{Credo.Check.Refactor.CyclomaticComplexity, false},
{Credo.Check.Refactor.FilterCount, []},
{Credo.Check.Refactor.FilterFilter, []},
{Credo.Check.Refactor.MatchInCondition, []},
{Credo.Check.Refactor.MatchInCondition, [allow_operators: true]},
{Credo.Check.Refactor.RedundantWithClauseResult, []},
{Credo.Check.Refactor.RejectReject, []},
{Credo.Check.Refactor.FunctionArity, []},
{Credo.Check.Refactor.LongQuoteBlocks, []},
{Credo.Check.Refactor.MatchInCondition, []},
{Credo.Check.Refactor.MapJoin, []},
{Credo.Check.Refactor.NegatedConditionsInUnless, []},
{Credo.Check.Refactor.NegatedConditionsWithElse, false},
{Credo.Check.Refactor.Nesting, []},
{Credo.Check.Refactor.Nesting, [max_nesting: 3]},
{Credo.Check.Refactor.UnlessWithElse, []},
{Credo.Check.Refactor.WithClauses, []},
{Credo.Check.Refactor.FilterFilter, []},
Expand Down
6 changes: 6 additions & 0 deletions .dialyzer_ignore.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[
{"lib/plausible/goals/goals.ex", :call_without_opaque},
{"lib/plausible/sites.ex", :call_without_opaque},
{"lib/plausible/teams/invitations.ex", :call_without_opaque},
{"lib/plausible_web/live/components/modal.ex", :pattern_match, 1}
]
2 changes: 1 addition & 1 deletion .github/workflows/elixir.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ concurrency:
cancel-in-progress: true

env:
CACHE_VERSION: v17
CACHE_VERSION: v18
PERSISTENT_CACHE_DIR: cached

jobs:
Expand Down
4 changes: 2 additions & 2 deletions .tool-versions
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
erlang 27.3.4.6
elixir 1.19.4-otp-27
erlang 28.5.0.1
elixir 1.20.1-otp-28
nodejs 23.2.0
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ All notable changes to this project will be documented in this file.
### Removed

- Removed the standalone team switcher page; team switching is now done from the topbar dropdown only
- Removed `Bamboo.SMTPAdapter` from supported e-mail adapters; the library is no longer in active developments and does not compile under Elixir 1.20+

### Changed

Expand Down
4 changes: 2 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# we can not use the pre-built tar because the distribution is
# platform specific, it makes sense to build it in the docker

ARG ALPINE_VERSION=3.22.2
ARG ALPINE_VERSION=3.22.4

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
ARG ALPINE_VERSION=3.22.4


#### Builder
FROM hexpm/elixir:1.19.4-erlang-27.3.4.6-alpine-${ALPINE_VERSION} AS buildcontainer
FROM hexpm/elixir:1.20.1-erlang-28.5.0.1-alpine-${ALPINE_VERSION} AS buildcontainer

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
FROM hexpm/elixir:1.20.1-erlang-28.5.0.1-alpine-${ALPINE_VERSION} AS buildcontainer
FROM hexpm/elixir:1.20.1-erlang-28.5.0.1-alpine-3.22.4@sha256:ba0f4e2b4cf931850708dfa3bff3c3f4b561fa010f554df9337eece9b71ee1f6 AS buildcontainer


ARG MIX_ENV=ce

Expand Down
14 changes: 0 additions & 14 deletions config/runtime.exs
Original file line number Diff line number Diff line change
Expand Up @@ -742,20 +742,6 @@ case mailer_adapter do
hackney_opts: [recv_timeout: :timer.seconds(10)],
api_key: get_var_from_path_or_env(config_dir, "SENDGRID_API_KEY")

"Bamboo.SMTPAdapter" ->
config :plausible, Plausible.Mailer,
adapter: Bamboo.SMTPAdapter,
server: get_var_from_path_or_env(config_dir, "SMTP_HOST_ADDR", "mail"),
hostname: base_url.host,
port: get_var_from_path_or_env(config_dir, "SMTP_HOST_PORT", "25"),
username: get_var_from_path_or_env(config_dir, "SMTP_USER_NAME"),
password: get_var_from_path_or_env(config_dir, "SMTP_USER_PWD"),
tls: :if_available,
allowed_tls_versions: [:tlsv1, :"tlsv1.1", :"tlsv1.2"],
ssl: get_bool_from_path_or_env(config_dir, "SMTP_HOST_SSL_ENABLED", false),
retries: get_var_from_path_or_env(config_dir, "SMTP_RETRIES") || 2,
no_mx_lookups: get_bool_from_path_or_env(config_dir, "SMTP_MX_LOOKUPS_ENABLED", true)

"Bamboo.Mua" ->
config :plausible, Plausible.Mailer, adapter: Bamboo.Mua

Expand Down
4 changes: 2 additions & 2 deletions extra/lib/license.ex
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ defmodule Plausible.License do
at hello@plausible.io to discuss obtaining a license.
"""

require Logger

if Mix.env() == :prod do
require Logger

def ensure_valid_license do
if has_valid_license?() do
:ok
Expand Down
19 changes: 12 additions & 7 deletions extra/lib/plausible/audit/encoder.ex
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@ defmodule Plausible.Audit.EncoderError do
end

defprotocol Plausible.Audit.Encoder do
def encode(x, opts \\ [])
def encode(x)

def encode(x, opts)
end

defimpl Plausible.Audit.Encoder, for: Ecto.Changeset do
def encode(changeset, opts) do
def encode(changeset, opts \\ []) do
changes =
Enum.reduce(changeset.changes, %{}, fn {k, v}, acc ->
Map.put(acc, k, Plausible.Audit.Encoder.encode(v, opts))
Expand All @@ -32,7 +34,7 @@ defimpl Plausible.Audit.Encoder, for: Ecto.Changeset do
end

defimpl Plausible.Audit.Encoder, for: Map do
def encode(x, opts) do
def encode(x, opts \\ []) do
{allow_not_loaded, data} = Map.pop(x, :__allow_not_loaded__)
raise_on_not_loaded? = Keyword.get(opts, :raise_on_not_loaded?, true)

Expand All @@ -53,22 +55,24 @@ defimpl Plausible.Audit.Encoder, for: Map do
end

defimpl Plausible.Audit.Encoder, for: [Integer, BitString, Float] do
def encode(x, _opts), do: x
def encode(x, _opts \\ []), do: x
end

defimpl Plausible.Audit.Encoder, for: [DateTime, Date, NaiveDateTime, Time] do
def encode(x, _opts), do: to_string(x)
def encode(x, _opts \\ []), do: to_string(x)
end

defimpl Plausible.Audit.Encoder, for: Atom do
def encode(x, opts \\ [])

def encode(nil, _opts), do: nil
def encode(true, _opts), do: true
def encode(false, _opts), do: false
def encode(x, _opts), do: Atom.to_string(x)
end

defimpl Plausible.Audit.Encoder, for: List do
def encode(x, opts) do
def encode(x, opts \\ []) do
Enum.map(x, &Plausible.Audit.Encoder.encode(&1, opts))
end
end
Expand Down Expand Up @@ -116,12 +120,13 @@ defimpl Plausible.Audit.Encoder, for: Any do

quote do
defimpl Plausible.Audit.Encoder, for: unquote(module) do
def encode(struct, opts) do
def encode(struct, opts \\ []) do
Plausible.Audit.Encoder.encode(unquote(extractor), opts)
end
end
end
end

def encode(_), do: raise("Implement me")
def encode(_, _), do: raise("Implement me")
end
1 change: 0 additions & 1 deletion extra/lib/plausible/auth/sso/domain/verification.ex
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ defmodule Plausible.Auth.SSO.Domain.Verification do
"""

alias Plausible.Auth.SSO.Domain
require Domain

@prefix "plausible-sso-verification"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ defmodule Plausible.InstallationSupport.Detection.Diagnostics do
@moduledoc """
Module responsible for translating diagnostics to user-friendly errors and recommendations.
"""
require Logger

# in this struct, nil means indeterminate
defstruct v1_detected: nil,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ defmodule Plausible.InstallationSupport.Verification.Diagnostics do
@moduledoc """
Module responsible for translating diagnostics to user-friendly errors and recommendations.
"""
require Logger

# In this struct
# - the default nil value for each field means that the value is indeterminate (e.g. we didn't even get to the part where response_status is set)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@ defmodule PlausibleWeb.CustomerSupport.Team.Components.Billing do
import Ecto.Query, only: [from: 2]
import PlausibleWeb.Components.Generic

require Plausible.Billing.Subscription.Status

def update(%{team: team}, socket) do
usage = Teams.Billing.quota_usage(team, with_features: true)

Expand Down
4 changes: 3 additions & 1 deletion lib/mix/tasks/create_free_subscription.ex
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
defmodule Mix.Tasks.CreateFreeSubscription do
@moduledoc false

use Mix.Task
use Plausible.Repo
require Logger

alias Plausible.Billing.Subscription

# coveralls-ignore-start
Expand Down
3 changes: 2 additions & 1 deletion lib/mix/tasks/generate_referrer_favicons.ex
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
defmodule Mix.Tasks.GenerateReferrerFavicons do
@moduledoc false

use Mix.Task
use Plausible.Repo
require Logger

@dialyzer {:nowarn_function, run: 1}
# coveralls-ignore-start
Expand Down
1 change: 0 additions & 1 deletion lib/mix/tasks/send_pageview.ex
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ defmodule Mix.Tasks.SendPageview do
"""

use Mix.Task
require Logger

@default_host "http://localhost:8000"
@default_ip_address "127.0.0.1"
Expand Down
8 changes: 7 additions & 1 deletion lib/plausible.ex
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,13 @@ defmodule Plausible do

defmacro always(term) do
quote do
:erlang.phash2(1, 1) == 0 && unquote(term)
case :erlang.phash2(1, 1) do
0 ->
unquote(term)

1 ->
not unquote(term)
end
end
end

Expand Down
4 changes: 1 addition & 3 deletions lib/plausible/application.ex
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ defmodule Plausible.Application do
use Application
use Plausible

require Logger

def start(_type, _args) do
on_ee(do: Plausible.License.ensure_valid_license())
on_ce(do: :inet_db.set_tcp_module(:happy_tcp))
Expand Down Expand Up @@ -359,7 +357,7 @@ defmodule Plausible.Application do
end

def setup_sentry() do
Logger.add_backend(Sentry.LoggerBackend)
LoggerBackends.add(Sentry.LoggerBackend)

:telemetry.attach_many(
"oban-errors",
Expand Down
2 changes: 1 addition & 1 deletion lib/plausible/billing/billing.ex
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ defmodule Plausible.Billing do
"""
use Plausible
use Plausible.Repo
require Plausible.Billing.Subscription.Status

alias Plausible.Auth
alias Plausible.Billing.Subscription
alias Plausible.Teams
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ defmodule Plausible.DataMigration.PopulateEventSessionColumns do
"""
use Plausible.DataMigration, dir: "PopulateEventSessionColumns", repo: Plausible.IngestRepo

require Logger

# See https://clickhouse.com/docs/en/sql-reference/dictionaries#cache for meaning of these defaults
@default_dictionary_config %{
lifetime: 600_000,
Expand Down
2 changes: 1 addition & 1 deletion lib/plausible/ecto/types/compiled_regex.ex
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@ defmodule Plausible.Ecto.Types.CompiledRegex do
def cast(val) when is_binary(val), do: {:ok, val}
def cast(_), do: :error

def load(val), do: {:ok, Regex.compile!(val)}
def load(val), do: {:ok, Regex.compile!(val, "E")}
def dump(val), do: {:ok, val}
end
2 changes: 0 additions & 2 deletions lib/plausible/google/api.ex
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ defmodule Plausible.Google.API do
alias Plausible.Google.SearchConsole
alias Plausible.Stats.Query

require Logger

@search_console_scope URI.encode_www_form(
"email https://www.googleapis.com/auth/webmasters.readonly"
)
Expand Down
2 changes: 0 additions & 2 deletions lib/plausible/ingestion/counters.ex
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@ defmodule Plausible.Ingestion.Counters do

@behaviour :gen_cycle

require Logger

alias Plausible.Ingestion.Counters.Buffer
alias Plausible.Ingestion.Counters.Record
alias Plausible.Ingestion.Counters.TelemetryHandler
Expand Down
2 changes: 0 additions & 2 deletions lib/plausible/ingestion/persistor/embedded.ex
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ defmodule Plausible.Ingestion.Persistor.Embedded do

alias Plausible.ClickhouseEventV2

require Logger

def persist_event(ingest_event, previous_user_id, opts) do
event = ingest_event.clickhouse_event
session_attrs = ingest_event.clickhouse_session_attrs
Expand Down
4 changes: 2 additions & 2 deletions lib/plausible/open_telemetry.ex
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
defmodule Plausible.OpenTelemetry do
@moduledoc false

require OpenTelemetry.Tracer, as: Tracer
alias OpenTelemetry.Tracer

def current_trace_id do
case OpenTelemetry.Tracer.current_span_ctx() do
case Tracer.current_span_ctx() do
:undefined ->
nil

Expand Down
2 changes: 0 additions & 2 deletions lib/plausible/open_telemetry/logger.ex
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ defmodule Plausible.OpenTelemetry.Logger do
to the Logger metadata when Phoenix router dispatch starts.
"""

require Logger

@doc """
Attaches telemetry handlers to set trace_id in Logger metadata.

Expand Down
5 changes: 4 additions & 1 deletion lib/plausible/session/cache_store.ex
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
defmodule Plausible.Session.CacheStore do
require Logger
@moduledoc """
Session management on the basis of incoming events.
"""

alias Plausible.Session.WriteBuffer

@lock_timeout 1000
Expand Down
2 changes: 0 additions & 2 deletions lib/plausible/site/gate_keeper.ex
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@ defmodule Plausible.Site.GateKeeper do
alias Plausible.{Site, RateLimit}
alias Plausible.Site.Cache

require Logger

@spec check(String.t(), Keyword.t()) :: t()
def check(domain, opts \\ []) when is_binary(domain) do
case policy(domain, opts) do
Expand Down
6 changes: 5 additions & 1 deletion lib/plausible/stats/query.ex
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
defmodule Plausible.Stats.Query do
@moduledoc """
Struct storing stats query parameters and configuration.
"""

use Plausible

defstruct utc_time_range: nil,
Expand Down Expand Up @@ -32,7 +36,7 @@ defmodule Plausible.Stats.Query do
sql_join_type: :left,
smear_session_metrics: false

require OpenTelemetry.Tracer, as: Tracer
alias OpenTelemetry.Tracer

alias Plausible.Stats.{
DateTimeRange,
Expand Down
1 change: 0 additions & 1 deletion lib/plausible/stats/sparkline.ex
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ defmodule Plausible.Stats.Sparkline do

alias Plausible.{Site, Stats}
alias Plausible.Stats.QueryBuilder
require Logger

@spec parallel_overview([Site.t()], NaiveDateTime.t()) :: map()
def parallel_overview(sites, now \\ NaiveDateTime.utc_now()) when is_list(sites) do
Expand Down
Loading
Loading