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
This commit is contained in:
Austin Bonander
2025-10-14 17:31:12 -07:00
committed by GitHub
parent 064d649abd
commit 388c424f48
18 changed files with 622 additions and 297 deletions

View File

@@ -26,7 +26,6 @@ jobs:
- run: >
cargo build
-p sqlx-cli
--bin sqlx
--release
--no-default-features
--features mysql,postgres,sqlite,sqlx-toml
@@ -34,7 +33,9 @@ jobs:
- uses: actions/upload-artifact@v4
with:
name: sqlx-cli
path: target/release/sqlx
path: |
target/release/sqlx
target/release/cargo-sqlx
mysql:
name: MySQL Examples
@@ -42,6 +43,10 @@ jobs:
needs: sqlx-cli
timeout-minutes: 30
strategy:
matrix:
offline: ['', 'offline']
services:
mysql:
image: mysql:latest
@@ -60,7 +65,7 @@ jobs:
- run: |
ls -R /home/runner/.local/bin
chmod +x /home/runner/.local/bin/sqlx
chmod +x /home/runner/.local/bin/sqlx /home/runner/.local/bin/cargo-sqlx
echo /home/runner/.local/bin >> $GITHUB_PATH
sleep 10
@@ -77,9 +82,32 @@ jobs:
DATABASE_URL: mysql://root:password@localhost:3306/todos?ssl-mode=disabled
run: sqlx db setup
- name: Todos (Prepare)
if: ${{ matrix.offline }}
working-directory: examples/mysql/todos
env:
DATABASE_URL: mysql://root:password@localhost:3306/todos?ssl-mode=disabled
run: cargo sqlx prepare
- name: Todos (Check Offline)
if: ${{ matrix.offline }}
run: |
cargo clean -p sqlx-example-mysql-todos
cargo check -p sqlx-example-mysql-todos
- name: Todos (Prepare from .env)
if: ${{ matrix.offline }}
working-directory: examples/mysql/todos
run: |
echo "DATABASE_URL=mysql://root:password@localhost:3306/todos?ssl-mode=disabled" > .env
cargo clean -p sqlx-example-mysql-todos
cargo sqlx prepare
rm .env
- name: Todos (Run)
env:
DATABASE_URL: mysql://root:password@localhost:3306/todos?ssl-mode=disabled
SQLX_OFFLINE: ${{ matrix.offline == 'offline' }}
run: cargo run -p sqlx-example-mysql-todos
postgres:
@@ -88,6 +116,10 @@ jobs:
needs: sqlx-cli
timeout-minutes: 30
strategy:
matrix:
offline: ['', 'offline']
services:
postgres:
image: postgres:latest
@@ -106,6 +138,7 @@ jobs:
- run: |
ls -R /home/runner/.local/bin
chmod +x $HOME/.local/bin/sqlx
chmod +x $HOME/.local/bin/cargo-sqlx
echo $HOME/.local/bin >> $GITHUB_PATH
sleep 10
@@ -120,14 +153,32 @@ jobs:
DATABASE_URL: postgres://postgres:password@localhost:5432/axum-social
run: sqlx db setup
- name: Axum Social with Tests (Check)
# Test `cargo sqlx prepare` setting `DATABASE_URL` both directly and in `.env`
# This doesn't need to be done for every single example here, but should at least cover potential problem cases.
- name: Axum Social with Tests (Prepare)
if: ${{ matrix.offline }}
env:
DATABASE_URL: postgres://postgres:password@localhost:5432/axum-social
run: cargo check -p sqlx-example-postgres-axum-social
run: cargo sqlx prepare -- -p sqlx-example-postgres-axum-social
- name: Axum Social with Tests (Check Offline)
if: ${{ matrix.offline }}
run: |
cargo clean -p sqlx-example-postgres-axum-social
cargo check -p sqlx-example-postgres-axum-social
- name: Axum Social with Tests (Prepare from .env)
if: ${{ matrix.offline }}
run: |
echo "DATABASE_URL=postgres://postgres:password@localhost:5432/axum-social" > .env
cargo clean -p sqlx-example-postgres-axum-social
cargo sqlx prepare -- -p sqlx-example-postgres-axum-social
rm .env
- name: Axum Social with Tests (Test)
env:
DATABASE_URL: postgres://postgres:password@localhost:5432/axum-social
SQLX_OFFLINE: ${{ matrix.offline == 'offline' }}
run: cargo test -p sqlx-example-postgres-axum-social
# The Chat example has an interactive TUI which is not trivial to test automatically,
@@ -190,11 +241,47 @@ jobs:
(cd payments && sqlx db setup)
sqlx db setup
- name: Multi-Database (Prepare)
if: ${{ matrix.offline }}
env:
DATABASE_URL: postgres://postgres:password@localhost:5432/multi-database
ACCOUNTS_DATABASE_URL: postgres://postgres:password@localhost:5432/multi-database-accounts
PAYMENTS_DATABASE_URL: postgres://postgres:password@localhost:5432/multi-database-payments
run: |
cargo clean -p sqlx-example-postgres-multi-database-accounts
cargo clean -p sqlx-example-postgres-multi-database-payments
cargo clean -p sqlx-example-postgres-multi-database
# should include -accounts and -payments
cargo sqlx prepare -- -p sqlx-example-postgres-multi-database
- name: Multi-Database (Check Offline)
if: ${{ matrix.offline }}
run: |
cargo clean -p sqlx-example-postgres-multi-database
cargo check -p sqlx-example-postgres-multi-database
- name: Multi-Database (Prepare from .env)
if: ${{ matrix.offline }}
run: |
# Tried to get this to work with heredocs but had trouble writing tabs in YAML
echo 'DATABASE_URL=postgres://postgres:password@localhost:5432/multi-database' >.env
# Important: append, don't truncate
echo 'ACCOUNTS_DATABASE_URL=postgres://postgres:password@localhost:5432/multi-database-accounts' >> .env
echo 'PAYMENTS_DATABASE_URL=postgres://postgres:password@localhost:5432/multi-database-payments' >> .env
cargo clean -p sqlx-example-postgres-multi-database-accounts
cargo clean -p sqlx-example-postgres-multi-database-payments
cargo clean -p sqlx-example-postgres-multi-database
cargo sqlx prepare -- -p sqlx-example-postgres-multi-database
rm .env
- name: Multi-Database (Run)
env:
DATABASE_URL: postgres://postgres:password@localhost:5432/multi-database
ACCOUNTS_DATABASE_URL: postgres://postgres:password@localhost:5432/multi-database-accounts
PAYMENTS_DATABASE_URL: postgres://postgres:password@localhost:5432/multi-database-payments
SQLX_OFFLINE: ${{ matrix.offline == 'offline' }}
run: cargo run -p sqlx-example-postgres-multi-database
- name: Multi-Tenant (Setup)
@@ -206,9 +293,38 @@ jobs:
(cd payments && sqlx migrate run)
sqlx migrate run
- name: Multi-Tenant (Prepare)
if: ${{ matrix.offline }}
env:
DATABASE_URL: postgres://postgres:password@localhost:5432/multi-tenant
run: |
cargo clean -p sqlx-example-postgres-multi-tenant-accounts
cargo clean -p sqlx-example-postgres-multi-tenant-payments
cargo clean -p sqlx-example-postgres-multi-tenant
# should include -accounts and -payments
cargo sqlx prepare -- -p sqlx-example-postgres-multi-tenant
- name: Multi-Tenant (Check Offline)
if: ${{ matrix.offline }}
run: cargo check -p sqlx-example-postgres-multi-tenant
- name: Multi-Tenant (Prepare from .env)
if: ${{ matrix.offline }}
run: |
echo "DATABASE_URL=postgres://postgres:password@localhost:5432/multi-tenant" > .env
cargo clean -p sqlx-example-postgres-multi-tenant-accounts
cargo clean -p sqlx-example-postgres-multi-tenant-payments
cargo clean -p sqlx-example-postgres-multi-tenant
# should include -accounts and -payments
cargo sqlx prepare -- -p sqlx-example-postgres-multi-tenant
rm .env
- name: Multi-Tenant (Run)
env:
DATABASE_URL: postgres://postgres:password@localhost:5432/multi-tenant
SQLX_OFFLINE: ${{ matrix.offline == 'offline' }}
run: cargo run -p sqlx-example-postgres-multi-tenant
- name: Preferred-Crates (Setup)
@@ -217,7 +333,7 @@ jobs:
DATABASE_URL: postgres://postgres:password@localhost:5432/preferred-crates
run: sqlx db setup
- name: Multi-Tenant (Run)
- name: Preferred-Crates (Run)
env:
DATABASE_URL: postgres://postgres:password@localhost:5432/preferred-crates
run: cargo run -p sqlx-example-postgres-preferred-crates
@@ -275,7 +391,28 @@ jobs:
DATABASE_URL: sqlite://todos.sqlite
run: sqlx db setup --source=examples/sqlite/todos/migrations
- name: Todos (Prepare)
if: ${{ matrix.offline }}
env:
DATABASE_URL: sqlite://todos.sqlite
run: cargo sqlx prepare -- -p sqlx-example-sqlite-todos
- name: Todos (Check Offline)
if: ${{ matrix.offline }}
run: |
cargo clean -p sqlx-example-sqlite-todos
cargo check -p sqlx-example-sqlite-todos
- name: Todos (Prepare from .env)
if: ${{ matrix.offline }}
run: |
echo "DATABASE_URL=sqlite://todos.sqlite" > .env
cargo clean -p sqlx-example-sqlite-todos
cargo sqlx prepare -- -p sqlx-example-sqlite-todos
rm .env
- name: TODOs (Run)
env:
DATABASE_URL: sqlite://todos.sqlite
SQLX_OFFLINE: ${{ matrix.offline == 'offline' }}
run: cargo run -p sqlx-example-sqlite-todos