Skip to content

Commit bf15a81

Browse files
author
DavidQ
committed
Adds dry-run and validation capabilities to deployment scripts to ensure safe execution.
BUILD_PR_LEVEL_09_26_DEPLOY_VALIDATION_AND_DRYRUN
1 parent 02ac94c commit bf15a81

11 files changed

Lines changed: 162 additions & 31 deletions

docs/dev/CODEX_COMMANDS.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@ MODEL: GPT-5.4
22
REASONING: high
33

44
COMMAND:
5-
- refine scripts in scripts/PS/deploy/
6-
- ensure docker-ready deployment flow
7-
- standardize parameters and logging
8-
- enforce script structure rules
5+
- add dry-run mode to scripts/PS/deploy/
6+
- validate inputs and environment
7+
- prevent destructive execution without explicit confirmation
8+
- improve output messaging
99
- commit format:
1010
description first line
1111
PR name last line

docs/dev/COMMIT_COMMENT.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
Refine Docker deploy scripts with standardized mode handling/logging and deploy-folder enforcement checks.
2-
BUILD_PR_LEVEL_09_25_DOCKER_DEPLOY_SCRIPT_REFINEMENT
1+
Add deploy dry-run/environment validation guards and require explicit destructive confirmation for apply cleanup/refresh paths.
2+
BUILD_PR_LEVEL_09_26_DEPLOY_VALIDATION_AND_DRYRUN

docs/dev/NEXT_COMMAND.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
BUILD_PR_LEVEL_09_26_DEPLOY_VALIDATION_AND_DRYRUN
1+
BUILD_PR_LEVEL_09_27_DEPLOY_ENV_CONFIG_STANDARDIZATION
Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,18 @@
1-
BUILD_PR_LEVEL_09_25_DOCKER_DEPLOY_SCRIPT_REFINEMENT
1+
BUILD_PR_LEVEL_09_26_DEPLOY_VALIDATION_AND_DRYRUN
22

33
Scope:
4-
- Refined deploy scripts under scripts/PS/deploy/ only.
5-
- Kept behavior surgical and non-destructive by default.
4+
- Refined deployment safety/validation behavior only under `scripts/PS/deploy/`.
5+
- No runtime, engine, tool UI, or non-deploy scope changes.
66

77
Implemented:
8-
- Added shared deploy execution mode normalization (`-Apply` / `-DryRun`) in WebsiteRepoDeploymentCommon.ps1.
9-
- Added shared structured deploy logging helper with consistent level+timestamp output.
10-
- Added deploy script placement enforcement (`scripts/PS/deploy/`) with actionable failure text.
11-
- Added Docker artifact readiness assertion after artifact writes in prep/update flows.
12-
- Updated prep/update/clean entry scripts to use shared mode/logging enforcement helpers.
8+
- Kept/standardized dry-run behavior across deploy scripts with clearer next-step messaging.
9+
- Added environment readiness validation (`repo root`, `tmp root`, staging-root containment) before execution.
10+
- Added include-path contract validation (repo-relative only, no traversal/wildcards/rooted paths).
11+
- Added explicit destructive confirmation guard via `-ConfirmDestructive` for:
12+
- `Update-WebsiteRepoDeployment.ps1` apply path (site-root refresh/delete)
13+
- `Clean-WebsiteRepoDeployment.ps1` apply path (artifact deletion)
14+
- Preserved non-destructive defaults and existing staging-root safety checks.
1315

14-
Docs/Tracking:
15-
- Updated commit comment format (description first line, PR name last line).
16-
- Updated validation checklist for focused PowerShell/deploy checks.
17-
- Updated roadmap with status-only progression tied to acceptance enforcement.
16+
Tracking:
17+
- Commit comment format enforced (description first line, PR name last line, no leading blank line).
18+
- Roadmap updated with status-only change.
Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1-
[x] PowerShell parse/readiness checks on touched deploy scripts
2-
[x] focused dry-run smoke checks for prep/update/clean deploy flow
3-
[x] focused apply smoke checks in tmp staging path for prep/update/clean deploy flow
4-
[x] Docker artifact readiness assertions pass after prep/update apply flows
5-
[x] script structure validation smoke run passes
6-
[x] roadmap updated with status-only change
1+
[x] PowerShell parse/readiness checks pass on touched deploy scripts
2+
[x] Dry-run smoke checks pass for prep/update/clean deploy scripts
3+
[x] Environment readiness validation executes before deploy operations
4+
[x] Invalid include path traversal input is rejected
5+
[x] Update apply is blocked without explicit -ConfirmDestructive
6+
[x] Clean apply is blocked without explicit -ConfirmDestructive
7+
[x] Update/Clean apply succeed when -ConfirmDestructive is provided
8+
[x] Script structure validation smoke run passes
9+
[x] Roadmap updated with status-only change

docs/dev/roadmaps/MASTER_ROADMAP_HIGH_LEVEL.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -627,7 +627,7 @@
627627
- [x] finish active promotion-gate lane enough to remove it from half-active status
628628
- [.] convert repo structure normalization into exact move-map BUILDs with explicit validation
629629
- [.] re-baseline this roadmap after active execution lanes stabilize
630-
- [ ] split future implementation into small dependency-ordered PRs
630+
- [.] split future implementation into small dependency-ordered PRs
631631
- [ ] avoid broad repo-wide cleanup passes until the active lanes above are materially further along
632632

633633
- [x] relocate active template surfaces to `tools/templates/` and remove the empty root `templates/` directory
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# BUILD_PR — LEVEL 09_26 — DEPLOY VALIDATION AND DRY-RUN
2+
3+
## Objective
4+
Add validation and dry-run capabilities to deployment scripts to ensure safe execution before actual Docker deployment.
5+
6+
## Scope
7+
- add dry-run mode to deploy scripts
8+
- validate required inputs and environment
9+
- ensure no destructive operations without confirmation
10+
11+
## Out of Scope
12+
- no runtime changes
13+
- no tool UI changes
14+
15+
## Roadmap Instruction
16+
- Update roadmap status only

scripts/PS/deploy/Clean-WebsiteRepoDeployment.ps1

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ param(
33
[string]$StagingRoot,
44
[switch]$RemoveMetadata,
55
[switch]$Apply,
6-
[switch]$DryRun
6+
[switch]$DryRun,
7+
[switch]$ConfirmDestructive
78
)
89

910
Set-StrictMode -Version Latest
@@ -15,6 +16,7 @@ $executionMode = Resolve-DeployExecutionMode -Apply:$Apply.IsPresent -DryRun:$Dr
1516

1617
$paths = Get-WebsiteDeploymentPaths -StagingRoot $StagingRoot
1718
Test-StagingRootSafety -StagingRoot $paths.stagingRoot
19+
$environment = Assert-DeployEnvironmentReadiness -Paths $paths
1820

1921
$targets = New-Object System.Collections.Generic.List[string]
2022
if (Test-Path -LiteralPath $paths.siteRoot) {
@@ -42,11 +44,15 @@ if ($executionMode.isDryRun) {
4244
mode = $executionMode.label
4345
targetCount = $targets.Count
4446
targets = @($targets)
47+
dockerCliFound = $environment.dockerCliFound
48+
destructiveConfirmationRequired = $true
4549
}
46-
Write-DeployLog -Level "INFO" -Message "Run with -Apply to remove deployment artifacts."
50+
Write-DeployLog -Level "INFO" -Message "Next step: run Clean-WebsiteRepoDeployment.ps1 -Apply -ConfirmDestructive after reviewing the dry-run output."
4751
exit 0
4852
}
4953

54+
Assert-ExplicitDestructiveConfirmation -IsDryRun:$executionMode.isDryRun -ConfirmDestructive:$ConfirmDestructive.IsPresent -OperationName "Clean-WebsiteRepoDeployment delete" -TargetCount $targets.Count
55+
5056
foreach ($target in $targets) {
5157
if (-not (Test-PathWithinRoot -Path $target -RootPath $paths.stagingRoot)) {
5258
throw "Safety check failed. Target escapes staging root: $target"
@@ -61,4 +67,5 @@ Write-DeployLog -Level "SUCCESS" -Message "Cleaned website deployment artifacts.
6167
script = "Clean-WebsiteRepoDeployment"
6268
mode = $executionMode.label
6369
targetCount = $targets.Count
70+
dockerCliFound = $environment.dockerCliFound
6471
}

scripts/PS/deploy/Prep-WebsiteRepoDeployment.ps1

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,13 @@ $executionMode = Resolve-DeployExecutionMode -Apply:$Apply.IsPresent -DryRun:$Dr
1616
$repoRoot = Get-DeployRepoRoot
1717
$paths = Get-WebsiteDeploymentPaths -StagingRoot $StagingRoot
1818
Test-StagingRootSafety -StagingRoot $paths.stagingRoot
19+
$environment = Assert-DeployEnvironmentReadiness -Paths $paths
1920

2021
$normalizedIncludePaths = Normalize-IncludePaths -IncludePaths $IncludePaths
2122
if ($normalizedIncludePaths.Count -eq 0) {
2223
$normalizedIncludePaths = Get-DefaultWebsiteIncludePaths
2324
}
25+
Assert-NormalizedIncludePaths -IncludePaths $normalizedIncludePaths
2426

2527
$missing = New-Object System.Collections.Generic.List[string]
2628
foreach ($entry in $normalizedIncludePaths) {
@@ -44,8 +46,9 @@ if ($executionMode.isDryRun) {
4446
mode = $executionMode.label
4547
stagingRoot = $paths.stagingRoot
4648
includePaths = $normalizedIncludePaths
49+
dockerCliFound = $environment.dockerCliFound
4750
}
48-
Write-DeployLog -Level "INFO" -Message "Run with -Apply to create staging folders, deployment plan, and Docker artifacts."
51+
Write-DeployLog -Level "INFO" -Message "Next step: run Prep-WebsiteRepoDeployment.ps1 -Apply after reviewing include paths and staging root."
4952
exit 0
5053
}
5154

@@ -70,4 +73,5 @@ Write-DeployLog -Level "SUCCESS" -Message "Prepared website deployment staging."
7073
stagingRoot = $paths.stagingRoot
7174
planPath = $paths.planPath
7275
dockerfilePath = $paths.dockerfilePath
76+
dockerCliFound = $environment.dockerCliFound
7377
}

scripts/PS/deploy/Update-WebsiteRepoDeployment.ps1

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ param(
33
[string]$StagingRoot,
44
[string[]]$IncludePaths,
55
[switch]$Apply,
6-
[switch]$DryRun
6+
[switch]$DryRun,
7+
[switch]$ConfirmDestructive
78
)
89

910
Set-StrictMode -Version Latest
@@ -16,6 +17,7 @@ $executionMode = Resolve-DeployExecutionMode -Apply:$Apply.IsPresent -DryRun:$Dr
1617
$repoRoot = Get-DeployRepoRoot
1718
$paths = Get-WebsiteDeploymentPaths -StagingRoot $StagingRoot
1819
Test-StagingRootSafety -StagingRoot $paths.stagingRoot
20+
$environment = Assert-DeployEnvironmentReadiness -Paths $paths
1921

2022
$normalizedIncludePaths = Normalize-IncludePaths -IncludePaths $IncludePaths
2123
if ($normalizedIncludePaths.Count -eq 0) {
@@ -27,6 +29,7 @@ if ($normalizedIncludePaths.Count -eq 0) {
2729
$normalizedIncludePaths = Get-DefaultWebsiteIncludePaths
2830
}
2931
}
32+
Assert-NormalizedIncludePaths -IncludePaths $normalizedIncludePaths
3033

3134
$copyEntries = New-Object System.Collections.Generic.List[object]
3235
foreach ($entry in $normalizedIncludePaths) {
@@ -56,8 +59,10 @@ if ($executionMode.isDryRun) {
5659
mode = $executionMode.label
5760
siteRoot = $paths.siteRoot
5861
includePaths = $normalizedIncludePaths
62+
dockerCliFound = $environment.dockerCliFound
63+
destructiveConfirmationRequired = $true
5964
}
60-
Write-DeployLog -Level "INFO" -Message "Run with -Apply to refresh staged website content."
65+
Write-DeployLog -Level "INFO" -Message "Next step: run Update-WebsiteRepoDeployment.ps1 -Apply -ConfirmDestructive after reviewing the dry-run output."
6166
exit 0
6267
}
6368

@@ -73,6 +78,9 @@ Ensure-Directory -Path $paths.stagingRoot
7378
Ensure-Directory -Path $paths.metaRoot
7479
Ensure-Directory -Path $paths.siteRoot
7580

81+
$existingSiteRoot = Test-Path -LiteralPath $paths.siteRoot
82+
Assert-ExplicitDestructiveConfirmation -IsDryRun:$executionMode.isDryRun -ConfirmDestructive:$ConfirmDestructive.IsPresent -OperationName "Update-WebsiteRepoDeployment site refresh" -TargetCount $(if ($existingSiteRoot) { 1 } else { 0 })
83+
7684
if (Test-Path -LiteralPath $paths.siteRoot) {
7785
if (-not (Test-PathWithinRoot -Path $paths.siteRoot -RootPath $paths.stagingRoot)) {
7886
throw "Site root safety check failed: $($paths.siteRoot)"
@@ -111,4 +119,5 @@ Write-DeployLog -Level "SUCCESS" -Message "Updated website deployment staging co
111119
copiedEntries = $copyEntries.Count
112120
dockerfilePath = $paths.dockerfilePath
113121
reportPath = $paths.updateReportPath
122+
dockerCliFound = $environment.dockerCliFound
114123
}

0 commit comments

Comments
 (0)