The Push Docker image step is failing post-merge of CAR-1362 with
buildx "unknown" error after layers push successfully. The pre-existing
failure was masked by the cache export error.
Simplify the Push step to match the proven-green cartsnitch/auth/ci.yml
pattern: drop `file: ./Dockerfile` (default) and `build-args:`
(APT_CACHE_BUST is only used to bust apt cache in stage 1 of multi-
stage build, not needed for the rebuilt image). Keep `if: github.event_name
== "push"` to skip on pull_request events.
Diff: 4 lines removed from .gitea/workflows/ci.yml Push step.
Co-authored-by: Paperclip <noreply@paperclip.ing>
The build-and-push job fails post-merge of CAR-1356 REGISTRY_TOKEN fix:
cache-from/cache-to: type=gha backend does not exist on Gitea. Build
succeeds but post-build cache export fails and cascades to skipping the
Push Docker image step. Confirmed in uat run 3444 + dev run 3445.
Per CAR-1362, drop cache-from and cache-to from both Build and Push
Docker image steps. Matches proven-green cartsnitch/auth/ci.yml pattern.
Refs: CAR-1362, CAR-1356, CAR-1330, CAR-1357.
Co-authored-by: Paperclip <noreply@paperclip.ing>
Squashed fix swaps github.token → secrets.REGISTRY_TOKEN at .gitea/workflows/ci.yml:121, matching the proven-green cartsnitch/auth pattern (CAR-1009). Parity fix with uat PR #49 to prevent reintroduction on next dev→uat promotion.
Note: includes 3 absorbed lint/typecheck commits from PR #48 (already merged to dev via #48) to unblock CI on this branch. No app code changes; one-line CI config swap only.
QA: PR #50 approved by @cs_charlie (review id 4616); CI run 3443 lint/typecheck/test all green.
Co-authored-by: Barcode Betty <32+cs_betty@noreply.git.farh.net>
Co-committed-by: Barcode Betty <32+cs_betty@noreply.git.farh.net>
Three CI-blocking issues on dev branch (also present on uat, fixed in 2b20946):
1. tests/conftest.py — remove extra blank line (ruff format).
2. src/cartsnitch_api/middleware/rate_limit.py — delete duplicate
_public_limiter/_auth_limiter/_auth_strict_limiter forward-decl block
(the second occurrence; mypy no-redef).
3. src/cartsnitch_api/cache.py:38 — annotate
value: str | bytes | None so mypy doesn't widen redis client return
to Any (no-any-return).
Verified: ruff check . && ruff format --check . && mypy src/cartsnitch_api
all pass.
Sibling of CAR-1330 (which fixes uat directly). Heals dev so future
dev → uat promotions stay green.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
The api typecheck job is continue-on-error but still posts a failure
status that blocks merges. Three pre-existing mypy errors on dev were
inherited by every PR based on it:
1. middleware/rate_limit.py: duplicate 'name already defined' for
_public_limiter, _auth_limiter, _auth_strict_limiter (declared at
lines 111-113 and again at 124-126). The second set is redundant
because actual assignment happens inside the if/else below.
2. cache.py:43 - 'Returning Any' from .get(); the redis client's get()
return type isn't narrowed to bytes|str, so the final 'return value'
branch is Any. Wrap with str() to satisfy the declared str|None.
3. middleware/rate_limit.py:150 - 'Returning Any' from _get_client_ip.
request.headers.get() and request.client.host are typed Any; wrap
the branches with str() to match the declared str return.
Refs CAR-1335.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
- tests/test_openapi.py: collapse 2 blank lines to 1 (ruff format)
- tests/conftest.py: collapse 2 blank lines to 1 (ruff format)
These format nits block lint (a hard gate). The conftest.py one was
introduced in CAR-1132 (#42) and would have blocked every subsequent PR
on dev until fixed.
Refs CAR-1335, CAR-1135.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
- main.py: add docstring inside the lifespan function explaining why
dispose_engine is lazy-imported rather than top-level. The original
import path (top-level) crashed the container at import time with
'ImportError: cannot import name dispose_engine from cartsnitch_api.database'
when database.py was stale or stripped during a CI build. Lazy import
keeps the engine disposal behavior while preventing the module-load
crash.
- tests/test_openapi.py: add test_dispose_engine_importable_from_database
that asserts dispose_engine is importable and callable. This is the
exact path the deployed UAT image was failing on, captured as a
regression test so a future regression lands in CI before deploy.
Refs CAR-1135.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
QA approved by Checkout Charlie; CTO Dev review approved by Savannah Savings. Adds pool_timeout=30 and DB-connectivity /health probe. Strict CI improvement (lint+typecheck green); remaining test failure pre-existing on dev, tracked under CAR-1132/PR#42.
Add missing blank line between the _set_timestamp_defaults helper
and the next top-level constant so `ruff format --check .` passes.
Pre-existing on dev's HEAD; surfaced after rebasing PR #39 onto dev
in 2b20946.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
QA review of PR #39 (CAR-1121) identified three blocking issues; this
commit addresses all three plus the typecheck errors flagged as CI RED.
CAR-1077 (PR #39) changes:
- database.py: add pool_timeout=30 so the engine fails fast when the
connection pool is exhausted (defends against the "server closed
connection unexpectedly" pod failures).
- routes/health.py: /health now calls SELECT 1 through Depends(get_db)
and raises HTTPException(503) when the database is unreachable, so
Kubernetes readiness probes can correctly mark the pod unhealthy and
stop routing traffic to it. Logs the failure at exception level for
observability.
- Drop .mcp.json from this PR (root-level MCP server config, not
related to the pool fix; tracked separately).
CI typecheck fixes (pre-existing on dev, were failing mypy on PR #39):
- auth/passwords.py: cast bcrypt return values so mypy doesn't widen
to Any.
- config.py: silence the false-positive call-arg on Settings() — the
three required fields are populated from the environment by
pydantic-settings at runtime.
- cache.py: coerce the bytes/str union returned by the redis client
to the documented str | None return type.
- middleware/rate_limit.py: annotate the three module-level limiters
with the RateLimitBackend protocol, cast the redis zrange score to
float before arithmetic, and add max_requests/window_seconds to the
protocol so the response-header builder can read them.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-06-02 14:53:16 +00:00
9 changed files with 55 additions and 27 deletions
"""Regression for CAR-1135: api main.py used to import dispose_engine
at module level. A stale database.py (no dispose_engine) crashed the
container at import time with ImportError on line 9. The fix moved
the import inside the lifespan function, but `dispose_engine` must
still be importable from `cartsnitch_api.database` for the lifespan
teardown to actually close pooled connections.
"""
assertcallable(dispose_engine)
assertdispose_engine.__name__=="dispose_engine"
EXPECTED_ROUTES=[
# Auth (3 — register/login/refresh are handled by Better-Auth service)
("get","/auth/me"),
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.