Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .github/workflows/windows-full-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,12 @@ on:
- "scripts/test-fetch-herdr-annotate.*"
- "scripts/test-fetch-plannotator-tui.*"
- "scripts/test-herdr-windows-plugin.ps1"
- "scripts/test-herdr-windows-full-plugin.ps1"
- "scripts/test-herdr-windows-full-pane.ps1"
- "scripts/test-herdr-windows-full-paths.ps1"
- "scripts/test-http-server.py"
- "scripts/test-windows-full-manifest.py"
- "windows-full/**"
- ".github/workflows/windows-full-ci.yml"
merge_group:

Expand Down Expand Up @@ -53,6 +57,12 @@ jobs:
plannotator-tui-source/herdr/herdr-plugin.toml
- name: pinned Herdr link and list
run: ./scripts/test-herdr-windows-plugin.ps1
- name: pinned Herdr windows-full acceptance and 0.8.2 rejection
run: ./scripts/test-herdr-windows-full-plugin.ps1
- name: windows-full review pane render, quit and teardown
run: ./scripts/test-herdr-windows-full-pane.ps1
- name: windows-full path matrix
run: ./scripts/test-herdr-windows-full-paths.ps1

unix-regression:
strategy:
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
.DS_Store
bin/*
!bin/.gitkeep
windows-full/bin/*
!windows-full/bin/.gitkeep
/rust/target/
33 changes: 21 additions & 12 deletions scripts/fetch-herdr-annotate.ps1
Original file line number Diff line number Diff line change
@@ -1,22 +1,31 @@
$ErrorActionPreference = "Stop"
Set-Location (Join-Path $PSScriptRoot "..")
# Anchored on the script's own location rather than the current directory, and every path
# below is absolute and literal. A checkout path may legitimately contain square brackets --
# the Windows acceptance path matrix requires it -- and PowerShell reads those as wildcards in
# any -Path parameter. Worse, once the current directory contains them, it is stored escaped,
# so even -LiteralPath with a relative path resolves to a name with backticks in it and is not
# found. Not depending on the current directory at all is what makes that whole class go away.
# .NET rather than Split-Path: an extended-length \\?\ root is a path matrix row, and
# Split-Path cannot parse one -- it reports a null drive and returns nothing.
$root = [System.IO.Path]::GetDirectoryName($PSScriptRoot)

$versionContents = Get-Content -LiteralPath "herdr-annotate.version" -Raw
$versionContents = Get-Content -LiteralPath ([System.IO.Path]::Combine($root, "herdr-annotate.version")) -Raw
$version = if ($null -eq $versionContents) { "" } else { [string]$versionContents }
$version = $version.Trim()
if (-not $version) { throw "herdr-annotate.version is empty" }
New-Item -ItemType Directory -Force "bin" | Out-Null
$destination = Join-Path "bin" "herdr-annotate.exe"
$stamp = Join-Path "bin" "herdr-annotate.version"
$binDirectory = [System.IO.Path]::Combine($root, "bin")
[System.IO.Directory]::CreateDirectory($binDirectory) | Out-Null
$destination = [System.IO.Path]::Combine($binDirectory, "herdr-annotate.exe")
$stamp = [System.IO.Path]::Combine($binDirectory, "herdr-annotate.version")
$installed = if (Test-Path -LiteralPath $stamp -PathType Leaf) { ([string](Get-Content -LiteralPath $stamp -Raw)).Trim() } else { "" }

if ((Test-Path $destination) -and $installed -eq $version -and -not $env:HERDR_ANNOTATE_BIN) {
if ((Test-Path -LiteralPath $destination) -and $installed -eq $version -and -not $env:HERDR_ANNOTATE_BIN) {
Write-Output "herdr-annotate $version already installed"
exit 0
}

if ($env:HERDR_ANNOTATE_BIN) {
if (-not (Test-Path $env:HERDR_ANNOTATE_BIN -PathType Leaf)) {
if (-not (Test-Path -LiteralPath $env:HERDR_ANNOTATE_BIN -PathType Leaf)) {
throw "HERDR_ANNOTATE_BIN is not a file: $env:HERDR_ANNOTATE_BIN"
}
Copy-Item -Force -LiteralPath $env:HERDR_ANNOTATE_BIN -Destination "$destination.tmp"
Expand All @@ -35,20 +44,20 @@ $target = switch ($architecture) {
$asset = "herdr-annotate-$target.exe"
$base = "https://github.com/plannotator/herdr-annotate/releases/download/rust-lite-v$version"
$temporary = Join-Path ([System.IO.Path]::GetTempPath()) ("herdr-annotate-" + [guid]::NewGuid())
New-Item -ItemType Directory $temporary | Out-Null
[System.IO.Directory]::CreateDirectory($temporary) | Out-Null
try {
Invoke-WebRequest -UseBasicParsing "$base/$asset" -OutFile (Join-Path $temporary $asset)
Invoke-WebRequest -UseBasicParsing "$base/SHA256SUMS" -OutFile (Join-Path $temporary "SHA256SUMS")
$line = Get-Content (Join-Path $temporary "SHA256SUMS") | Where-Object { $_ -match "\s$([regex]::Escape($asset))$" } | Select-Object -First 1
$line = Get-Content -LiteralPath (Join-Path $temporary "SHA256SUMS") | Where-Object { $_ -match "\s$([regex]::Escape($asset))$" } | Select-Object -First 1
if (-not $line) { throw "$asset is not listed in $base/SHA256SUMS" }
$expected = ($line -split "\s+")[0].ToLowerInvariant()
$actual = (Get-FileHash -Algorithm SHA256 (Join-Path $temporary $asset)).Hash.ToLowerInvariant()
$actual = (Get-FileHash -Algorithm SHA256 -LiteralPath (Join-Path $temporary $asset)).Hash.ToLowerInvariant()
if ($actual -ne $expected) { throw "sha256 mismatch for ${asset}: expected $expected, got $actual" }
Copy-Item -Force (Join-Path $temporary $asset) "$destination.tmp"
Copy-Item -Force -LiteralPath (Join-Path $temporary $asset) -Destination "$destination.tmp"
Move-Item -Force -LiteralPath "$destination.tmp" -Destination $destination
Set-Content -LiteralPath $stamp -NoNewline -Value $version
Write-Output "installed herdr-annotate $version ($target)"
}
finally {
Remove-Item -Recurse -Force $temporary -ErrorAction SilentlyContinue
Remove-Item -Recurse -Force -LiteralPath $temporary -ErrorAction SilentlyContinue
}
48 changes: 36 additions & 12 deletions scripts/fetch-plannotator-tui.ps1
Original file line number Diff line number Diff line change
@@ -1,15 +1,35 @@
# -DestinationDirectory stages the binary and its stamp somewhere other than the repository's
# own bin/, which is how the windows-full variant keeps its copy beside its manifest. Omitted,
# the destination is unchanged, so every existing caller behaves exactly as before. The pin is
# read from the repository root either way: there is one release pin, not one per variant.
param([string]$DestinationDirectory)

$ErrorActionPreference = "Stop"
Set-Location (Join-Path $PSScriptRoot "..")
# Anchored on the script's own location rather than the current directory, and every path
# below is absolute and literal. A checkout path may legitimately contain square brackets --
# the Windows acceptance path matrix requires it -- and PowerShell reads those as wildcards in
# any -Path parameter. Worse, once the current directory contains them, it is stored escaped,
# so even -LiteralPath with a relative path resolves to a name with backticks in it and is not
# found. Not depending on the current directory at all is what makes that whole class go away.
# .NET rather than Split-Path: an extended-length \\?\ root is a path matrix row, and
# Split-Path cannot parse one -- it reports a null drive and returns nothing.
$root = [System.IO.Path]::GetDirectoryName($PSScriptRoot)

$versionContents = Get-Content -LiteralPath "plannotator-tui.version" -Raw
$versionContents = Get-Content -LiteralPath ([System.IO.Path]::Combine($root, "plannotator-tui.version")) -Raw
$version = if ($null -eq $versionContents) { "" } else { [string]$versionContents }
$version = $version.Trim()
if (-not $version) { throw "plannotator-tui.version is empty" }

$destinationDirectory = Join-Path (Get-Location).Path "bin"
$destination = Join-Path $destinationDirectory "plannotator-tui.exe"
$stamp = Join-Path $destinationDirectory "plannotator-tui.version"
New-Item -ItemType Directory -Force $destinationDirectory | Out-Null
$destinationDirectory = if ([string]::IsNullOrWhiteSpace($DestinationDirectory)) {
[System.IO.Path]::Combine($root, "bin")
} else {
$DestinationDirectory
}
$destination = [System.IO.Path]::Combine($destinationDirectory, "plannotator-tui.exe")
$stamp = [System.IO.Path]::Combine($destinationDirectory, "plannotator-tui.version")
# .NET rather than New-Item for the same reason: the destination is an absolute path that may
# contain brackets, and New-Item -Path would treat them as a wildcard.
[System.IO.Directory]::CreateDirectory($destinationDirectory) | Out-Null

$localOverride = [Environment]::GetEnvironmentVariable("PLANNOTATOR_TUI_BIN", "Process")
$hasLocalOverride = $null -ne $localOverride
Expand All @@ -28,9 +48,9 @@ if ((Test-Path -LiteralPath $destination -PathType Leaf) -and
function Install-PlannotatorTui {
param([Parameter(Mandatory = $true)][string]$Source)

$candidate = Join-Path $destinationDirectory ("plannotator-tui-" + [guid]::NewGuid() + ".tmp")
$backup = Join-Path $destinationDirectory ("plannotator-tui-" + [guid]::NewGuid() + ".bak")
$stampBackup = Join-Path $destinationDirectory ("plannotator-tui-version-" + [guid]::NewGuid() + ".bak")
$candidate = [System.IO.Path]::Combine($destinationDirectory, ("plannotator-tui-" + [guid]::NewGuid() + ".tmp"))
$backup = [System.IO.Path]::Combine($destinationDirectory, ("plannotator-tui-" + [guid]::NewGuid() + ".bak"))
$stampBackup = [System.IO.Path]::Combine($destinationDirectory, ("plannotator-tui-version-" + [guid]::NewGuid() + ".bak"))
$hadDestination = Test-Path -LiteralPath $destination -PathType Leaf
$hadStamp = Test-Path -LiteralPath $stamp -PathType Leaf
$replacementCompleted = $false
Expand Down Expand Up @@ -112,16 +132,20 @@ try {
"PLANNOTATOR_TUI_RELEASE_BASE",
"Process"
)
# PLANNOTATOR_TUI_RELEASE_BASE is a test-only seam for a loopback fixture server.
$base = if ($null -ne $releaseBaseOverride) {
# PLANNOTATOR_TUI_RELEASE_BASE is a test-only seam for a loopback fixture server. An empty
# value counts as absent: a caller clearing it through an API that binds $null as "" would
# otherwise leave the name defined, and an empty base builds a URL with no host at all --
# which surfaces as "invalid URI" long after the mistake, through the warn-and-exit-zero
# contract that hides it.
$base = if (-not [string]::IsNullOrWhiteSpace($releaseBaseOverride)) {
$releaseBaseOverride.TrimEnd([char]"/")
} else {
"https://github.com/plannotator/plannotator-tui/releases/download/v$version"
}

$temporary = Join-Path ([System.IO.Path]::GetTempPath()) ("plannotator-tui-" + [guid]::NewGuid())
try {
New-Item -ItemType Directory $temporary | Out-Null
[System.IO.Directory]::CreateDirectory($temporary) | Out-Null
$downloadedAsset = Join-Path $temporary $asset
$checksumFile = Join-Path $temporary "SHA256SUMS"
Invoke-WebRequest -UseBasicParsing "$base/$asset" -OutFile $downloadedAsset
Expand Down
Loading