Skip to content

修復測試部署清理失敗時的 .env 還原 - #243

Merged
monkey1sai merged 1 commit into
mainfrom
fix/test-deploy-env-restore-on-clean-failure
Jun 23, 2026
Merged

monkey1sai merged 1 commit into
mainfrom
fix/test-deploy-env-restore-on-clean-failure

Conversation

@monkey1sai

@monkey1sai monkey1sai commented Jun 23, 2026 •

Copy link
Copy Markdown
Owner

摘要

  • 修正 rebuild-test-deploy 在 git clean -fdx 失敗時沒有還原 .env snapshot 的問題。
  • 新增回歸測試,模擬 git clean 已刪除 .env.web-plane.host-kit 後因 locked log 失敗,確認 MinIO credential 檔會被還原。

驗證

  • powershell -NoProfile -ExecutionPolicy Bypass -File scripts\tests\test-rebuild-test-deploy.ps1
  • git diff --check -- scripts/lib/rebuild-test-deploy.ps1 scripts/tests/test-rebuild-test-deploy.ps1
  • gitnexus detect_changes(scope=staged):2 files, low risk, no indexed symbols affected

Deploy Path Verification

Item Result
Deployment path D:\Users\deploy\AI-bim-geo
Rebuild command exercised scripts\dev\rebuild-test-deploy.ps1 -Build
Env file preservation .env, bim-review-coordinator\.env, .env.web-plane.host-kit restored before deploy on normal path; .env.web-plane.host-kit restored after simulated failed clean
Runtime health coordinator 200, viewer 200, governance 200, conversion 200
MinIO watcher /api/external/minio-watch/status returned enabled=true, last_error=null, poll_count=18, seen_count=3

已知限制

  • 本 PR 不修改 MinIO credential;credential 仍只存在部署區 private .env。
  • triggered_total=0 表示 watcher 尚未看到新的 */model.ifc 物件;既有物件已作為 baseline。

Summary by CodeRabbit

  • Bug Fixes

    • Improved resilience during deployment reset sequences with enhanced error reporting and recovery attempts.
  • Tests

    • Added test coverage for failure scenarios during cleanup operations, including validation of environment restoration.

Copilot AI review requested due to automatic review settings June 23, 2026 07:40
@coderabbitai

coderabbitai Bot commented Jun 23, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Invoke-TestDeployRebuild now wraps the git fetch/reset --hard/clean -fdx sequence and initial env restore in a try/catch. On failure, the catch re-attempts env restoration, logs results, and throws a combined error if the fallback also fails. A new test covers the clean -fdx failure path.

Changes

Env Restore on Clean Failure

Layer / File(s) Summary
try/catch env restore logic
scripts/lib/rebuild-test-deploy.ps1
Moves the git cleanup commands and primary Restore-TestDeployEnvSnapshot call into a try block; the new catch re-attempts env restoration, logs restored file names and count, and throws a combined error message if the fallback restore fails.
Test: clean failure with env restoration
scripts/tests/test-rebuild-test-deploy.ps1
Adds a scenario with a dedicated sandbox deploy root where clean -fdx is mocked to delete the host-kit env file and return a non-zero exit code; asserts the error is surfaced, the deploy runner is not invoked, and the original env credentials are recovered.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

  • monkey1sai/AI-BIM-governance#198: Establishes the initial Invoke-TestDeployRebuild scaffolding in scripts/lib/rebuild-test-deploy.ps1 and its test coverage in scripts/tests/test-rebuild-test-deploy.ps1 that this PR extends with clean -fdx failure handling.

Poem

🐇 When clean -fdx goes awry,
And env files vanish — oh my!
The catch block leaps, restores each key,
Logs every file for you to see.
No secret lost, no cred left dry! 🌿

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: adding error handling to restore .env files when git clean -fdx fails during test deployment cleanup.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/test-deploy-env-restore-on-clean-failure

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
scripts/tests/test-rebuild-test-deploy.ps1 (1)

251-253: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Also assert the clean failure exit code to harden this regression test.

The test checks message text, but not the expected non-zero code from the mocked clean -fdx failure. Asserting exit code 42 here would better lock the error contract.

Proposed test tweak
     Assert-True (-not [string]::IsNullOrWhiteSpace($cleanFailureMessage)) 'clean failure is surfaced'
+    Assert-True ($cleanFailureMessage -match 'exit code 42') 'clean failure includes exit code'
     Assert-True ($cleanFailureMessage -match 'locked governance log') 'clean failure includes command output'
     Assert-True (-not $cleanFailureDeployWasCalled) 'clean failure stops before deploy'
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/tests/test-rebuild-test-deploy.ps1` around lines 251 - 253, The test
validates the clean failure message and deployment behavior but does not assert
the expected exit code from the mocked clean failure. Add an Assert-True
statement after the existing assertions to verify that the clean failure exit
code equals 42, ensuring the error contract is properly locked. Store and check
a variable representing the exit code from the clean command failure (similar to
how $cleanFailureMessage and $cleanFailureDeployWasCalled are currently
validated) to complete the regression test coverage.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@scripts/lib/rebuild-test-deploy.ps1`:
- Line 272: Replace the bare Write-Host call in the deployment restoration
logging at line 272 with a structured logging call from
scripts/lib/StructLog.psm1. Instead of using Write-Host directly, use the
appropriate structured logging function from the StructLog module to log the
message about restored deployment environment files after failed cleanup. This
ensures consistent output formatting and enables downstream parsing as per the
scripts coding guidelines.

---

Nitpick comments:
In `@scripts/tests/test-rebuild-test-deploy.ps1`:
- Around line 251-253: The test validates the clean failure message and
deployment behavior but does not assert the expected exit code from the mocked
clean failure. Add an Assert-True statement after the existing assertions to
verify that the clean failure exit code equals 42, ensuring the error contract
is properly locked. Store and check a variable representing the exit code from
the clean command failure (similar to how $cleanFailureMessage and
$cleanFailureDeployWasCalled are currently validated) to complete the regression
test coverage.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 8876b86c-1a5a-4e46-94f7-903b7cbeb37a

📥 Commits

Reviewing files that changed from the base of the PR and between 2c7641c and 98cd595.

📒 Files selected for processing (2)
  • scripts/lib/rebuild-test-deploy.ps1
  • scripts/tests/test-rebuild-test-deploy.ps1

try {
$restoredAfterFailure = @(Restore-TestDeployEnvSnapshot -DeploymentPath $deployRoot -Snapshot $envSnapshot)
if ($restoredAfterFailure.Count -gt 0) {
Write-Host "[rebuild-test-deploy] restored deployment env files after failed cleanup count=$($restoredAfterFailure.Count): $($restoredAfterFailure -join ', ')"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Use structured logging instead of bare Write-Host in the new failure-restore path.

Line 272 introduces a new bare Write-Host; this should go through the structured logger used by scripts for consistent output and downstream parsing.

As per coding guidelines: "scripts/**/*.ps1: Use scripts/lib/StructLog.psm1 for structured logging output; do not replace with bare Write-Host calls".

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/lib/rebuild-test-deploy.ps1` at line 272, Replace the bare Write-Host
call in the deployment restoration logging at line 272 with a structured logging
call from scripts/lib/StructLog.psm1. Instead of using Write-Host directly, use
the appropriate structured logging function from the StructLog module to log the
message about restored deployment environment files after failed cleanup. This
ensures consistent output formatting and enables downstream parsing as per the
scripts coding guidelines.

Source: Coding guidelines

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes a secret-loss bug in the test-deploy rebuild helper: previously, if git clean -fdx failed after deleting deployment .env files (e.g., due to a locked governance log), the preserved .env snapshot was never restored. The change wraps the fetch/reset/clean/restore sequence in a try/catch so that the env snapshot is restored even on failure, before the error is re-thrown to abort the deploy. This protects deployment-only secrets (notably MinIO credentials in .env.web-plane.host-kit) that exist only in the deployment checkout.

Changes:

  • Wrapped the git fetch/reset/clean and env-restore steps in try/catch in Invoke-TestDeployRebuild, restoring the env snapshot on failure and surfacing a combined error if the restore itself fails.
  • Added a regression test simulating a failed git clean -fdx (after the host-kit env was deleted) that asserts the MinIO credentials are restored, the failure is surfaced, and deploy is not invoked.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
scripts/lib/rebuild-test-deploy.ps1 Adds try/catch around fetch/reset/clean/restore so preserved env files are restored on cleanup failure, then re-throws to abort before deploy.
scripts/tests/test-rebuild-test-deploy.ps1 Adds a regression test verifying env (MinIO credential) restoration after a simulated failed git clean -fdx, and that deploy is not reached.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 98cd595181

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

try {
$restoredAfterFailure = @(Restore-TestDeployEnvSnapshot -DeploymentPath $deployRoot -Snapshot $envSnapshot)
if ($restoredAfterFailure.Count -gt 0) {
Write-Host "[rebuild-test-deploy] restored deployment env files after failed cleanup count=$($restoredAfterFailure.Count): $($restoredAfterFailure -join ', ')"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Emit cleanup recovery through structured logging

When git clean -fdx fails after deleting preserved env files, this new recovery message is emitted only via naked Write-Host, even though scripts/AGENTS.md explicitly requires scripts to use scripts/lib/StructLog.psm1 and not bare Write-Host. That makes this failure-recovery event invisible to the structured-log pipeline used for deploy diagnostics; please emit it through the structured logger instead.

Useful? React with 👍 / 👎.

} catch {
$cleanupError = $_
try {
$restoredAfterFailure = @(Restore-TestDeployEnvSnapshot -DeploymentPath $deployRoot -Snapshot $envSnapshot)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Continue restoring later env snapshots after one write fails

In a partial cleanup failure where one preserved env file remains locked or unwritable while another has already been deleted, this single restore call aborts on the first WriteAllBytes error inside Restore-TestDeployEnvSnapshot. Because snapshots are restored in .env, coordinator .env, then host-kit order, a locked root .env prevents later deleted credentials such as .env.web-plane.host-kit from being restored, leaving the deployment checkout without the private MinIO settings this recovery path is meant to preserve.

Useful? React with 👍 / 👎.

$restoredEnvFiles = @(Restore-TestDeployEnvSnapshot -DeploymentPath $deployRoot -Snapshot $envSnapshot)
$restoredEnvFiles = @()
try {
Invoke-TestDeployGitCommand -Tool 'git' -Arguments @('fetch', 'origin', $mainRefSpec) -WorkingDirectory $deployRoot -CommandRunner $CommandRunner | Out-Null

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep fetch outside the cleanup-recovery block

When the explicit git fetch fails because of network or auth, no reset or clean has run yet, but placing it inside this cleanup-recovery try means the catch still rewrites preserved .env snapshots. That changes the documented fail-fast fetch path and can even mask the real fetch blocker if a preserved env file is locked or unwritable; only failures after a destructive reset/clean step should trigger snapshot restoration.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants