diff --git a/.gitea/workflows/cd.yaml b/.gitea/workflows/cd.yaml index 7afa436f..9d79208d 100644 --- a/.gitea/workflows/cd.yaml +++ b/.gitea/workflows/cd.yaml @@ -2390,6 +2390,7 @@ jobs: continue-on-error: true run: | cat > /tmp/awoooi-smoke.sh <<'CI_SCRIPT' + set -euo pipefail # 首席架構師 Review I4 + 2026-04-05 Claude Code cache優化: # playwright.config.ts import @playwright/test — 必須先安裝 pnpm node_modules # pnpm store 持久化到 /opt/pnpm-store,pnpm-lock.yaml hash 未變則 --prefer-offline @@ -2415,16 +2416,18 @@ jobs: CURRENT_PNPM_HASH=$(md5sum pnpm-lock.yaml | awk '{print $1}') corepack enable 2>/dev/null || npm install -g pnpm@9 -q + mkdir -p "$PNPM_STORE" pnpm config set store-dir $PNPM_STORE if [ "$(cat $PNPM_HASH_FILE 2>/dev/null)" != "$CURRENT_PNPM_HASH" ]; then echo "📦 pnpm lock 已變更,重裝 node_modules..." - pnpm install --frozen-lockfile 2>&1 | tail -5 + pnpm install --frozen-lockfile 2>&1 | tee /tmp/pnpm-install.log | tail -20 echo "$CURRENT_PNPM_HASH" > $PNPM_HASH_FILE else echo "⚡ 使用快取 pnpm store (lock 未變更),prefer-offline..." - pnpm install --frozen-lockfile --prefer-offline 2>&1 | tail -5 + pnpm install --frozen-lockfile --prefer-offline 2>&1 | tee /tmp/pnpm-install.log | tail -20 fi + pnpm --dir apps/web exec node -e "require.resolve('@playwright/test')" cd apps/web # Playwright Chromium 持久化到 /opt/playwright-browsers,版本 hash guard @@ -2433,7 +2436,7 @@ jobs: PLAYWRIGHT_HASH_FILE=/opt/playwright-browsers/.version_hash if [ "$(cat $PLAYWRIGHT_HASH_FILE 2>/dev/null)" != "$PLAYWRIGHT_VER" ]; then echo "📦 Playwright 版本變更 ($PLAYWRIGHT_VER),重裝 Chromium..." - npx playwright install chromium --with-deps 2>&1 | tail -5 + pnpm exec playwright install chromium --with-deps 2>&1 | tail -20 echo "$PLAYWRIGHT_VER" > $PLAYWRIGHT_HASH_FILE else echo "⚡ 使用快取 Playwright Chromium ($PLAYWRIGHT_VER)" @@ -2442,7 +2445,7 @@ jobs: # chromium launch failure(例如 libnspr4.so missing)。 if ! ldconfig -p 2>/dev/null | grep -q 'libnspr4'; then echo "📦 Playwright system deps missing,補安裝 Chromium deps..." - npx playwright install-deps chromium > /tmp/playwright-install-deps.log 2>&1 || { + pnpm exec playwright install-deps chromium > /tmp/playwright-install-deps.log 2>&1 || { tail -40 /tmp/playwright-install-deps.log exit 1 } @@ -2450,7 +2453,7 @@ jobs: fi # 對已部署的生產環境跑 smoke test SMOKE_STATUS=pass - npx playwright test tests/e2e/smoke.spec.ts --reporter=line || SMOKE_STATUS=fail + pnpm exec playwright test tests/e2e/smoke.spec.ts --reporter=line || SMOKE_STATUS=fail echo "smoke_status=${SMOKE_STATUS}" >> $GITHUB_OUTPUT CI_SCRIPT SMOKE_OUTPUT="$PWD/.awoooi-smoke-output" diff --git a/docs/LOGBOOK.md b/docs/LOGBOOK.md index 22244f28..a2ab872a 100644 --- a/docs/LOGBOOK.md +++ b/docs/LOGBOOK.md @@ -1,3 +1,15 @@ +## 2026-07-01 — 17:18 Gitea CD post-deploy smoke 依賴證據修正 + +**照主線修正的問題**: +- CD `#4270` 已成功完成 tests、build-and-deploy、ArgoCD sync、K8s rollout 與 production deploy readback,但 post-deploy browser smoke 回 `SMOKE_RESULT=⚠️`;log 顯示 `npx playwright` 下載孤立 CLI 後找不到 workspace 內的 `@playwright/test`。 +- `.gitea/workflows/cd.yaml` 的 E2E smoke script 改成 `set -euo pipefail`,`pnpm install` 失敗會直接失敗,不再被 `tail` pipe 吃掉;安裝後用 `pnpm --dir apps/web exec node -e "require.resolve('@playwright/test')"` 做明確依賴 readback。 +- Playwright 安裝與執行全面改用 workspace 依賴:`pnpm exec playwright install`、`pnpm exec playwright install-deps`、`pnpm exec playwright test`;禁止回到 `npx playwright` 造成假 smoke。 +- `ops/runner/test_cd_controlled_runtime_profile.py` 新增 guard,鎖住 post-deploy smoke 必須使用 workspace Playwright,避免 Gitea/CD 顯示綠燈但 browser smoke 沒有真跑。 + +**邊界**:未讀 secret / token / `.env` / raw sessions / SQLite / auth;未使用 GitHub / `gh` / GitHub API;未重啟主機 / Docker / Nginx / K3s / DB / firewall;未 force push。 + +**下一步**:跑本地 workflow guard 後推 Gitea main,讓下一個 CD 重新產生 post-deploy smoke 證據;production 目前已由 `#4270` 讀回 `fdbbe408c3` closure verified。 + ## 2026-07-01 — 17:08 Gitea CD #4269 B5 socket blocker / DB pool rollout profile 收斂 **照主線修正的問題**: diff --git a/ops/runner/test_cd_controlled_runtime_profile.py b/ops/runner/test_cd_controlled_runtime_profile.py index 5d96159e..e688a4cf 100644 --- a/ops/runner/test_cd_controlled_runtime_profile.py +++ b/ops/runner/test_cd_controlled_runtime_profile.py @@ -125,6 +125,20 @@ def test_cd_requires_production_deploy_readback_after_rollout() -> None: assert "treating as rollout risk, not deploy failure" in text +def test_post_deploy_smoke_uses_workspace_playwright_dependency() -> None: + text = _workflow_text() + block = text.split("- name: E2E Smoke Test", 1)[1] + block = block.split("- name: Notify Success", 1)[0] + + assert "set -euo pipefail" in block + assert "tee /tmp/pnpm-install.log | tail -20" in block + assert 'pnpm --dir apps/web exec node -e "require.resolve(\'@playwright/test\')"' in block + assert "pnpm exec playwright install chromium --with-deps" in block + assert "pnpm exec playwright install-deps chromium" in block + assert "pnpm exec playwright test tests/e2e/smoke.spec.ts --reporter=line" in block + assert "npx playwright" not in block + + def test_harbor_login_has_public_route_retry_and_safe_secret_transport() -> None: text = _workflow_text() block = text.split("- name: Login to Harbor", 1)[1]