Fix git not found error crashing document uploads in container
All checks were successful
Build & Deploy / build-and-deploy (push) Successful in 3m13s
All checks were successful
Build & Deploy / build-and-deploy (push) Successful in 3m13s
Install git in Docker image and wrap all subprocess git calls in try/except so a missing or failing git binary never kills an upload that already succeeded. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -87,7 +87,7 @@ VALUES (
|
|||||||
'752cebdd-6748-4a04-aacd-c7ab0294ef33',
|
'752cebdd-6748-4a04-aacd-c7ab0294ef33',
|
||||||
'agent_completion',
|
'agent_completion',
|
||||||
'סוכן סיים משימה — נדרשת בדיקה והחלטה על הצעד הבא',
|
'סוכן סיים משימה — נדרשת בדיקה והחלטה על הצעד הבא',
|
||||||
'pending',
|
'queued',
|
||||||
'agent'
|
'agent'
|
||||||
);"
|
);"
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ VALUES (
|
|||||||
'752cebdd-6748-4a04-aacd-c7ab0294ef33',
|
'752cebdd-6748-4a04-aacd-c7ab0294ef33',
|
||||||
'agent_completion',
|
'agent_completion',
|
||||||
'מייצא טיוטה סיים משימה — נדרשת בדיקה',
|
'מייצא טיוטה סיים משימה — נדרשת בדיקה',
|
||||||
'pending', 'agent'
|
'queued', 'agent'
|
||||||
);"
|
);"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -116,6 +116,6 @@ VALUES (
|
|||||||
'752cebdd-6748-4a04-aacd-c7ab0294ef33',
|
'752cebdd-6748-4a04-aacd-c7ab0294ef33',
|
||||||
'agent_completion',
|
'agent_completion',
|
||||||
'מגיה מסמכים סיים משימה — נדרשת בדיקה',
|
'מגיה מסמכים סיים משימה — נדרשת בדיקה',
|
||||||
'pending', 'agent'
|
'queued', 'agent'
|
||||||
);"
|
);"
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -121,6 +121,6 @@ VALUES (
|
|||||||
'752cebdd-6748-4a04-aacd-c7ab0294ef33',
|
'752cebdd-6748-4a04-aacd-c7ab0294ef33',
|
||||||
'agent_completion',
|
'agent_completion',
|
||||||
'בודק איכות סיים משימה — נדרשת בדיקה',
|
'בודק איכות סיים משימה — נדרשת בדיקה',
|
||||||
'pending', 'agent'
|
'queued', 'agent'
|
||||||
);"
|
);"
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ VALUES (
|
|||||||
'752cebdd-6748-4a04-aacd-c7ab0294ef33',
|
'752cebdd-6748-4a04-aacd-c7ab0294ef33',
|
||||||
'agent_completion',
|
'agent_completion',
|
||||||
'חוקר תקדימים סיים משימה — נדרשת בדיקה',
|
'חוקר תקדימים סיים משימה — נדרשת בדיקה',
|
||||||
'pending', 'agent'
|
'queued', 'agent'
|
||||||
);"
|
);"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -159,7 +159,7 @@ VALUES (
|
|||||||
'752cebdd-6748-4a04-aacd-c7ab0294ef33',
|
'752cebdd-6748-4a04-aacd-c7ab0294ef33',
|
||||||
'agent_completion',
|
'agent_completion',
|
||||||
'כותב החלטה סיים משימה — נדרשת בדיקה',
|
'כותב החלטה סיים משימה — נדרשת בדיקה',
|
||||||
'pending', 'agent'
|
'queued', 'agent'
|
||||||
);"
|
);"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ WORKDIR /app
|
|||||||
|
|
||||||
# Install Node.js 20.x
|
# Install Node.js 20.x
|
||||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||||
curl ca-certificates \
|
curl ca-certificates git \
|
||||||
&& curl -fsSL https://deb.nodesource.com/setup_20.x | bash - \
|
&& curl -fsSL https://deb.nodesource.com/setup_20.x | bash - \
|
||||||
&& apt-get install -y --no-install-recommends nodejs \
|
&& apt-get install -y --no-install-recommends nodejs \
|
||||||
&& rm -rf /var/lib/apt/lists/*
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|||||||
@@ -106,17 +106,20 @@ async def case_create(
|
|||||||
notes_file = case_dir / "notes.md"
|
notes_file = case_dir / "notes.md"
|
||||||
notes_file.write_text(f"# הערות - תיק {case_number}\n\n{notes}\n")
|
notes_file.write_text(f"# הערות - תיק {case_number}\n\n{notes}\n")
|
||||||
|
|
||||||
# Initialize git repo
|
# Initialize git repo (best-effort)
|
||||||
subprocess.run(["git", "init"], cwd=case_dir, capture_output=True)
|
try:
|
||||||
subprocess.run(["git", "add", "."], cwd=case_dir, capture_output=True)
|
subprocess.run(["git", "init"], cwd=case_dir, capture_output=True)
|
||||||
subprocess.run(
|
subprocess.run(["git", "add", "."], cwd=case_dir, capture_output=True)
|
||||||
["git", "commit", "-m", f"אתחול תיק {case_number}: {title}"],
|
subprocess.run(
|
||||||
cwd=case_dir,
|
["git", "commit", "-m", f"אתחול תיק {case_number}: {title}"],
|
||||||
capture_output=True,
|
cwd=case_dir,
|
||||||
env={"GIT_AUTHOR_NAME": "Ezer Mishpati", "GIT_AUTHOR_EMAIL": "legal@local",
|
capture_output=True,
|
||||||
"GIT_COMMITTER_NAME": "Ezer Mishpati", "GIT_COMMITTER_EMAIL": "legal@local",
|
env={"GIT_AUTHOR_NAME": "Ezer Mishpati", "GIT_AUTHOR_EMAIL": "legal@local",
|
||||||
"PATH": "/usr/bin:/bin"},
|
"GIT_COMMITTER_NAME": "Ezer Mishpati", "GIT_COMMITTER_EMAIL": "legal@local",
|
||||||
)
|
"PATH": "/usr/bin:/bin"},
|
||||||
|
)
|
||||||
|
except Exception:
|
||||||
|
pass # git not available — non-critical
|
||||||
|
|
||||||
return json.dumps(case, default=str, ensure_ascii=False, indent=2)
|
return json.dumps(case, default=str, ensure_ascii=False, indent=2)
|
||||||
|
|
||||||
@@ -199,20 +202,23 @@ async def case_update(
|
|||||||
|
|
||||||
updated = await db.update_case(UUID(case["id"]), **fields)
|
updated = await db.update_case(UUID(case["id"]), **fields)
|
||||||
|
|
||||||
# Git commit the update
|
# Git commit the update (best-effort)
|
||||||
case_dir = config.find_case_dir(case_number)
|
try:
|
||||||
if case_dir.exists():
|
case_dir = config.find_case_dir(case_number)
|
||||||
case_json = case_dir / "case.json"
|
if case_dir.exists():
|
||||||
case_json.write_text(json.dumps(updated, default=str, ensure_ascii=False, indent=2))
|
case_json = case_dir / "case.json"
|
||||||
subprocess.run(["git", "add", "case.json"], cwd=case_dir, capture_output=True)
|
case_json.write_text(json.dumps(updated, default=str, ensure_ascii=False, indent=2))
|
||||||
subprocess.run(
|
subprocess.run(["git", "add", "case.json"], cwd=case_dir, capture_output=True)
|
||||||
["git", "commit", "-m", f"עדכון תיק: {', '.join(fields.keys())}"],
|
subprocess.run(
|
||||||
cwd=case_dir,
|
["git", "commit", "-m", f"עדכון תיק: {', '.join(fields.keys())}"],
|
||||||
capture_output=True,
|
cwd=case_dir,
|
||||||
env={"GIT_AUTHOR_NAME": "Ezer Mishpati", "GIT_AUTHOR_EMAIL": "legal@local",
|
capture_output=True,
|
||||||
"GIT_COMMITTER_NAME": "Ezer Mishpati", "GIT_COMMITTER_EMAIL": "legal@local",
|
env={"GIT_AUTHOR_NAME": "Ezer Mishpati", "GIT_AUTHOR_EMAIL": "legal@local",
|
||||||
"PATH": "/usr/bin:/bin"},
|
"GIT_COMMITTER_NAME": "Ezer Mishpati", "GIT_COMMITTER_EMAIL": "legal@local",
|
||||||
)
|
"PATH": "/usr/bin:/bin"},
|
||||||
|
)
|
||||||
|
except Exception:
|
||||||
|
pass # git not available — non-critical
|
||||||
|
|
||||||
return json.dumps(updated, default=str, ensure_ascii=False, indent=2)
|
return json.dumps(updated, default=str, ensure_ascii=False, indent=2)
|
||||||
|
|
||||||
|
|||||||
@@ -67,31 +67,34 @@ async def document_upload(
|
|||||||
await db.update_document(UUID(doc["id"]), doc_type=classified_type)
|
await db.update_document(UUID(doc["id"]), doc_type=classified_type)
|
||||||
doc["doc_type"] = classified_type
|
doc["doc_type"] = classified_type
|
||||||
|
|
||||||
# Git commit
|
# Git commit (best-effort — don't fail upload on git errors)
|
||||||
repo_dir = config.find_case_dir(case_number)
|
try:
|
||||||
if repo_dir.exists():
|
repo_dir = config.find_case_dir(case_number)
|
||||||
subprocess.run(["git", "add", "."], cwd=repo_dir, capture_output=True)
|
if repo_dir.exists():
|
||||||
doc_type_hebrew = {
|
subprocess.run(["git", "add", "."], cwd=repo_dir, capture_output=True)
|
||||||
"appeal": "כתב ערר",
|
doc_type_hebrew = {
|
||||||
"response": "תשובה",
|
"appeal": "כתב ערר",
|
||||||
"protocol": "פרוטוקול",
|
"response": "תשובה",
|
||||||
"plan": "תכנית",
|
"protocol": "פרוטוקול",
|
||||||
"permit": "היתר",
|
"plan": "תכנית",
|
||||||
"court_decision": "פסק דין",
|
"permit": "היתר",
|
||||||
"decision": "החלטה",
|
"court_decision": "פסק דין",
|
||||||
"appraisal": "שומה",
|
"decision": "החלטה",
|
||||||
"objection": "התנגדות",
|
"appraisal": "שומה",
|
||||||
"exhibit": "נספח",
|
"objection": "התנגדות",
|
||||||
"reference": "מסמך עזר",
|
"exhibit": "נספח",
|
||||||
}.get(actual_doc_type, actual_doc_type)
|
"reference": "מסמך עזר",
|
||||||
subprocess.run(
|
}.get(actual_doc_type, actual_doc_type)
|
||||||
["git", "commit", "-m", f"הוספת {doc_type_hebrew}: {title}"],
|
subprocess.run(
|
||||||
cwd=repo_dir,
|
["git", "commit", "-m", f"הוספת {doc_type_hebrew}: {title}"],
|
||||||
capture_output=True,
|
cwd=repo_dir,
|
||||||
env={"GIT_AUTHOR_NAME": "Ezer Mishpati", "GIT_AUTHOR_EMAIL": "legal@local",
|
capture_output=True,
|
||||||
"GIT_COMMITTER_NAME": "Ezer Mishpati", "GIT_COMMITTER_EMAIL": "legal@local",
|
env={"GIT_AUTHOR_NAME": "Ezer Mishpati", "GIT_AUTHOR_EMAIL": "legal@local",
|
||||||
"PATH": "/usr/bin:/bin"},
|
"GIT_COMMITTER_NAME": "Ezer Mishpati", "GIT_COMMITTER_EMAIL": "legal@local",
|
||||||
)
|
"PATH": "/usr/bin:/bin"},
|
||||||
|
)
|
||||||
|
except Exception:
|
||||||
|
pass # git not available in container — non-critical
|
||||||
|
|
||||||
return json.dumps({
|
return json.dumps({
|
||||||
"document": doc,
|
"document": doc,
|
||||||
|
|||||||
74
web/app.py
74
web/app.py
@@ -2565,25 +2565,28 @@ async def _process_tagged_document(task_id: str, dest: Path, case_number: str, c
|
|||||||
_progress[task_id] = {"status": "processing", "filename": display_name, "step": "extracting"}
|
_progress[task_id] = {"status": "processing", "filename": display_name, "step": "extracting"}
|
||||||
result = await processor.process_document(doc_id, case_id)
|
result = await processor.process_document(doc_id, case_id)
|
||||||
|
|
||||||
# Git commit + push
|
# Git commit + push (best-effort — don't fail upload on git errors)
|
||||||
repo_dir = config.find_case_dir(case_number)
|
try:
|
||||||
if repo_dir.exists():
|
repo_dir = config.find_case_dir(case_number)
|
||||||
env = {
|
if repo_dir.exists():
|
||||||
"GIT_AUTHOR_NAME": "Ezer Mishpati", "GIT_AUTHOR_EMAIL": "legal@local",
|
env = {
|
||||||
"GIT_COMMITTER_NAME": "Ezer Mishpati", "GIT_COMMITTER_EMAIL": "legal@local",
|
"GIT_AUTHOR_NAME": "Ezer Mishpati", "GIT_AUTHOR_EMAIL": "legal@local",
|
||||||
"PATH": "/usr/bin:/bin",
|
"GIT_COMMITTER_NAME": "Ezer Mishpati", "GIT_COMMITTER_EMAIL": "legal@local",
|
||||||
}
|
"PATH": "/usr/bin:/bin",
|
||||||
doc_type_hebrew = DOC_TYPE_NAMES.get(doc_type, doc_type)
|
}
|
||||||
subprocess.run(["git", "add", "."], cwd=repo_dir, capture_output=True)
|
doc_type_hebrew = DOC_TYPE_NAMES.get(doc_type, doc_type)
|
||||||
subprocess.run(
|
subprocess.run(["git", "add", "."], cwd=repo_dir, capture_output=True)
|
||||||
["git", "commit", "-m", f"הוספת {doc_type_hebrew}: {display_name}"],
|
subprocess.run(
|
||||||
cwd=repo_dir, capture_output=True, env=env,
|
["git", "commit", "-m", f"הוספת {doc_type_hebrew}: {display_name}"],
|
||||||
)
|
cwd=repo_dir, capture_output=True, env=env,
|
||||||
# Try to push to Gitea (non-blocking)
|
)
|
||||||
subprocess.run(["git", "push"], cwd=repo_dir, capture_output=True, env={
|
# Try to push to Gitea (non-blocking)
|
||||||
**env,
|
subprocess.run(["git", "push"], cwd=repo_dir, capture_output=True, env={
|
||||||
"GIT_TERMINAL_PROMPT": "0",
|
**env,
|
||||||
})
|
"GIT_TERMINAL_PROMPT": "0",
|
||||||
|
})
|
||||||
|
except Exception:
|
||||||
|
logger.warning("Git commit/push failed for %s (non-critical)", display_name)
|
||||||
|
|
||||||
_progress[task_id] = {
|
_progress[task_id] = {
|
||||||
"status": "completed",
|
"status": "completed",
|
||||||
@@ -2821,21 +2824,24 @@ async def _process_case_document(task_id: str, source: Path, req: ClassifyReques
|
|||||||
_progress[task_id] = {"status": "processing", "filename": req.filename, "step": "extracting"}
|
_progress[task_id] = {"status": "processing", "filename": req.filename, "step": "extracting"}
|
||||||
result = await processor.process_document(UUID(doc["id"]), case_id)
|
result = await processor.process_document(UUID(doc["id"]), case_id)
|
||||||
|
|
||||||
# Git commit
|
# Git commit (best-effort)
|
||||||
repo_dir = config.find_case_dir(req.case_number)
|
try:
|
||||||
if repo_dir.exists():
|
repo_dir = config.find_case_dir(req.case_number)
|
||||||
subprocess.run(["git", "add", "."], cwd=repo_dir, capture_output=True)
|
if repo_dir.exists():
|
||||||
doc_type_hebrew = {
|
subprocess.run(["git", "add", "."], cwd=repo_dir, capture_output=True)
|
||||||
"appeal": "כתב ערר", "response": "תשובה", "decision": "החלטה",
|
doc_type_hebrew = {
|
||||||
"reference": "מסמך עזר", "exhibit": "נספח",
|
"appeal": "כתב ערר", "response": "תשובה", "decision": "החלטה",
|
||||||
}.get(req.doc_type, req.doc_type)
|
"reference": "מסמך עזר", "exhibit": "נספח",
|
||||||
subprocess.run(
|
}.get(req.doc_type, req.doc_type)
|
||||||
["git", "commit", "-m", f"הוספת {doc_type_hebrew}: {title}"],
|
subprocess.run(
|
||||||
cwd=repo_dir, capture_output=True,
|
["git", "commit", "-m", f"הוספת {doc_type_hebrew}: {title}"],
|
||||||
env={"GIT_AUTHOR_NAME": "Ezer Mishpati", "GIT_AUTHOR_EMAIL": "legal@local",
|
cwd=repo_dir, capture_output=True,
|
||||||
"GIT_COMMITTER_NAME": "Ezer Mishpati", "GIT_COMMITTER_EMAIL": "legal@local",
|
env={"GIT_AUTHOR_NAME": "Ezer Mishpati", "GIT_AUTHOR_EMAIL": "legal@local",
|
||||||
"PATH": "/usr/bin:/bin"},
|
"GIT_COMMITTER_NAME": "Ezer Mishpati", "GIT_COMMITTER_EMAIL": "legal@local",
|
||||||
)
|
"PATH": "/usr/bin:/bin"},
|
||||||
|
)
|
||||||
|
except Exception:
|
||||||
|
logger.warning("Git commit failed for %s (non-critical)", req.filename)
|
||||||
|
|
||||||
# Remove from uploads
|
# Remove from uploads
|
||||||
source.unlink(missing_ok=True)
|
source.unlink(missing_ok=True)
|
||||||
|
|||||||
Reference in New Issue
Block a user