Initial commit
This commit is contained in:
@@ -0,0 +1,134 @@
|
||||
#Requires -Version 5.1
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Generates a full idempotent EF Core migration SQL script and drops it into Y:\pcc\deployment.
|
||||
|
||||
.DESCRIPTION
|
||||
Runs `dotnet ef migrations script --idempotent` against the PowderCoating database and writes
|
||||
the output to Y:\pcc\deployment\migrations_YYYYMMDD_HHmmss.sql. The script is safe to run on
|
||||
any database state: EF wraps each migration in an IF NOT EXISTS check against
|
||||
__EFMigrationsHistory, so already-applied migrations are skipped.
|
||||
|
||||
.NOTES
|
||||
Run from any directory — paths are resolved relative to this script's location.
|
||||
Requires: .NET 8 SDK, dotnet-ef tool (dotnet tool install --global dotnet-ef)
|
||||
#>
|
||||
|
||||
[CmdletBinding()]
|
||||
param (
|
||||
[string]$OutputDir = "Y:\pcc\deployment"
|
||||
)
|
||||
|
||||
$timestamp = Get-Date -Format "yyyyMMdd_HHmmss"
|
||||
$displayStamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
|
||||
$outputFile = "migrations_$timestamp.sql"
|
||||
|
||||
$scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
|
||||
$repoRoot = Split-Path -Parent $scriptDir
|
||||
$webProject = Join-Path $repoRoot "src\PowderCoating.Web"
|
||||
$infraProject = Join-Path $repoRoot "src\PowderCoating.Infrastructure"
|
||||
$outputPath = Join-Path $OutputDir $outputFile
|
||||
|
||||
Write-Host ""
|
||||
Write-Host "=== EF Migration Script Generator ===" -ForegroundColor Cyan
|
||||
Write-Host " Web project : $webProject"
|
||||
Write-Host " Output : $outputPath"
|
||||
Write-Host ""
|
||||
|
||||
# ── Preflight checks ──────────────────────────────────────────────────────────
|
||||
|
||||
if (!(Test-Path $webProject)) {
|
||||
Write-Host "ERROR: Web project not found at: $webProject" -ForegroundColor Red
|
||||
exit 1
|
||||
}
|
||||
|
||||
if (!(Test-Path $OutputDir)) {
|
||||
Write-Host "Creating output directory: $OutputDir" -ForegroundColor Yellow
|
||||
New-Item -ItemType Directory -Path $OutputDir -Force | Out-Null
|
||||
}
|
||||
|
||||
$efVersion = dotnet ef --version 2>$null
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Write-Host "ERROR: dotnet-ef tool not found. Install with: dotnet tool install --global dotnet-ef" -ForegroundColor Red
|
||||
exit 1
|
||||
}
|
||||
Write-Host "dotnet-ef : $($efVersion | Select-Object -First 1)" -ForegroundColor DarkGray
|
||||
|
||||
# ── Generate script ───────────────────────────────────────────────────────────
|
||||
|
||||
Write-Host "Generating idempotent migration script..." -ForegroundColor Cyan
|
||||
|
||||
$savedLocation = Get-Location
|
||||
Set-Location $webProject
|
||||
|
||||
# Capture stderr to a temp file so EF's structured log noise (INF/WRN lines and
|
||||
# the "Ignoring added logger provider" design-time message) don't trigger
|
||||
# PowerShell 5.1's NativeCommandError handling.
|
||||
$tempErr = [System.IO.Path]::GetTempFileName()
|
||||
try {
|
||||
# Temporarily silence $ErrorActionPreference so PS 5.1 doesn't surface EF's
|
||||
# design-time stderr lines (structured log noise) as NativeCommandError objects.
|
||||
$prevEAP = $ErrorActionPreference
|
||||
$ErrorActionPreference = "SilentlyContinue"
|
||||
$null = dotnet ef migrations script `
|
||||
--idempotent `
|
||||
--context ApplicationDbContext `
|
||||
--project $infraProject `
|
||||
--output $outputPath `
|
||||
--no-build 2>$tempErr
|
||||
$exitCode = $LASTEXITCODE
|
||||
$ErrorActionPreference = $prevEAP
|
||||
|
||||
# Surface any genuine errors — filter out EF's routine log/diagnostic lines
|
||||
if (Test-Path $tempErr) {
|
||||
Get-Content $tempErr |
|
||||
Where-Object {
|
||||
$_ -notmatch "^\s*$" -and
|
||||
$_ -notmatch "\[.*\]\s+(INF|WRN)" -and
|
||||
$_ -notmatch "Ignoring added logger provider" -and
|
||||
$_ -notmatch "NativeCommandError"
|
||||
} |
|
||||
ForEach-Object { Write-Host " $_" -ForegroundColor DarkYellow }
|
||||
}
|
||||
}
|
||||
finally {
|
||||
Set-Location $savedLocation
|
||||
if (Test-Path $tempErr) { Remove-Item $tempErr -Force }
|
||||
}
|
||||
|
||||
if ($exitCode -ne 0) {
|
||||
Write-Host "ERROR: dotnet ef migrations script failed (exit code $exitCode)" -ForegroundColor Red
|
||||
exit $exitCode
|
||||
}
|
||||
|
||||
if (!(Test-Path $outputPath)) {
|
||||
Write-Host "ERROR: Output file was not created: $outputPath" -ForegroundColor Red
|
||||
exit 1
|
||||
}
|
||||
|
||||
# ── Stamp header ──────────────────────────────────────────────────────────────
|
||||
|
||||
$header = @"
|
||||
-- =============================================================================
|
||||
-- Idempotent EF Core migration script
|
||||
-- Project : PowderCoating.Web
|
||||
-- Generated: $displayStamp
|
||||
-- Safe to run on any database state (checks __EFMigrationsHistory per migration)
|
||||
-- =============================================================================
|
||||
|
||||
"@
|
||||
|
||||
$existing = Get-Content $outputPath -Raw
|
||||
Set-Content -Path $outputPath -Value ($header + $existing) -Encoding UTF8
|
||||
|
||||
# ── Report ────────────────────────────────────────────────────────────────────
|
||||
|
||||
$size = [math]::Round((Get-Item $outputPath).Length / 1KB, 1)
|
||||
$lineCount = (Get-Content $outputPath).Count
|
||||
|
||||
Write-Host ""
|
||||
Write-Host "Done." -ForegroundColor Green
|
||||
Write-Host " File : $outputPath"
|
||||
Write-Host " Size : $size KB ($lineCount lines)"
|
||||
Write-Host " Stamp : $displayStamp"
|
||||
Write-Host ""
|
||||
Reference in New Issue
Block a user