From a19b659f07c8f212a0514bf4af1affe657fa0fe1 Mon Sep 17 00:00:00 2001 From: Your Name Date: Mon, 29 Jun 2026 13:14:51 +0800 Subject: [PATCH] fix(ci): include product manifest in api image --- .gitea/workflows/cd.yaml | 2 ++ apps/api/Dockerfile | 1 + .../test_product_awoooi_manifest_standard_api.py | 11 +++++++++++ docs/LOGBOOK.md | 14 ++++++++++++++ ops/runner/test_cd_controlled_runtime_profile.py | 1 + 5 files changed, 29 insertions(+) diff --git a/.gitea/workflows/cd.yaml b/.gitea/workflows/cd.yaml index 316c639c..66a651e3 100644 --- a/.gitea/workflows/cd.yaml +++ b/.gitea/workflows/cd.yaml @@ -224,6 +224,8 @@ jobs: ;; apps/api/src/services/heartbeat_report_service.py) ;; + apps/api/Dockerfile) + ;; apps/api/src/services/awoooi_gitea_onboarding_warning_step_dashboard.py) ;; apps/api/src/services/awoooi_gitea_onboarding_warning_step_owner_package.py) diff --git a/apps/api/Dockerfile b/apps/api/Dockerfile index a627626d..4625686e 100644 --- a/apps/api/Dockerfile +++ b/apps/api/Dockerfile @@ -83,6 +83,7 @@ COPY --chown=appuser:appuser k8s/ ./k8s/ COPY --chown=appuser:appuser infra/ansible/ ./infra/ansible/ # 2026-04-10 Claude Sonnet 4.6: RAG 知識庫索引來源 (ADR-067 Phase 33) COPY --chown=appuser:appuser docs/ ./docs/ +COPY --chown=appuser:appuser product.awoooi.yaml ./product.awoooi.yaml COPY --chown=appuser:appuser .agents/skills/ ./.agents/skills/ # 2026-05-04 Claude Sonnet 4.6 (Task 1.2): hermes agent_loader 的 system prompt 來源 # agent_loader.py 預設讀 /app/.claude/agents/,對應 K8s AGENTS_DIR 環境變數 diff --git a/apps/api/tests/test_product_awoooi_manifest_standard_api.py b/apps/api/tests/test_product_awoooi_manifest_standard_api.py index e333e6a6..56411a11 100644 --- a/apps/api/tests/test_product_awoooi_manifest_standard_api.py +++ b/apps/api/tests/test_product_awoooi_manifest_standard_api.py @@ -1,5 +1,7 @@ from __future__ import annotations +from pathlib import Path + from fastapi import FastAPI from fastapi.testclient import TestClient @@ -44,3 +46,12 @@ def test_product_awoooi_manifest_standard_endpoint_returns_snapshot(): assert data["status"] == "ready_for_product_manifest_adoption" assert data["rollups"]["source_readiness_percent"] == 100 assert data["operation_boundaries"]["repo_creation_allowed"] is False + + +def test_api_image_copies_product_manifest() -> None: + dockerfile = Path(__file__).resolve().parents[3] / "apps" / "api" / "Dockerfile" + + assert ( + "COPY --chown=appuser:appuser product.awoooi.yaml ./product.awoooi.yaml" + in dockerfile.read_text(encoding="utf-8") + ) diff --git a/docs/LOGBOOK.md b/docs/LOGBOOK.md index 017da625..b02de043 100644 --- a/docs/LOGBOOK.md +++ b/docs/LOGBOOK.md @@ -1,3 +1,17 @@ +## 2026-06-29 — 13:35 P0-002 product manifest API image packaging 修補 + +**完成內容**: +- `cd.yaml #3879` / `d128f298` 已讀回 `Success`,deploy marker `5920c95ad chore(cd): deploy d128f29 [skip ci]` 已進 Gitea main;`0c8d4e88` 已修 P0-004 source readiness production layout。 +- Production `/api/v1/agents/product-awoooi-manifest-standard` 已上線,但 readback 顯示 `product.awoooi.yaml present=false`;根因為 API image 複製 `docs/` 但未複製 repo root 的 `product.awoooi.yaml`。 +- `apps/api/Dockerfile` 複製 `product.awoooi.yaml` 到 `/app/product.awoooi.yaml`,讓 P0-002 readiness loader 在 production image layout 下可讀回 manifest。 +- CD controlled-runtime profile 納入 `apps/api/Dockerfile`,並以 runner profile test 與 API image copy test 鎖住。 + +**驗證目標**: +- Focused:`test_product_awoooi_manifest_standard_api.py`、`test_p0_cicd_baseline_source_readiness_api.py`、`ops/runner/test_cd_controlled_runtime_profile.py`。 +- Source / workflow guards:`py_compile`、`guard-gitea-runner-pressure.py`、`check-gitea-step-env-secrets.js`、`git diff --check`。 + +**邊界**:未使用 GitHub / `gh` / GitHub API;未 workflow_dispatch;未讀 token / cookie / session / secret / auth / `.env`;未操作 host / Docker / K8s / DB;未 force push。 + ## 2026-06-29 — 13:22 P0-004 source readiness production layout readback 修正 **完成內容**: diff --git a/ops/runner/test_cd_controlled_runtime_profile.py b/ops/runner/test_cd_controlled_runtime_profile.py index f55f73a8..b2a6cb37 100644 --- a/ops/runner/test_cd_controlled_runtime_profile.py +++ b/ops/runner/test_cd_controlled_runtime_profile.py @@ -21,6 +21,7 @@ def test_web_changes_stay_on_controlled_runtime_profile() -> None: def test_product_manifest_changes_stay_on_controlled_runtime_profile() -> None: text = _workflow_text() assert "product.awoooi.yaml)" in text + assert "apps/api/Dockerfile)" in text assert "docs/schemas/product_awoooi_manifest_v1.schema.json)" in text assert "apps/api/src/services/product_awoooi_manifest_standard.py)" in text assert "tests/test_product_awoooi_manifest_standard_api.py" in text