fix: Immich v2.7.5 compat, supply-chain hardening, and quality fixes (0.5.2) (#23)

* fix: Immich v2.7.5 compat, supply-chain hardening, and quality fixes (0.5.2)

- Remove assetCount pre-filter broken by Immich v2.7.5 API change; check
  MIN_FACE_COUNT after fetch_all_assets instead
- Replace curl|sh uv installer with COPY --from Docker stage (supply chain)
- Fix HEALTHCHECK to use kill -0 on PID file instead of static file test
- Fix CONFIG_FILE path to resolve inside DATA_DIR for volume persistence
- Fix EmbeddingCache singleton to re-init when cache_dir changes
- Fix fd leak in _suppress_output() with nested finally closes
- Fix silent exception on SQLite connection close in upload_tracker
- Log unexpected Frigate API keys at DEBUG in get_all_frigate_person_files
- Add reconcile FIFO-mapping debug log
- Pin all CI action SHAs; update setup-uv v8.2.0, upload/download-artifact,
  ruff-action v4.0.0

* chore: update lockfile

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
This commit is contained in:
2026-06-14 19:15:20 -04:00
committed by GitHub
co-authored by github-actions[bot]
parent d99d607fc8
commit 8acf8b52b8
17 changed files with 144 additions and 92 deletions
+13 -5
View File
@@ -9,7 +9,7 @@ from typing import ClassVar
from dotenv import load_dotenv
from rich.prompt import Prompt
CONFIG_FILE = Path(".immich_config.json")
_LEGACY_CONFIG_FILE = Path(".immich_config.json") # pre-v0.6: lived in process CWD, not on a volume
class _Config:
@@ -113,9 +113,13 @@ class _Config:
# Fall back to config file only when the env var is genuinely absent (None).
# An explicitly empty env var (IMMICH_URL="") takes priority over the file.
if CONFIG_FILE.exists():
# Prefer DATA_DIR/.immich_config.json (volume-safe in Docker) and fall back
# to the legacy CWD path so existing installations continue to work.
_data_cfg = Path(self.DATA_DIR) / ".immich_config.json"
config_file = _data_cfg if _data_cfg.exists() else _LEGACY_CONFIG_FILE
if config_file.exists():
try:
data = json.loads(CONFIG_FILE.read_text())
data = json.loads(config_file.read_text())
if self.IMMICH_URL is None:
self.IMMICH_URL = data.get("IMMICH_URL")
if os.getenv("OUTPUT_DIR") is None:
@@ -135,9 +139,13 @@ class _Config:
API_KEY is intentionally excluded — store it in .env or as an
environment variable instead of a plain-text config file.
Writes to DATA_DIR/.immich_config.json so the file survives container
restarts when DATA_DIR is a mounted volume.
"""
config_file = Path(self.DATA_DIR) / ".immich_config.json"
try:
CONFIG_FILE.write_text(
Path(self.DATA_DIR).mkdir(parents=True, exist_ok=True)
config_file.write_text(
json.dumps(
{
"IMMICH_URL": self.IMMICH_URL,
@@ -146,7 +154,7 @@ class _Config:
indent=2,
)
)
logging.info("Configuration saved to %s", CONFIG_FILE)
logging.info("Configuration saved to %s", config_file)
except OSError as e:
logging.error("Failed to save config: %s", e)