diff --git a/.dockerignore b/.dockerignore index 6c1161b7..cfde6de8 100644 --- a/.dockerignore +++ b/.dockerignore @@ -3,12 +3,14 @@ .gitignore # Python -__pycache__ -*.pyc -*.pyo +**/__pycache__/ +**/*.pyc +**/*.pyo +**/.pytest_cache/ venv/ .venv/ -*.egg-info/ +**/*.egg-info/ +packages/*/build/ # Node node_modules/ @@ -31,6 +33,7 @@ static/ # Docs .claude/ +.docs/ docs/ *.md !README.md diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 508f48b4..3bcde962 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -121,8 +121,9 @@ jobs: labels: ${{ steps.meta.outputs.labels }} build-args: | VERSION=${{ steps.vars.outputs.version }} - cache-from: type=gha - cache-to: type=gha,mode=max + # 固定 registry 引用,让不同发布 tag 复用包含中间 builder 的缓存。 + cache-from: type=registry,ref=${{ env.IMAGE_NAME }}:buildcache + cache-to: type=registry,ref=${{ env.IMAGE_NAME }}:buildcache,mode=max - name: Generate release notes (tag push only) if: ${{ github.event_name == 'push' }} diff --git a/Dockerfile b/Dockerfile index 21961a37..ce3295d4 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,7 +2,8 @@ # 多阶段构建,减小最终镜像大小 # ===== Stage 1: 前端构建 ===== -FROM node:24.14.0-alpine AS frontend-builder +# 静态资源与目标架构无关,使用构建机原生平台,避免 ARM 镜像构建时通过 QEMU 跑 pnpm。 +FROM --platform=$BUILDPLATFORM node:24.14.0-alpine AS frontend-builder WORKDIR /app/frontend @@ -42,9 +43,6 @@ RUN sed 's/^-e //' requirements-runtime.txt > /tmp/requirements-runtime.txt \ # ===== Stage 3: Python 运行环境 ===== FROM python:3.11-slim-bookworm -# 版本号(构建时传入) -ARG VERSION=dev - WORKDIR /app # 安装系统依赖 @@ -98,7 +96,8 @@ COPY src/ ./src/ COPY server.py ./ COPY prompts/ ./prompts/ -# 写入版本号 +# 写入版本号;延后声明,避免换版本号时让系统依赖安装缓存失效。 +ARG VERSION=dev RUN echo "${VERSION}" > VERSION # 从前端构建阶段复制静态文件 diff --git a/tests/test_assistant_task_runner.py b/tests/test_assistant_task_runner.py index 53419ea4..e1e74728 100644 --- a/tests/test_assistant_task_runner.py +++ b/tests/test_assistant_task_runner.py @@ -213,11 +213,10 @@ def complete_task_with_message(self, task_id, conversation_id, content): async def run(): runner.start_message(task_id, conversation_id) - for _ in range(20): - if repository.get_task_snapshot(task_id)["status"] == "completed": - return - await asyncio.sleep(0.01) - raise AssertionError("runner did not finish") + # Wait for the worker before reading the shared in-memory SQLite connection. + async with asyncio.timeout(5): + while runner.is_running(task_id): + await asyncio.sleep(0.01) asyncio.run(run()) events = repository.list_task_events(task_id, after_sequence=2)