* docs: prepare Vendoo 1.41.2 git-ignore boundary hotfix * fix: track native source modules with root-anchored runtime ignores
211 lines
10 KiB
PowerShell
211 lines
10 KiB
PowerShell
# Vendoo 1.41.2 – kontrollierter GitHub-Erstimport
|
||
$ErrorActionPreference = 'Stop'
|
||
$Root = Split-Path -Parent (Split-Path -Parent $MyInvocation.MyCommand.Path)
|
||
$RepoUrl = 'https://github.com/Masterluke77/vendoo.git'
|
||
$PullRequestUrl = 'https://github.com/Masterluke77/vendoo/pull/18'
|
||
$Branch = 'release/1.41.2-git-ignore-boundary-hotfix'
|
||
$WorkRoot = Join-Path $env:TEMP ('vendoo-github-deploy-' + [Guid]::NewGuid().ToString('N'))
|
||
$CloneDir = Join-Path $WorkRoot 'repo'
|
||
|
||
function Info($Text) { Write-Host "[INFO] $Text" -ForegroundColor Cyan }
|
||
function Ok($Text) { Write-Host "[OK] $Text" -ForegroundColor Green }
|
||
function Warn($Text) { Write-Host "[WARN] $Text" -ForegroundColor Yellow }
|
||
function Fail($Text) { Write-Host "[FEHLER] $Text" -ForegroundColor Red }
|
||
|
||
function Test-Command([string]$Name) {
|
||
return [bool](Get-Command $Name -ErrorAction SilentlyContinue)
|
||
}
|
||
|
||
function Ensure-Git {
|
||
if (Test-Command 'git.exe') { return }
|
||
Warn 'Git für Windows wurde nicht gefunden.'
|
||
if (Test-Command 'winget.exe') {
|
||
$answer = Read-Host 'Git jetzt automatisch über winget installieren? (ja/nein)'
|
||
if ($answer -eq 'ja') {
|
||
& winget.exe install --id Git.Git --exact --source winget --accept-package-agreements --accept-source-agreements
|
||
if ($LASTEXITCODE -ne 0) { throw 'Git-Installation über winget ist fehlgeschlagen.' }
|
||
$env:Path = [Environment]::GetEnvironmentVariable('Path','Machine') + ';' + [Environment]::GetEnvironmentVariable('Path','User')
|
||
}
|
||
}
|
||
if (-not (Test-Command 'git.exe')) { throw 'Git für Windows wird benötigt. Starte den Assistenten nach der Git-Installation erneut.' }
|
||
}
|
||
|
||
function Invoke-Git([string[]]$Arguments, [string]$WorkingDirectory = $CloneDir) {
|
||
Push-Location $WorkingDirectory
|
||
try {
|
||
& git.exe @Arguments
|
||
if ($LASTEXITCODE -ne 0) { throw "git $($Arguments -join ' ') fehlgeschlagen (Exit-Code $LASTEXITCODE)." }
|
||
} finally { Pop-Location }
|
||
}
|
||
|
||
function Copy-ProjectClean {
|
||
if (-not (Test-Command 'node.exe')) {
|
||
throw 'Node.js ist für den sicheren GitHub-Import erforderlich. Bitte zuerst über setup.bat installieren oder aktualisieren.'
|
||
}
|
||
Info 'Bereite den bereinigten Git-Arbeitsordner mit dem plattformübergreifenden Staging-Builder vor ...'
|
||
$builder = Join-Path $Root 'tools\prepare-git-staging.mjs'
|
||
$result = Invoke-NodeProcess -ScriptPath $builder -Arguments @($Root, $CloneDir) -WorkingDirectory $Root -Prefix 'Staging'
|
||
if ($result.ExitCode -ne 0) {
|
||
$result.Lines | ForEach-Object { Write-Host $_ -ForegroundColor Red }
|
||
throw 'Der sichere Git-Staging-Aufbau ist fehlgeschlagen.'
|
||
}
|
||
$result.Lines | ForEach-Object { Write-Host $_ }
|
||
}
|
||
|
||
function Invoke-NodeProcess {
|
||
param(
|
||
[Parameter(Mandatory=$true)][string]$ScriptPath,
|
||
[string[]]$Arguments = @(),
|
||
[string]$WorkingDirectory = $CloneDir,
|
||
[string]$Prefix = 'Node'
|
||
)
|
||
$id = [Guid]::NewGuid().ToString('N')
|
||
$stdoutPath = Join-Path $WorkRoot ("$Prefix-$id-stdout.txt")
|
||
$stderrPath = Join-Path $WorkRoot ("$Prefix-$id-stderr.txt")
|
||
$nodePath = (Get-Command node.exe -ErrorAction Stop).Source
|
||
$allArguments = @($ScriptPath) + $Arguments
|
||
$argumentLine = ($allArguments | ForEach-Object { '"' + ([string]$_).Replace('"','\"') + '"' }) -join ' '
|
||
$process = Start-Process -FilePath $nodePath `
|
||
-ArgumentList $argumentLine `
|
||
-WorkingDirectory $WorkingDirectory `
|
||
-NoNewWindow `
|
||
-Wait `
|
||
-PassThru `
|
||
-RedirectStandardOutput $stdoutPath `
|
||
-RedirectStandardError $stderrPath
|
||
|
||
$lines = @()
|
||
if (Test-Path -LiteralPath $stdoutPath) { $lines += @(Get-Content -LiteralPath $stdoutPath -Encoding UTF8 -ErrorAction SilentlyContinue) }
|
||
if (Test-Path -LiteralPath $stderrPath) { $lines += @(Get-Content -LiteralPath $stderrPath -Encoding UTF8 -ErrorAction SilentlyContinue) }
|
||
return [pscustomobject]@{ ExitCode = [int]$process.ExitCode; Lines = $lines }
|
||
}
|
||
|
||
function Run-SafetyGate {
|
||
$ReportDir = Join-Path $Root 'logs'
|
||
$ReportPath = Join-Path $ReportDir 'github-deploy-safety-report.txt'
|
||
if (-not (Test-Command 'node.exe')) {
|
||
throw 'Node.js ist für den sicheren GitHub-Import erforderlich. Bitte zuerst über setup.bat installieren oder aktualisieren.'
|
||
}
|
||
|
||
Info 'Führe das Vendoo Git-Sicherheitsgate über den vollständigen Staging-Arbeitsbaum aus ...'
|
||
$result = Invoke-NodeProcess -ScriptPath 'tools/verify-git-safety.mjs' -WorkingDirectory $CloneDir -Prefix 'SafetyGate'
|
||
foreach ($line in $result.Lines) {
|
||
if ($line -match '^Git-Sicherheitsgate fehlgeschlagen|^- ') { Write-Host $line -ForegroundColor Red }
|
||
elseif ($line -match '^\[WARN\]') { Write-Host $line -ForegroundColor Yellow }
|
||
else { Write-Host $line }
|
||
}
|
||
|
||
if ($result.ExitCode -ne 0) {
|
||
New-Item -ItemType Directory -Path $ReportDir -Force | Out-Null
|
||
@(
|
||
'Vendoo Git-Sicherheitsgate – vollständiger Fehlerbericht',
|
||
('Zeitpunkt: ' + (Get-Date -Format 'yyyy-MM-dd HH:mm:ss')),
|
||
('Projekt: ' + $Root),
|
||
('Staging: ' + $CloneDir),
|
||
'',
|
||
$result.Lines
|
||
) | Set-Content -LiteralPath $ReportPath -Encoding UTF8
|
||
Fail "Das Gate hat $($result.Lines.Count) Diagnosezeilen erzeugt. Bericht: $ReportPath"
|
||
try { Start-Process notepad.exe -ArgumentList ('"' + $ReportPath + '"') | Out-Null } catch {}
|
||
throw 'Git-Sicherheitsgate ist fehlgeschlagen. Die konkreten Treffer wurden oben angezeigt und im Bericht gespeichert.'
|
||
}
|
||
|
||
Remove-Item -LiteralPath $ReportPath -Force -ErrorAction SilentlyContinue
|
||
$forbidden = Get-ChildItem -LiteralPath $CloneDir -Recurse -Force -File -ErrorAction SilentlyContinue | Where-Object {
|
||
($_.Name -match '^\.env(?:\..+)?$' -and $_.Name -notin @('.env.example','.env.docker.example')) -or
|
||
$_.Extension -in @('.db','.sqlite','.sqlite3','.log','.key','.pem','.pfx','.p12')
|
||
}
|
||
if ($forbidden) {
|
||
throw ('Verbotene Dateien im Git-Staging: ' + (($forbidden | Select-Object -First 20 -ExpandProperty FullName) -join ', '))
|
||
}
|
||
Ok 'Git-Sicherheitsgate erfolgreich: keine lokalen Secrets oder Laufzeitdaten im Import.'
|
||
}
|
||
|
||
try {
|
||
Write-Host ''
|
||
Write-Host 'Vendoo 1.41.2 – GitHub Deploy Assistent' -ForegroundColor Green
|
||
Write-Host 'Repository: Masterluke77/vendoo (privat)' -ForegroundColor DarkGray
|
||
Write-Host ''
|
||
|
||
Ensure-Git
|
||
New-Item -ItemType Directory -Path $WorkRoot -Force | Out-Null
|
||
|
||
Info 'Klone die vorhandene GitHub-Baseline ...'
|
||
& git.exe clone $RepoUrl $CloneDir
|
||
if ($LASTEXITCODE -ne 0) { throw 'Repository konnte nicht geklont werden. Die Git-Anmeldung öffnet sich normalerweise automatisch im Browser.' }
|
||
|
||
Push-Location $CloneDir
|
||
try {
|
||
& git.exe ls-remote --exit-code --heads origin $Branch 1>$null 2>$null
|
||
$branchExists = ($LASTEXITCODE -eq 0)
|
||
} finally { Pop-Location }
|
||
if ($branchExists) {
|
||
Invoke-Git @('fetch','origin',$Branch)
|
||
Invoke-Git @('switch','--track','-c',$Branch,("origin/" + $Branch))
|
||
} else {
|
||
Invoke-Git @('switch','-c',$Branch)
|
||
}
|
||
|
||
Copy-ProjectClean
|
||
Run-SafetyGate
|
||
|
||
Info 'Prüfe produktive Source-Dateien und Git-Ignore-Grenzen im Staging ...'
|
||
$sourceGate = Invoke-NodeProcess -ScriptPath 'tools/verify-source-boundaries-1.41.2.mjs' -WorkingDirectory $CloneDir -Prefix 'SourceGate'
|
||
$sourceGate.Lines | ForEach-Object { Write-Host $_ }
|
||
if ($sourceGate.ExitCode -ne 0) { throw 'Produktive Source-Root-Prüfung ist fehlgeschlagen.' }
|
||
$ignoreGate = Invoke-NodeProcess -ScriptPath 'tools/verify-git-ignore-boundaries-1.41.2.mjs' -WorkingDirectory $CloneDir -Prefix 'IgnoreGate'
|
||
$ignoreGate.Lines | ForEach-Object { Write-Host $_ }
|
||
if ($ignoreGate.ExitCode -ne 0) { throw 'Git-Ignore-Grenzprüfung ist fehlgeschlagen.' }
|
||
|
||
Invoke-Git @('config','user.name','Markus Müller')
|
||
Invoke-Git @('config','user.email','163446896+Masterluke77@users.noreply.github.com')
|
||
Invoke-Git @('add','--all')
|
||
|
||
$requiredTracked = @(
|
||
'app/modules/listings/routes.mjs',
|
||
'app/modules/inventory/index.mjs',
|
||
'app/modules/inventory/repository.mjs',
|
||
'app/modules/inventory/routes.mjs',
|
||
'app/modules/sessions/index.mjs'
|
||
)
|
||
Push-Location $CloneDir
|
||
try {
|
||
$ignoredModules = @(& git.exe ls-files --others --ignored --exclude-standard -- app/modules)
|
||
if ($ignoredModules.Count -gt 0) { throw ('Produktive Moduldateien werden von .gitignore ausgeschlossen: ' + ($ignoredModules -join ', ')) }
|
||
foreach ($rel in $requiredTracked) {
|
||
if (-not (Test-Path -LiteralPath (Join-Path $CloneDir $rel))) { throw "Pflichtdatei fehlt im Git-Staging: $rel" }
|
||
& git.exe ls-files --error-unmatch -- $rel 1>$null 2>$null
|
||
if ($LASTEXITCODE -ne 0) { throw "Pflichtdatei wurde von Git nicht getrackt: $rel" }
|
||
}
|
||
} finally { Pop-Location }
|
||
Ok 'Produktive Moduldateien sind vorhanden und werden von Git getrackt.'
|
||
|
||
Push-Location $CloneDir
|
||
try {
|
||
$status = & git.exe status --short
|
||
if (-not $status) { Warn 'Es gibt keine Änderungen gegenüber GitHub.'; exit 0 }
|
||
Write-Host ''
|
||
Write-Host $status
|
||
Write-Host ''
|
||
} finally { Pop-Location }
|
||
|
||
$confirm = Read-Host 'Geprüften Vendoo-Stand als Release-Branch zu GitHub übertragen? Zum Fortfahren PUSH eingeben'
|
||
if ($confirm -cne 'PUSH') { Warn 'Deployment abgebrochen. Auf GitHub wurde nichts verändert.'; exit 0 }
|
||
|
||
Invoke-Git @('commit','-m','fix: track native source modules with root-anchored runtime ignores')
|
||
Invoke-Git @('push','--set-upstream','origin',$Branch)
|
||
Ok "Branch $Branch wurde erfolgreich übertragen."
|
||
|
||
Info 'Öffne jetzt Draft Pull Request #18 im Browser ...'
|
||
Start-Process $PullRequestUrl
|
||
Write-Host ''
|
||
Write-Host 'Nächster Schritt im Browser: Pull Request #18 und CI prüfen. Erst nach grüner CI nach main mergen.' -ForegroundColor Yellow
|
||
} catch {
|
||
Fail $_.Exception.Message
|
||
exit 1
|
||
} finally {
|
||
if (Test-Path -LiteralPath $WorkRoot) {
|
||
Remove-Item -LiteralPath $WorkRoot -Recurse -Force -ErrorAction SilentlyContinue
|
||
}
|
||
}
|