72 lines
4.0 KiB
PowerShell
72 lines
4.0 KiB
PowerShell
param([string]$BashPath='bash')
|
|
$ErrorActionPreference='Stop'
|
|
$repoRoot=Split-Path $PSScriptRoot -Parent
|
|
$psSource=[IO.File]::ReadAllText((Join-Path $repoRoot 'scripts/deploy-from-workstation.ps1'))
|
|
$parseErrors=$null; $tokens=$null
|
|
$ast=[Management.Automation.Language.Parser]::ParseInput($psSource,[ref]$tokens,[ref]$parseErrors)
|
|
if($parseErrors.Count){throw 'Deployment PowerShell syntax invalid'}
|
|
$function=$ast.Find({param($node) $node -is [Management.Automation.Language.FunctionDefinitionAst] -and $node.Name -eq 'Test-CaiwuReleaseIncludesCommit'},$true)
|
|
if(-not $function){throw 'PowerShell inclusion guard missing'}
|
|
. ([ScriptBlock]::Create($function.Extent.Text))
|
|
$bashSource=[IO.File]::ReadAllText((Join-Path $repoRoot 'scripts/deploy-from-mac.sh')).Replace("`r`n","`n")
|
|
$bashFunction=[regex]::Match($bashSource,'(?ms)^release_includes_commit\(\) \{\n.*?^\}').Value
|
|
if(-not $bashFunction){throw 'Bash inclusion guard missing'}
|
|
|
|
$fixture=Join-Path ([IO.Path]::GetTempPath()) ('caiwu-release-inclusion-'+[guid]::NewGuid().ToString('N'))
|
|
New-Item -ItemType Directory -Path $fixture | Out-Null
|
|
$expectedFixture=[IO.Path]::GetFullPath($fixture)
|
|
function Invoke-FixtureGit {
|
|
param([Parameter(ValueFromRemainingArguments=$true)][string[]]$GitArgs)
|
|
$output=@(git @GitArgs 2>&1)
|
|
if($LASTEXITCODE -ne 0){throw "Fixture Git failed: $($GitArgs[0])"}
|
|
return $output
|
|
}
|
|
function New-FixtureCommit {
|
|
param([string]$Value,[string]$Message)
|
|
[IO.File]::WriteAllText((Join-Path $fixture 'value.txt'),$Value)
|
|
Invoke-FixtureGit add value.txt | Out-Null
|
|
Invoke-FixtureGit commit -m $Message | Out-Null
|
|
return (Invoke-FixtureGit rev-parse HEAD) -join ''
|
|
}
|
|
Push-Location $fixture
|
|
try {
|
|
Invoke-FixtureGit init -b main | Out-Null
|
|
Invoke-FixtureGit config user.name 'Release guard fixture' | Out-Null
|
|
Invoke-FixtureGit config user.email 'release-guard@example.invalid' | Out-Null
|
|
$base=New-FixtureCommit 'base' 'base'
|
|
Invoke-FixtureGit switch -c hotfix | Out-Null
|
|
$hotfix=New-FixtureCommit 'hotfix content' 'hotfix'
|
|
Invoke-FixtureGit switch main | Out-Null
|
|
$squashed=New-FixtureCommit 'hotfix content' 'squashed identity'
|
|
$release=New-FixtureCommit 'next authorized change' 'new release'
|
|
Invoke-FixtureGit switch -c unrelated $base | Out-Null
|
|
$unrelated=New-FixtureCommit 'different hotfix content' 'hotfix'
|
|
$cases=@(
|
|
@{name='direct ancestor';previous=$base;release=$release;expected=$true},
|
|
@{name='same commit';previous=$hotfix;release=$hotfix;expected=$true},
|
|
@{name='identical squash tree at head';previous=$hotfix;release=$squashed;expected=$true},
|
|
@{name='identical squash tree in release ancestry';previous=$hotfix;release=$release;expected=$true},
|
|
@{name='real unmerged change';previous=$unrelated;release=$release;expected=$false},
|
|
@{name='rollback to before hotfix';previous=$hotfix;release=$base;expected=$false},
|
|
@{name='missing deployed commit';previous=('0'*40);release=$release;expected=$false},
|
|
@{name='missing release commit';previous=$hotfix;release=('0'*40);expected=$false}
|
|
)
|
|
foreach($case in $cases){
|
|
$actual=Test-CaiwuReleaseIncludesCommit -PreviousSha $case.previous -ReleaseSha $case.release
|
|
if($actual -ne $case.expected){throw "PowerShell failed: $($case.name)"}
|
|
$code=$bashFunction+"`nrelease_includes_commit "+'"$1" "$2"'
|
|
& $BashPath --noprofile --norc -c $code guard $case.previous $case.release
|
|
$bashActual=$LASTEXITCODE -eq 0
|
|
if($bashActual -ne $case.expected){throw "Bash failed: $($case.name)"}
|
|
}
|
|
"PASS: $($cases.Count) real Git cases for both PowerShell and Bash guards"
|
|
} finally {
|
|
Pop-Location
|
|
$resolved=(Resolve-Path -LiteralPath $fixture).Path
|
|
if([IO.Path]::GetFullPath($resolved) -ne $expectedFixture -or (Get-Item -LiteralPath $resolved).Attributes.HasFlag([IO.FileAttributes]::ReparsePoint)){
|
|
throw 'Refusing cleanup outside the exact generated fixture directory'
|
|
}
|
|
Remove-Item -LiteralPath $resolved -Recurse -Force
|
|
}
|
|
exit 0
|