From 8443c330f6c2eefacf25c514dda38fc0b47b9a63 Mon Sep 17 00:00:00 2001 From: yaojin3616 Date: Mon, 15 Jun 2026 21:55:49 +0800 Subject: [PATCH 1/7] ci: add test branch trigger to verify drone pipeline --- .github/drone.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/drone.yml b/.github/drone.yml index 6b1410b3e..35e2dc551 100644 --- a/.github/drone.yml +++ b/.github/drone.yml @@ -292,6 +292,7 @@ trigger: branch: - main - release + - ci/test-drone # 临时添加,测试完成后删除 event: - push - pull_request From 2462f04bc8cd8bd833562c54c4bd9f415f41e5da Mon Sep 17 00:00:00 2001 From: yaojin3616 Date: Mon, 15 Jun 2026 22:36:32 +0800 Subject: [PATCH 2/7] ci: trigger pipeline test From 689c857455367a2d00d864f0054e7948b58a1da4 Mon Sep 17 00:00:00 2001 From: yaojin3616 Date: Tue, 16 Jun 2026 10:51:03 +0800 Subject: [PATCH 3/7] ci: add docker-compose.ci.yml for pipeline deploy test --- docker-compose.ci.yml | 65 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 docker-compose.ci.yml diff --git a/docker-compose.ci.yml b/docker-compose.ci.yml new file mode 100644 index 000000000..a3aac3c19 --- /dev/null +++ b/docker-compose.ci.yml @@ -0,0 +1,65 @@ +# ============================================================ +# CI 专用 Docker Compose +# 用于 Drone CI 的本地部署测试和升级测试 +# 使用预构建镜像,不构建、不挂载持久化卷 +# ============================================================ + +services: + postgres: + image: postgres:15-alpine + networks: + - default + environment: + POSTGRES_USER: clawith + POSTGRES_PASSWORD: clawith + POSTGRES_DB: clawith + healthcheck: + test: ["CMD-SHELL", "pg_isready -U clawith"] + interval: 5s + timeout: 5s + retries: 5 + + redis: + image: redis:7-alpine + networks: + - default + healthcheck: + test: ["CMD", "redis-cli", "ping"] + interval: 5s + timeout: 5s + retries: 5 + + backend: + image: clawith-backend:${IMAGE_TAG:-new} + environment: + DATABASE_URL: postgresql+asyncpg://clawith:clawith@postgres:5432/clawith + REDIS_URL: redis://redis:6379/0 + AGENT_DATA_DIR: /data/agents + AGENT_TEMPLATE_DIR: /app/agent_template + SECRET_KEY: ci-test-secret + JWT_SECRET_KEY: ci-test-jwt-secret + PROCESS_ROLE: all + CORS_ORIGINS: '["*"]' + networks: + - default + depends_on: + postgres: + condition: service_healthy + redis: + condition: service_healthy + + frontend: + image: clawith-frontend:${IMAGE_TAG:-new} + ports: + - "3008:3000" + environment: + VITE_API_URL: http://localhost:8000 + API_UPSTREAM: backend:8000 + networks: + - default + depends_on: + - backend + +networks: + default: + name: clawith_network From c1fb3ba290f16d7a623d076eb424d4bd2be1b508 Mon Sep 17 00:00:00 2001 From: yaojin3616 Date: Tue, 16 Jun 2026 11:20:57 +0800 Subject: [PATCH 4/7] ci: remove redundant apk packages, only install bash --- .github/drone.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/drone.yml b/.github/drone.yml index 35e2dc551..396d5b467 100644 --- a/.github/drone.yml +++ b/.github/drone.yml @@ -105,7 +105,7 @@ steps: - name: docker-socket path: /var/run/docker.sock commands: - - apk add --no-cache docker-cli-compose curl bash + - apk add --no-cache bash - echo "========================================" - echo "本地部署测试 全新部署验证" - echo "========================================" @@ -159,7 +159,7 @@ steps: - name: docker-socket path: /var/run/docker.sock commands: - - apk add --no-cache docker-cli-compose curl bash + - apk add --no-cache bash - echo "========================================" - echo "本地升级测试 旧版 → 新版数据库迁移验证" - echo "========================================" From 2fdd1e52d329f0f31385e8506deac25855c78a23 Mon Sep 17 00:00:00 2001 From: yaojin3616 Date: Tue, 16 Jun 2026 11:21:45 +0800 Subject: [PATCH 5/7] ci: drop --no-cache flag from apk add --- .github/drone.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/drone.yml b/.github/drone.yml index 396d5b467..4fda0657e 100644 --- a/.github/drone.yml +++ b/.github/drone.yml @@ -105,7 +105,7 @@ steps: - name: docker-socket path: /var/run/docker.sock commands: - - apk add --no-cache bash + - apk add bash - echo "========================================" - echo "本地部署测试 全新部署验证" - echo "========================================" @@ -159,7 +159,7 @@ steps: - name: docker-socket path: /var/run/docker.sock commands: - - apk add --no-cache bash + - apk add bash - echo "========================================" - echo "本地升级测试 旧版 → 新版数据库迁移验证" - echo "========================================" From a7a55294451fbf60529bebd7b9fbda9f86f9b270 Mon Sep 17 00:00:00 2001 From: yaojin3616 Date: Tue, 16 Jun 2026 12:52:02 +0800 Subject: [PATCH 6/7] fix(auth): resolve DetachedInstanceError on User.identity during registration --- backend/app/api/auth.py | 2 ++ backend/app/services/registration_service.py | 1 + 2 files changed, 3 insertions(+) diff --git a/backend/app/api/auth.py b/backend/app/api/auth.py index e943dee70..cb3681005 100644 --- a/backend/app/api/auth.py +++ b/backend/app/api/auth.py @@ -223,6 +223,8 @@ async def register_init( user.is_active = is_first_user # Active immediately if first user user.email_verified = identity.email_verified await session.flush() + else: + user.identity = identity # 5. Generate token outside transaction token = create_access_token(str(user.id), user.role) diff --git a/backend/app/services/registration_service.py b/backend/app/services/registration_service.py index a999d5fac..b4bdc4302 100644 --- a/backend/app/services/registration_service.py +++ b/backend/app/services/registration_service.py @@ -182,6 +182,7 @@ async def create_user_with_identity( "registration_source": registration_source, "is_active": is_active or identity.is_platform_admin, }) + user.identity = identity # Link to OrgMember if exists await self.bind_org_member(user) From f4df71a04b4f0474297c7d59619413a5ae5ce491 Mon Sep 17 00:00:00 2001 From: yaojin3616 Date: Tue, 16 Jun 2026 14:34:28 +0800 Subject: [PATCH 7/7] fix(auth): reject register_init for passwordless/synced identities --- backend/app/api/auth.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/backend/app/api/auth.py b/backend/app/api/auth.py index cb3681005..091cdeb8a 100644 --- a/backend/app/api/auth.py +++ b/backend/app/api/auth.py @@ -175,6 +175,13 @@ async def register_init( detail="Username already taken. Please choose a different username.", ) + # Reject registration if the identity exists but has no password set (SSO/synced users) + if identity.password_hash is None: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail="Email already registered via SSO/sync. Please use password reset to set a password, or log in via SSO.", + ) + # Verify password outside transaction if identity.password_hash and not await verify_password_async(data.password, identity.password_hash): raise HTTPException(