Skip to content

Commit d214c8f

Browse files
committed
Support OTP 28 in CI
This also fixes errors caused by different internal references in compiled regex objects.
1 parent 420a84d commit d214c8f

3 files changed

Lines changed: 82 additions & 62 deletions

File tree

.github/workflows/ci.yml

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,17 @@ jobs:
1919
fail-fast: false
2020
matrix:
2121
include:
22-
- elixir: "1.18.1"
23-
otp: "27.2"
22+
- elixir: "1.18.4"
23+
otp: "28.0"
2424
lint: lint
2525
- elixir: "1.17.3"
26-
otp: "27.1"
26+
otp: "27.3"
2727
- elixir: "1.17.3"
28-
otp: "25.0.4"
28+
otp: "26.2"
29+
- elixir: "1.17.3"
30+
otp: "25.3"
2931
- elixir: "1.14.5"
30-
otp: "24.3.4.17"
32+
otp: "24.3"
3133

3234
steps:
3335
- name: Checkout
@@ -68,11 +70,13 @@ jobs:
6870
fail-fast: false
6971
matrix:
7072
elixirbase:
71-
- "1.17.3-erlang-27.1-alpine-3.17.9"
72-
- "1.17.3-erlang-25.0.4-alpine-3.17.9"
73-
- "1.14.5-erlang-23.3.4.20-alpine-3.16.9"
73+
- "1.18.4-erlang-28.0.2-alpine-3.22.1"
74+
- "1.17.3-erlang-27.3.4.2-alpine-3.22.1"
75+
- "1.17.3-erlang-26.2.5.14-alpine-3.22.1"
76+
- "1.17.3-erlang-25.3.2.21-alpine-3.22.1"
77+
- "1.14.5-erlang-24.3.4.17-alpine-3.22.1"
7478
steps:
7579
- uses: earthly/actions-setup@v1
76-
- uses: actions/checkout@v3
80+
- uses: actions/checkout@v4
7781
- name: ecto integration-test under ${{matrix.elixirbase}}
7882
run: earthly -P --ci --build-arg ELIXIR_BASE=${{matrix.elixirbase}} +integration-test

Earthfile

Lines changed: 32 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,14 @@ VERSION 0.6
22

33
all:
44
BUILD \
5-
--build-arg ELIXIR_BASE=1.15.6-erlang-25.3.2.6-alpine-3.18.4 \
6-
--build-arg ELIXIR_BASE=1.15.6-erlang-24.3.4.14-alpine-3.18.4 \
5+
--build-arg ELIXIR_BASE=1.18.4-erlang-28.0.2-alpine-3.22.1 \
6+
--build-arg ELIXIR_BASE=1.17.3-erlang-27.3.4.2-alpine-3.22.1 \
7+
--build-arg ELIXIR_BASE=1.17.3-erlang-26.2.5.14-alpine-3.22.1 \
8+
--build-arg ELIXIR_BASE=1.14.5-erlang-24.3.4.17-alpine-3.22.1 \
79
+integration-test
810

911
integration-test-base:
10-
ARG ELIXIR_BASE=1.15.6-erlang-25.3.2.6-alpine-3.18.4
12+
ARG ELIXIR_BASE=1.18.4-erlang-28.0.2-alpine-3.22.1
1113
ARG TARGETARCH
1214
FROM hexpm/elixir:$ELIXIR_BASE
1315
RUN apk add --no-progress --update git build-base
@@ -44,37 +46,37 @@ integration-test:
4446
ARG MCR_IMG="mcr.microsoft.com/mssql/server:2019-latest"
4547
ARG MYSQL_IMG="mysql:5.7"
4648

47-
# then run the tests
49+
# then run the tests
4850
WITH DOCKER --pull "$PG_IMG" --pull "$MCR_IMG" --pull "$MYSQL_IMG" --platform linux/amd64
49-
RUN set -e; \
50-
timeout=$(expr $(date +%s) + 60); \
51+
RUN set -e; \
52+
timeout=$(expr $(date +%s) + 60); \
5153

52-
# start databases
53-
docker run --name mssql --network=host -d -e 'ACCEPT_EULA=Y' -e 'MSSQL_SA_PASSWORD=some!Password' "$MCR_IMG"; \
54-
docker run --name pg --network=host -d -e POSTGRES_USER=postgres -e POSTGRES_PASSWORD=postgres -e POSTGRES_DB=postgres "$PG_IMG"; \
55-
docker run --name mysql --network=host -d -e MYSQL_ROOT_PASSWORD=root "$MYSQL_IMG"; \
54+
# start databases
55+
docker run --name mssql --network=host -d -e 'ACCEPT_EULA=Y' -e 'MSSQL_SA_PASSWORD=some!Password' "$MCR_IMG"; \
56+
docker run --name pg --network=host -d -e POSTGRES_USER=postgres -e POSTGRES_PASSWORD=postgres -e POSTGRES_DB=postgres "$PG_IMG"; \
57+
docker run --name mysql --network=host -d -e MYSQL_ROOT_PASSWORD=root "$MYSQL_IMG"; \
5658

57-
# wait for mssql to start
58-
while ! sqlcmd -C -S tcp:127.0.0.1,1433 -U sa -P 'some!Password' -Q "SELECT 1" >/dev/null 2>&1; do \
59-
test "$(date +%s)" -le "$timeout" || (echo "timed out waiting for mssql"; exit 1); \
60-
echo "waiting for mssql"; \
61-
sleep 1; \
62-
done; \
59+
# wait for mssql to start
60+
while ! sqlcmd -C -S tcp:127.0.0.1,1433 -U sa -P 'some!Password' -Q "SELECT 1" >/dev/null 2>&1; do \
61+
test "$(date +%s)" -le "$timeout" || (echo "timed out waiting for mssql"; exit 1); \
62+
echo "waiting for mssql"; \
63+
sleep 1; \
64+
done; \
6365

64-
# wait for postgres to start
65-
while ! pg_isready --host=127.0.0.1 --port=5432 --quiet; do \
66-
test "$(date +%s)" -le "$timeout" || (echo "timed out waiting for postgres"; exit 1); \
67-
echo "waiting for postgres"; \
68-
sleep 1; \
69-
done; \
66+
# wait for postgres to start
67+
while ! pg_isready --host=127.0.0.1 --port=5432 --quiet; do \
68+
test "$(date +%s)" -le "$timeout" || (echo "timed out waiting for postgres"; exit 1); \
69+
echo "waiting for postgres"; \
70+
sleep 1; \
71+
done; \
7072

71-
# wait for mysql to start
72-
while ! mysqladmin ping --host=127.0.0.1 --port=3306 --protocol=TCP --silent; do \
73-
test "$(date +%s)" -le "$timeout" || (echo "timed out waiting for mysql"; exit 1); \
74-
echo "waiting for mysql"; \
75-
sleep 1; \
76-
done; \
73+
# wait for mysql to start
74+
while ! mysqladmin ping --host=127.0.0.1 --port=3306 --protocol=TCP --silent; do \
75+
test "$(date +%s)" -le "$timeout" || (echo "timed out waiting for mysql"; exit 1); \
76+
echo "waiting for mysql"; \
77+
sleep 1; \
78+
done; \
7779

78-
# run test
79-
MSSQL_URL='sa:some!Password@127.0.0.1' MYSQL_URL='root:root@127.0.0.1' PG_URL='postgres:postgres@127.0.0.1' ECTO_PATH='/src/ecto' mix test.all;
80+
# run test
81+
MSSQL_URL='sa:some!Password@127.0.0.1' MYSQL_URL='root:root@127.0.0.1' PG_URL='postgres:postgres@127.0.0.1' ECTO_PATH='/src/ecto' mix test.all;
8082
END

test/ecto/changeset_test.exs

Lines changed: 37 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1317,15 +1317,15 @@ defmodule Ecto.ChangesetTest do
13171317

13181318
assert changeset.valid?
13191319
assert changeset.errors == []
1320-
assert validations(changeset) == [title: {:format, ~r/@/}]
1320+
assert match?([title: {:format, %Regex{source: "@"}}], validations(changeset))
13211321

13221322
changeset =
13231323
changeset(%{"title" => "foobar"})
13241324
|> validate_format(:title, ~r/@/)
13251325

13261326
refute changeset.valid?
13271327
assert changeset.errors == [title: {"has invalid format", [validation: :format]}]
1328-
assert validations(changeset) == [title: {:format, ~r/@/}]
1328+
assert match?([title: {:format, %Regex{source: "@"}}], validations(changeset))
13291329

13301330
changeset =
13311331
changeset(%{"title" => "foobar"})
@@ -2681,17 +2681,19 @@ defmodule Ecto.ChangesetTest do
26812681
message: "cannot be more than 15 characters"
26822682
)
26832683

2684-
assert constraints(changeset) ==
2684+
assert match?(
26852685
[
26862686
%{
26872687
type: :check,
26882688
field: :title,
2689-
constraint: ~r/title_must_be_short\d+/,
2689+
constraint: %Regex{source: "title_must_be_short\\d+"},
26902690
match: :exact,
26912691
error_message: "cannot be more than 15 characters",
26922692
error_type: :check
26932693
}
2694-
]
2694+
],
2695+
constraints(changeset)
2696+
)
26952697

26962698
assert_raise ArgumentError, ~r/invalid match type: :invalid/, fn ->
26972699
change(%Post{})
@@ -2769,17 +2771,19 @@ defmodule Ecto.ChangesetTest do
27692771
changeset =
27702772
change(%Post{}) |> unique_constraint(:title, name: ~r/whatever\d+/, message: "is taken")
27712773

2772-
assert constraints(changeset) ==
2774+
assert match?(
27732775
[
27742776
%{
27752777
type: :unique,
27762778
field: :title,
2777-
constraint: ~r/whatever\d+/,
2779+
constraint: %Regex{source: "whatever\\d+"},
27782780
match: :exact,
27792781
error_message: "is taken",
27802782
error_type: :unique
27812783
}
2782-
]
2784+
],
2785+
constraints(changeset)
2786+
)
27832787

27842788
assert_raise ArgumentError, ~r/invalid match type: :invalid/, fn ->
27852789
change(%Post{})
@@ -2836,17 +2840,19 @@ defmodule Ecto.ChangesetTest do
28362840
changeset =
28372841
change(%Post{}) |> unique_constraint(:permalink, name: ~r/whatever\d+/, message: "is taken")
28382842

2839-
assert constraints(changeset) ==
2843+
assert match?(
28402844
[
28412845
%{
28422846
type: :unique,
28432847
field: :permalink,
2844-
constraint: ~r/whatever\d+/,
2848+
constraint: %Regex{source: "whatever\\d+"},
28452849
match: :exact,
28462850
error_message: "is taken",
28472851
error_type: :unique
28482852
}
2849-
]
2853+
],
2854+
constraints(changeset)
2855+
)
28502856

28512857
assert_raise ArgumentError, ~r/invalid match type: :invalid/, fn ->
28522858
change(%Post{})
@@ -2979,17 +2985,19 @@ defmodule Ecto.ChangesetTest do
29792985
change(%Comment{})
29802986
|> foreign_key_constraint(:post, name: ~r/whatever\d+/, message: "is not available")
29812987

2982-
assert constraints(changeset) ==
2988+
assert match?(
29832989
[
29842990
%{
29852991
type: :foreign_key,
29862992
field: :post,
2987-
constraint: ~r/whatever\d+/,
2993+
constraint: %Regex{source: "whatever\\d+"},
29882994
match: :exact,
29892995
error_message: "is not available",
29902996
error_type: :foreign
29912997
}
2992-
]
2998+
],
2999+
constraints(changeset)
3000+
)
29933001

29943002
assert_raise ArgumentError, ~r/invalid match type: :invalid/, fn ->
29953003
change(%Comment{})
@@ -3100,17 +3108,19 @@ defmodule Ecto.ChangesetTest do
31003108
change(%Comment{})
31013109
|> assoc_constraint(:post, name: ~r/whatever\d+/, message: "is not available")
31023110

3103-
assert constraints(changeset) ==
3111+
assert match?(
31043112
[
31053113
%{
31063114
type: :foreign_key,
31073115
field: :post,
3108-
constraint: ~r/whatever\d+/,
3116+
constraint: %Regex{source: "whatever\\d+"},
31093117
match: :exact,
31103118
error_message: "is not available",
31113119
error_type: :assoc
31123120
}
3113-
]
3121+
],
3122+
constraints(changeset)
3123+
)
31143124

31153125
assert_raise ArgumentError, ~r/invalid match type: :invalid/, fn ->
31163126
change(%Comment{})
@@ -3229,17 +3239,19 @@ defmodule Ecto.ChangesetTest do
32293239
change(%Post{})
32303240
|> no_assoc_constraint(:comments, name: ~r/comments_post_id_fkey\d+/, message: "exists")
32313241

3232-
assert constraints(changeset) ==
3242+
assert match?(
32333243
[
32343244
%{
32353245
type: :foreign_key,
32363246
field: :comments,
3237-
constraint: ~r/comments_post_id_fkey\d+/,
3247+
constraint: %Regex{source: "comments_post_id_fkey\\d+"},
32383248
match: :exact,
32393249
error_message: "exists",
32403250
error_type: :no_assoc
32413251
}
3242-
]
3252+
],
3253+
constraints(changeset)
3254+
)
32433255

32443256
assert_raise ArgumentError, ~r/invalid match type: :invalid/, fn ->
32453257
change(%Post{})
@@ -3409,17 +3421,19 @@ defmodule Ecto.ChangesetTest do
34093421
change(%Post{})
34103422
|> exclusion_constraint(:title, name: ~r/whatever\d+/, message: "is invalid")
34113423

3412-
assert constraints(changeset) ==
3424+
assert match?(
34133425
[
34143426
%{
34153427
type: :exclusion,
34163428
field: :title,
3417-
constraint: ~r/whatever\d+/,
3429+
constraint: %Regex{source: "whatever\\d+"},
34183430
match: :exact,
34193431
error_message: "is invalid",
34203432
error_type: :exclusion
34213433
}
3422-
]
3434+
],
3435+
constraints(changeset)
3436+
)
34233437

34243438
assert_raise ArgumentError, ~r/invalid match type: :invalid/, fn ->
34253439
change(%Post{})

0 commit comments

Comments
 (0)