Skip to content

Commit 388c424

Browse files
authored
fix(macros): smarter .env loading, caching, and invalidation (#4053)
* fix(macros): smarter `.env` loading, caching, and invalidation * feat(mysql): test `.env` loading in CI * feat(postgres): test `.env` loading in CI * feat(macros): allow `DATABASE_URL` to be empty * fix(examples/postgres): make `cargo-sqlx` executable * fix(examples/postgres): `cargo sqlx` invocation * feat(examples/postgres): check offline prepare on more examples * fix(examples/postgres): the name of this step * fix(cli): don't suppress error from `dotenv()` * fix(ci/examples/postgres): don't use heredoc in this step * fix(ci/examples/postgres): multi-tenant * fix(ci/examples/sqlite): test `.env` loading * chore: add CHANGELOG entry
1 parent 064d649 commit 388c424

File tree

18 files changed

+621
-296
lines changed

18 files changed

+621
-296
lines changed

.github/workflows/examples.yml

Lines changed: 143 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,22 +26,27 @@ jobs:
2626
- run: >
2727
cargo build
2828
-p sqlx-cli
29-
--bin sqlx
3029
--release
3130
--no-default-features
3231
--features mysql,postgres,sqlite,sqlx-toml
3332
3433
- uses: actions/upload-artifact@v4
3534
with:
3635
name: sqlx-cli
37-
path: target/release/sqlx
36+
path: |
37+
target/release/sqlx
38+
target/release/cargo-sqlx
3839
3940
mysql:
4041
name: MySQL Examples
4142
runs-on: ubuntu-latest
4243
needs: sqlx-cli
4344
timeout-minutes: 30
4445

46+
strategy:
47+
matrix:
48+
offline: ['', 'offline']
49+
4550
services:
4651
mysql:
4752
image: mysql:latest
@@ -60,7 +65,7 @@ jobs:
6065

6166
- run: |
6267
ls -R /home/runner/.local/bin
63-
chmod +x /home/runner/.local/bin/sqlx
68+
chmod +x /home/runner/.local/bin/sqlx /home/runner/.local/bin/cargo-sqlx
6469
echo /home/runner/.local/bin >> $GITHUB_PATH
6570
sleep 10
6671
@@ -77,9 +82,32 @@ jobs:
7782
DATABASE_URL: mysql://root:password@localhost:3306/todos?ssl-mode=disabled
7883
run: sqlx db setup
7984

85+
- name: Todos (Prepare)
86+
if: ${{ matrix.offline }}
87+
working-directory: examples/mysql/todos
88+
env:
89+
DATABASE_URL: mysql://root:password@localhost:3306/todos?ssl-mode=disabled
90+
run: cargo sqlx prepare
91+
92+
- name: Todos (Check Offline)
93+
if: ${{ matrix.offline }}
94+
run: |
95+
cargo clean -p sqlx-example-mysql-todos
96+
cargo check -p sqlx-example-mysql-todos
97+
98+
- name: Todos (Prepare from .env)
99+
if: ${{ matrix.offline }}
100+
working-directory: examples/mysql/todos
101+
run: |
102+
echo "DATABASE_URL=mysql://root:password@localhost:3306/todos?ssl-mode=disabled" > .env
103+
cargo clean -p sqlx-example-mysql-todos
104+
cargo sqlx prepare
105+
rm .env
106+
80107
- name: Todos (Run)
81108
env:
82109
DATABASE_URL: mysql://root:password@localhost:3306/todos?ssl-mode=disabled
110+
SQLX_OFFLINE: ${{ matrix.offline == 'offline' }}
83111
run: cargo run -p sqlx-example-mysql-todos
84112

85113
postgres:
@@ -88,6 +116,10 @@ jobs:
88116
needs: sqlx-cli
89117
timeout-minutes: 30
90118

119+
strategy:
120+
matrix:
121+
offline: ['', 'offline']
122+
91123
services:
92124
postgres:
93125
image: postgres:latest
@@ -106,6 +138,7 @@ jobs:
106138
- run: |
107139
ls -R /home/runner/.local/bin
108140
chmod +x $HOME/.local/bin/sqlx
141+
chmod +x $HOME/.local/bin/cargo-sqlx
109142
echo $HOME/.local/bin >> $GITHUB_PATH
110143
sleep 10
111144
@@ -120,14 +153,32 @@ jobs:
120153
DATABASE_URL: postgres://postgres:password@localhost:5432/axum-social
121154
run: sqlx db setup
122155

123-
- name: Axum Social with Tests (Check)
156+
# Test `cargo sqlx prepare` setting `DATABASE_URL` both directly and in `.env`
157+
# This doesn't need to be done for every single example here, but should at least cover potential problem cases.
158+
- name: Axum Social with Tests (Prepare)
159+
if: ${{ matrix.offline }}
124160
env:
125161
DATABASE_URL: postgres://postgres:password@localhost:5432/axum-social
126-
run: cargo check -p sqlx-example-postgres-axum-social
162+
run: cargo sqlx prepare -- -p sqlx-example-postgres-axum-social
163+
164+
- name: Axum Social with Tests (Check Offline)
165+
if: ${{ matrix.offline }}
166+
run: |
167+
cargo clean -p sqlx-example-postgres-axum-social
168+
cargo check -p sqlx-example-postgres-axum-social
169+
170+
- name: Axum Social with Tests (Prepare from .env)
171+
if: ${{ matrix.offline }}
172+
run: |
173+
echo "DATABASE_URL=postgres://postgres:password@localhost:5432/axum-social" > .env
174+
cargo clean -p sqlx-example-postgres-axum-social
175+
cargo sqlx prepare -- -p sqlx-example-postgres-axum-social
176+
rm .env
127177
128178
- name: Axum Social with Tests (Test)
129179
env:
130180
DATABASE_URL: postgres://postgres:password@localhost:5432/axum-social
181+
SQLX_OFFLINE: ${{ matrix.offline == 'offline' }}
131182
run: cargo test -p sqlx-example-postgres-axum-social
132183

133184
# The Chat example has an interactive TUI which is not trivial to test automatically,
@@ -190,11 +241,47 @@ jobs:
190241
(cd payments && sqlx db setup)
191242
sqlx db setup
192243
244+
- name: Multi-Database (Prepare)
245+
if: ${{ matrix.offline }}
246+
env:
247+
DATABASE_URL: postgres://postgres:password@localhost:5432/multi-database
248+
ACCOUNTS_DATABASE_URL: postgres://postgres:password@localhost:5432/multi-database-accounts
249+
PAYMENTS_DATABASE_URL: postgres://postgres:password@localhost:5432/multi-database-payments
250+
run: |
251+
cargo clean -p sqlx-example-postgres-multi-database-accounts
252+
cargo clean -p sqlx-example-postgres-multi-database-payments
253+
cargo clean -p sqlx-example-postgres-multi-database
254+
# should include -accounts and -payments
255+
cargo sqlx prepare -- -p sqlx-example-postgres-multi-database
256+
257+
- name: Multi-Database (Check Offline)
258+
if: ${{ matrix.offline }}
259+
run: |
260+
cargo clean -p sqlx-example-postgres-multi-database
261+
cargo check -p sqlx-example-postgres-multi-database
262+
263+
- name: Multi-Database (Prepare from .env)
264+
if: ${{ matrix.offline }}
265+
run: |
266+
# Tried to get this to work with heredocs but had trouble writing tabs in YAML
267+
echo 'DATABASE_URL=postgres://postgres:password@localhost:5432/multi-database' >.env
268+
# Important: append, don't truncate
269+
echo 'ACCOUNTS_DATABASE_URL=postgres://postgres:password@localhost:5432/multi-database-accounts' >> .env
270+
echo 'PAYMENTS_DATABASE_URL=postgres://postgres:password@localhost:5432/multi-database-payments' >> .env
271+
272+
cargo clean -p sqlx-example-postgres-multi-database-accounts
273+
cargo clean -p sqlx-example-postgres-multi-database-payments
274+
cargo clean -p sqlx-example-postgres-multi-database
275+
cargo sqlx prepare -- -p sqlx-example-postgres-multi-database
276+
277+
rm .env
278+
193279
- name: Multi-Database (Run)
194280
env:
195281
DATABASE_URL: postgres://postgres:password@localhost:5432/multi-database
196282
ACCOUNTS_DATABASE_URL: postgres://postgres:password@localhost:5432/multi-database-accounts
197283
PAYMENTS_DATABASE_URL: postgres://postgres:password@localhost:5432/multi-database-payments
284+
SQLX_OFFLINE: ${{ matrix.offline == 'offline' }}
198285
run: cargo run -p sqlx-example-postgres-multi-database
199286

200287
- name: Multi-Tenant (Setup)
@@ -206,9 +293,38 @@ jobs:
206293
(cd payments && sqlx migrate run)
207294
sqlx migrate run
208295
296+
- name: Multi-Tenant (Prepare)
297+
if: ${{ matrix.offline }}
298+
env:
299+
DATABASE_URL: postgres://postgres:password@localhost:5432/multi-tenant
300+
run: |
301+
cargo clean -p sqlx-example-postgres-multi-tenant-accounts
302+
cargo clean -p sqlx-example-postgres-multi-tenant-payments
303+
cargo clean -p sqlx-example-postgres-multi-tenant
304+
# should include -accounts and -payments
305+
cargo sqlx prepare -- -p sqlx-example-postgres-multi-tenant
306+
307+
- name: Multi-Tenant (Check Offline)
308+
if: ${{ matrix.offline }}
309+
run: cargo check -p sqlx-example-postgres-multi-tenant
310+
311+
- name: Multi-Tenant (Prepare from .env)
312+
if: ${{ matrix.offline }}
313+
run: |
314+
echo "DATABASE_URL=postgres://postgres:password@localhost:5432/multi-tenant" > .env
315+
316+
cargo clean -p sqlx-example-postgres-multi-tenant-accounts
317+
cargo clean -p sqlx-example-postgres-multi-tenant-payments
318+
cargo clean -p sqlx-example-postgres-multi-tenant
319+
# should include -accounts and -payments
320+
cargo sqlx prepare -- -p sqlx-example-postgres-multi-tenant
321+
322+
rm .env
323+
209324
- name: Multi-Tenant (Run)
210325
env:
211326
DATABASE_URL: postgres://postgres:password@localhost:5432/multi-tenant
327+
SQLX_OFFLINE: ${{ matrix.offline == 'offline' }}
212328
run: cargo run -p sqlx-example-postgres-multi-tenant
213329

214330
- name: Preferred-Crates (Setup)
@@ -217,7 +333,7 @@ jobs:
217333
DATABASE_URL: postgres://postgres:password@localhost:5432/preferred-crates
218334
run: sqlx db setup
219335

220-
- name: Multi-Tenant (Run)
336+
- name: Preferred-Crates (Run)
221337
env:
222338
DATABASE_URL: postgres://postgres:password@localhost:5432/preferred-crates
223339
run: cargo run -p sqlx-example-postgres-preferred-crates
@@ -275,7 +391,28 @@ jobs:
275391
DATABASE_URL: sqlite://todos.sqlite
276392
run: sqlx db setup --source=examples/sqlite/todos/migrations
277393

394+
- name: Todos (Prepare)
395+
if: ${{ matrix.offline }}
396+
env:
397+
DATABASE_URL: sqlite://todos.sqlite
398+
run: cargo sqlx prepare -- -p sqlx-example-sqlite-todos
399+
400+
- name: Todos (Check Offline)
401+
if: ${{ matrix.offline }}
402+
run: |
403+
cargo clean -p sqlx-example-sqlite-todos
404+
cargo check -p sqlx-example-sqlite-todos
405+
406+
- name: Todos (Prepare from .env)
407+
if: ${{ matrix.offline }}
408+
run: |
409+
echo "DATABASE_URL=sqlite://todos.sqlite" > .env
410+
cargo clean -p sqlx-example-sqlite-todos
411+
cargo sqlx prepare -- -p sqlx-example-sqlite-todos
412+
rm .env
413+
278414
- name: TODOs (Run)
279415
env:
280416
DATABASE_URL: sqlite://todos.sqlite
417+
SQLX_OFFLINE: ${{ matrix.offline == 'offline' }}
281418
run: cargo run -p sqlx-example-sqlite-todos

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,21 @@ This section will be replaced in subsequent alpha releases. See the Git history
4343
* Significant changes to the `Migrate` trait
4444
* `sqlx::migrate::resolve_blocking()` is now `#[doc(hidden)]` and thus SemVer-exempt.
4545

46+
### Fixed
47+
48+
* [[#4053]]: fix(macros): smarter `.env` loading, caching, and invalidation [[@abonander]]
49+
* Additional credit to [[@AlexTMjugador]] ([[#4018]]) and [[@Diggsey]] ([[#4039]]) for their proposed solutions
50+
which served as a useful comparison.
51+
4652
[seaorm-2600]: https://github.com/SeaQL/sea-orm/issues/2600
4753
[feature unification]: https://doc.rust-lang.org/cargo/reference/features.html#feature-unification
4854
[preferred-crates]: examples/postgres/preferred-crates
4955

5056
[#3821]: https://github.com/launchbadge/sqlx/pull/3821
5157
[#3383]: https://github.com/launchbadge/sqlx/pull/3383
58+
[#4018]: https://github.com/launchbadge/sqlx/pull/4018
59+
[#4039]: https://github.com/launchbadge/sqlx/pull/4039
60+
[#4053]: https://github.com/launchbadge/sqlx/pull/4053
5261

5362
## 0.8.6 - 2025-05-19
5463

@@ -2951,3 +2960,4 @@ Fix docs.rs build by enabling a runtime feature in the docs.rs metadata in `Carg
29512960
[@dyc3]: https://github.com/dyc3
29522961
[@ThomWright]: https://github.com/ThomWright
29532962
[@duhby]: https://github.com/duhby
2963+
[@AlexTMjugador]: https://github.com/AlexTMjugador

Cargo.lock

Lines changed: 30 additions & 12 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)