From e840573f9dad05a628d80122c29b7f1d01dbc121 Mon Sep 17 00:00:00 2001 From: AlterEgo Date: Sun, 19 Jul 2026 08:24:26 -0500 Subject: [PATCH] Automate pending SQL promotion names --- .github/workflows/promote-pending-sql.yml | 16 ++++++++ sql/pending_updates/README.md | 3 +- tools/dev/promote_pending_updates.ps1 | 48 +++++++++++++---------- 3 files changed, 45 insertions(+), 22 deletions(-) diff --git a/.github/workflows/promote-pending-sql.yml b/.github/workflows/promote-pending-sql.yml index c6d28d1f43..804cc851d6 100644 --- a/.github/workflows/promote-pending-sql.yml +++ b/.github/workflows/promote-pending-sql.yml @@ -36,6 +36,22 @@ jobs: git pull --rebase origin "${{ github.ref_name }}" + $pendingFiles = Get-ChildItem -Path sql/pending_updates -Filter *.sql -File -Recurse + $invalidFiles = @() + foreach ($file in $pendingFiles) { + $relativePath = $file.FullName.Substring((Get-Location).Path.Length + 1).Replace('\', '/') + $relativeParts = $relativePath.Split('/') + $databaseName = if ($relativeParts.Count -ge 3) { $relativeParts[2] } else { '' } + + if ($relativeParts.Count -ne 4 -or $relativeParts[0] -ne 'sql' -or $relativeParts[1] -ne 'pending_updates' -or $databaseName -notin @('auth', 'characters', 'world')) { + $invalidFiles += $relativePath + } + } + + if ($invalidFiles.Count -gt 0) { + Write-Error ("Pending SQL files must live directly under sql/pending_updates/. The promotion script assigns official YYYY_MM_DD__NN.sql filenames. Invalid file(s):`n" + ($invalidFiles -join "`n")) + } + ./tools/dev/promote_pending_updates.ps1 -Apply git add -A sql/pending_updates sql/updates diff --git a/sql/pending_updates/README.md b/sql/pending_updates/README.md index 5c0e617388..d119531da5 100644 --- a/sql/pending_updates/README.md +++ b/sql/pending_updates/README.md @@ -19,7 +19,8 @@ database setup and update tracking system can apply it. 1. Add the test SQL file to the matching pending folder. 2. Apply it manually to a test database. 3. Verify server startup, affected commands, and any in-game behavior. -4. Name the file like `YYYY-MM-DD__00_description.sql`. +4. Name the file clearly for review. It does not need the final update name. + The promotion script assigns `YYYY_MM_DD__NN.sql` automatically. 5. Push the pending SQL file and let the promotion workflow move it into `sql/updates/`. 6. Let the database setup system record it through `skyfire_db_updates` and diff --git a/tools/dev/promote_pending_updates.ps1 b/tools/dev/promote_pending_updates.ps1 index c49ca5f7c1..a10734d88b 100644 --- a/tools/dev/promote_pending_updates.ps1 +++ b/tools/dev/promote_pending_updates.ps1 @@ -4,9 +4,8 @@ Promotes pending SQL updates into the normal update stream. .DESCRIPTION Moves SQL files from sql/pending_updates/ to sql/updates/ -and renumbers them to the next available official update sequence. -Promoted files use the compact official name format: -YYYY-MM-DD__NN.sql. +and assigns each promoted file the next available official update name: +YYYY_MM_DD__NN.sql. The script runs in dry-run mode by default. Use -Apply to move files. @@ -17,13 +16,15 @@ powershell -NoProfile -ExecutionPolicy Bypass -File tools/dev/promote_pending_up powershell -NoProfile -ExecutionPolicy Bypass -File tools/dev/promote_pending_updates.ps1 -Database world -Apply .EXAMPLE -powershell -NoProfile -ExecutionPolicy Bypass -File tools/dev/promote_pending_updates.ps1 -InputPath sql/pending_updates/world/2026-06-22_world_04_areatrigger_tavern_missing.sql -Apply +powershell -NoProfile -ExecutionPolicy Bypass -File tools/dev/promote_pending_updates.ps1 -InputPath sql/pending_updates/world/areatrigger_tavern_missing.sql -Apply #> [CmdletBinding(SupportsShouldProcess = $true)] param( [string] $Root = '', + [string] $PromotionDate = '', + [ValidateSet('auth', 'characters', 'world')] [string[]] $Database, @@ -35,7 +36,21 @@ param( $ErrorActionPreference = 'Stop' $ValidDatabases = @('auth', 'characters', 'world') -$UpdateNamePattern = '^(?\d{4}[-_]\d{2}[-_]\d{2})_(?auth|characters|world)_(?\d{2})(?.*)\.sql$' +$UpdateNamePattern = '^(?\d{4}_\d{2}_\d{2})_(?auth|characters|world)_(?\d{2})(?.*)\.sql$' + +function Resolve-PromotionDate { + param([string] $RequestedDate) + + if ([string]::IsNullOrWhiteSpace($RequestedDate)) { + return (Get-Date).ToString('yyyy_MM_dd') + } + + if ($RequestedDate -notmatch '^\d{4}_\d{2}_\d{2}$') { + throw "PromotionDate '$RequestedDate' must use YYYY_MM_DD." + } + + return $RequestedDate +} function Resolve-RepoRoot { param([string] $RequestedRoot) @@ -163,20 +178,9 @@ function Get-PendingUpdateInfo { throw "Refusing '$relativePath' because '$databaseName' is not a known database folder." } - $match = [regex]::Match($File.Name, $UpdateNamePattern) - if (-not $match.Success) { - throw "Pending update '$relativePath' must be named like YYYY-MM-DD_${databaseName}_00_description.sql." - } - - $fileDatabaseName = $match.Groups['database'].Value - if ($fileDatabaseName -ne $databaseName) { - throw "Pending update '$relativePath' is in the '$databaseName' folder but its filename says '$fileDatabaseName'." - } - return [PSCustomObject]@{ Source = $File Database = $databaseName - Date = $match.Groups['date'].Value } } @@ -215,7 +219,8 @@ function Get-MaxOfficialSequence { function New-PromotionPlan { param( [string] $RootPath, - [System.IO.FileInfo[]] $Files + [System.IO.FileInfo[]] $Files, + [string] $DateText ) $infos = @() @@ -224,15 +229,15 @@ function New-PromotionPlan { } $actions = @() - $groups = $infos | Group-Object Database, Date + $groups = $infos | Group-Object Database foreach ($group in $groups) { $first = $group.Group | Select-Object -First 1 - $nextSequence = (Get-MaxOfficialSequence -RootPath $RootPath -DatabaseName $first.Database -DateText $first.Date) + 1 + $nextSequence = (Get-MaxOfficialSequence -RootPath $RootPath -DatabaseName $first.Database -DateText $DateText) + 1 $updatesDir = Join-Path $RootPath "sql\updates\$($first.Database)" foreach ($info in ($group.Group | Sort-Object { $_.Source.Name })) { - $targetName = '{0}_{1}_{2:D2}.sql' -f $info.Date, $info.Database, $nextSequence + $targetName = '{0}_{1}_{2:D2}.sql' -f $DateText, $info.Database, $nextSequence $targetPath = Join-Path $updatesDir $targetName if (Test-Path -LiteralPath $targetPath) { @@ -281,6 +286,7 @@ function Invoke-PromotionPlan { } $repoRoot = Resolve-RepoRoot -RequestedRoot $Root +$promotionDateText = Resolve-PromotionDate -RequestedDate $PromotionDate $pendingFiles = @(Get-PendingSqlFiles -RootPath $repoRoot -RequestedDatabases $Database -RequestedPaths $InputPath) if ($pendingFiles.Count -eq 0) { @@ -288,7 +294,7 @@ if ($pendingFiles.Count -eq 0) { exit 0 } -$plan = @(New-PromotionPlan -RootPath $repoRoot -Files $pendingFiles) +$plan = @(New-PromotionPlan -RootPath $repoRoot -Files $pendingFiles -DateText $promotionDateText) Invoke-PromotionPlan -RootPath $repoRoot -Actions $plan -ApplyChanges:$Apply if (-not $Apply) {