From 2f55761d4048490599ae60a3c2e6751f2813cf6a Mon Sep 17 00:00:00 2001 From: Timothy Bruce Date: Thu, 3 Sep 2026 05:12:12 -0400 Subject: [PATCH 1/6] Propagate framework-dependent archive publication --- packaging/BuildReleaseArchive.ps1 | 111 ++++++++++++++++++++++++------ 1 file changed, 91 insertions(+), 20 deletions(-) diff --git a/packaging/BuildReleaseArchive.ps1 b/packaging/BuildReleaseArchive.ps1 index bfc0bd0..d745bf3 100644 --- a/packaging/BuildReleaseArchive.ps1 +++ b/packaging/BuildReleaseArchive.ps1 @@ -1,24 +1,95 @@ -param([Parameter(Mandatory=$true)][string]$RuntimeIdentifier,[Parameter(Mandatory=$true)][string]$Version,[ValidateSet('Debug','Staging','Release')][string]$Configuration='Release',[string]$ArchiveBaseName='Icod.LineEditor') -$ErrorActionPreference='Stop' +param( + [Parameter(Mandatory = $true)] + [string]$RuntimeIdentifier, + [Parameter(Mandatory = $true)] + [string]$Version, + [ValidateSet('Debug', 'Staging', 'Release')] + [string]$Configuration = 'Release', + [string]$ArchiveBaseName = 'Icod.LineEditor' +) + +$ErrorActionPreference = 'Stop' Set-StrictMode -Version Latest -$repositoryRoot=[System.IO.Path]::GetFullPath((Join-Path $PSScriptRoot '..')) + +$repositoryRoot = [System.IO.Path]::GetFullPath((Join-Path $PSScriptRoot '..')) Import-Module (Join-Path $PSScriptRoot 'RepositoryTools.psm1') -Force -$solutionPath=Get-RepositorySolution -RepositoryRoot $repositoryRoot -$projects=@(Get-SolutionProjects -SolutionPath $solutionPath -RepositoryRoot $repositoryRoot) -$executables=@(Get-ExecutableProjects -ProjectPaths $projects -Configuration $Configuration) -$releaseRoot=Join-Path $repositoryRoot 'artifacts/release' -$stageName="$ArchiveBaseName-$Version-$RuntimeIdentifier" -$stageParent=Join-Path $releaseRoot 'stage' -$stage=Join-Path $stageParent $stageName -$archive=Join-Path $releaseRoot "$stageName.zip" -if(Test-Path $stage){Remove-Item $stage -Recurse -Force}; New-Item -ItemType Directory -Path $stage -Force|Out-Null -Invoke-DotNet -Arguments @('restore',$solutionPath,'-r',$RuntimeIdentifier) -foreach($executable in $executables){ - $publish=Join-Path $releaseRoot "publish/$RuntimeIdentifier/$($executable.AssemblyName)" - Invoke-DotNet -Arguments @('publish',$executable.ProjectPath,'-c',$Configuration,'-r',$RuntimeIdentifier,'--no-restore','--self-contained','false','-p:PublishSingleFile=true','-p:PublishTrimmed=false','-p:DebugType=None','-p:DebugSymbols=false','-p:ContinuousIntegrationBuild=true','-o',$publish) - $file=if($RuntimeIdentifier.StartsWith('win-')){"$($executable.AssemblyName).exe"}else{$executable.AssemblyName} - Copy-Item (Join-Path $publish $file) (Join-Path $stage $file) +$solutionPath = Get-RepositorySolution -RepositoryRoot $repositoryRoot +$projects = @(Get-SolutionProjects -SolutionPath $solutionPath -RepositoryRoot $repositoryRoot) +$executables = @(Get-ExecutableProjects -ProjectPaths $projects -Configuration $Configuration) +$releaseRoot = Join-Path $repositoryRoot 'artifacts/release' +$stageName = "$ArchiveBaseName-$Version-$RuntimeIdentifier" +$stageParent = Join-Path $releaseRoot 'stage' +$stage = Join-Path $stageParent $stageName +$archive = Join-Path $releaseRoot "$stageName.zip" + +if (Test-Path -LiteralPath $stage) { + Remove-Item -LiteralPath $stage -Recurse -Force } -foreach($support in @('README.md','LICENSE')){if(Test-Path (Join-Path $repositoryRoot $support)){Copy-Item (Join-Path $repositoryRoot $support) (Join-Path $stage $support)}} -if($RuntimeIdentifier.StartsWith('win-')){Compress-Archive -LiteralPath $stage -DestinationPath $archive -CompressionLevel Optimal}else{Get-ChildItem $stage -File|Where-Object{$_.Name -in @('lineeditor','ed','red','sed')}|ForEach-Object{& chmod +x $_.FullName}; Push-Location $stageParent;try{& zip -r -q $archive $stageName;if(0 -ne $LASTEXITCODE){throw 'zip failed'}}finally{Pop-Location}} +New-Item -ItemType Directory -Path $stage -Force | Out-Null + +Invoke-DotNet -Arguments @( + 'restore', + $solutionPath, + '-r', + $RuntimeIdentifier +) + +foreach ($executable in $executables) { + $publish = Join-Path $releaseRoot "publish/$RuntimeIdentifier/$($executable.AssemblyName)" + Invoke-DotNet -Arguments @( + 'publish', + $executable.ProjectPath, + '-c', + $Configuration, + '-r', + $RuntimeIdentifier, + '--no-restore', + '--self-contained', + 'false', + '-p:SelfContained=false', + '-p:PublishSingleFile=true', + '-p:PublishTrimmed=false', + '-p:DebugType=None', + '-p:DebugSymbols=false', + '-p:ContinuousIntegrationBuild=true', + '-o', + $publish + ) + $file = if ($RuntimeIdentifier.StartsWith('win-')) { + "$($executable.AssemblyName).exe" + } else { + $executable.AssemblyName + } + Copy-Item \ + -LiteralPath (Join-Path $publish $file) \ + -Destination (Join-Path $stage $file) +} + +foreach ($support in @('README.md', 'LICENSE')) { + $supportPath = Join-Path $repositoryRoot $support + if (Test-Path -LiteralPath $supportPath -PathType Leaf) { + Copy-Item -LiteralPath $supportPath -Destination (Join-Path $stage $support) + } +} + +if ($RuntimeIdentifier.StartsWith('win-')) { + Compress-Archive \ + -LiteralPath $stage \ + -DestinationPath $archive \ + -CompressionLevel Optimal +} else { + Get-ChildItem -LiteralPath $stage -File | + Where-Object { $_.Name -in @('lineeditor', 'ed', 'red', 'sed') } | + ForEach-Object { & chmod +x $_.FullName } + Push-Location $stageParent + try { + & zip -r -q $archive $stageName + if (0 -ne $LASTEXITCODE) { + throw 'zip failed' + } + } finally { + Pop-Location + } +} + Write-Host "Created release archive: $archive" From e6347d3a8961dd78dfe24dda258ad21b6baff24f Mon Sep 17 00:00:00 2001 From: Timothy Bruce Date: Thu, 3 Sep 2026 05:12:47 -0400 Subject: [PATCH 2/6] Correct PowerShell archive script syntax --- packaging/BuildReleaseArchive.ps1 | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/packaging/BuildReleaseArchive.ps1 b/packaging/BuildReleaseArchive.ps1 index d745bf3..1283be7 100644 --- a/packaging/BuildReleaseArchive.ps1 +++ b/packaging/BuildReleaseArchive.ps1 @@ -60,9 +60,7 @@ foreach ($executable in $executables) { } else { $executable.AssemblyName } - Copy-Item \ - -LiteralPath (Join-Path $publish $file) \ - -Destination (Join-Path $stage $file) + Copy-Item -LiteralPath (Join-Path $publish $file) -Destination (Join-Path $stage $file) } foreach ($support in @('README.md', 'LICENSE')) { @@ -73,10 +71,7 @@ foreach ($support in @('README.md', 'LICENSE')) { } if ($RuntimeIdentifier.StartsWith('win-')) { - Compress-Archive \ - -LiteralPath $stage \ - -DestinationPath $archive \ - -CompressionLevel Optimal + Compress-Archive -LiteralPath $stage -DestinationPath $archive -CompressionLevel Optimal } else { Get-ChildItem -LiteralPath $stage -File | Where-Object { $_.Name -in @('lineeditor', 'ed', 'red', 'sed') } | From 63191ee74c3cde947243bb2b8e5b4e16ab27ecb2 Mon Sep 17 00:00:00 2001 From: Timothy Bruce Date: Thu, 3 Sep 2026 05:13:14 -0400 Subject: [PATCH 3/6] Prepare 1.1.1 archive repair release --- Directory.Build.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Directory.Build.props b/Directory.Build.props index e74a1d5..7848b2a 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,7 +1,7 @@ - 1.1.0 + 1.1.1 $(VersionPrefix) $(VersionPrefix) $(VersionPrefix).0 From 7801b2faf9683f63dabbf3167740b79051512bc0 Mon Sep 17 00:00:00 2001 From: Timothy Bruce Date: Thu, 3 Sep 2026 05:13:38 -0400 Subject: [PATCH 4/6] Exercise release archive path in PR validation --- .github/workflows/pull-request.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/pull-request.yaml b/.github/workflows/pull-request.yaml index 15adc59..db509f4 100644 --- a/.github/workflows/pull-request.yaml +++ b/.github/workflows/pull-request.yaml @@ -66,3 +66,7 @@ jobs: if: matrix.verify_packages shell: pwsh run: ./packaging/VerifyPackageArtifact.ps1 -ArtifactDirectory artifacts -Configuration '${{ env.CONFIGURATION }}' -AllowNoPackages + - name: Smoke linux-x64 release archive construction + if: matrix.verify_packages + shell: pwsh + run: ./packaging/BuildReleaseArchive.ps1 -Configuration '${{ env.CONFIGURATION }}' -RuntimeIdentifier 'linux-x64' -Version 'pr' From 631df596f4f52b68649e5a6258016088a538aca4 Mon Sep 17 00:00:00 2001 From: Timothy Bruce Date: Thu, 3 Sep 2026 05:14:16 -0400 Subject: [PATCH 5/6] Centralize framework-dependent publish contract --- Directory.Build.props | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Directory.Build.props b/Directory.Build.props index 7848b2a..2d7bcbe 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,10 +1,11 @@ - 1.1.1 + 1.1.0 $(VersionPrefix) $(VersionPrefix) $(VersionPrefix).0 $(VersionPrefix).0 + false From 6f38f6c2017538b4a67efdcf0b213ae2cc8ad363 Mon Sep 17 00:00:00 2001 From: Timothy Bruce Date: Thu, 3 Sep 2026 05:19:46 -0400 Subject: [PATCH 6/6] Exclude test projects from executable discovery --- packaging/RepositoryTools.psm1 | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packaging/RepositoryTools.psm1 b/packaging/RepositoryTools.psm1 index ec3fbb5..c7f18e3 100644 --- a/packaging/RepositoryTools.psm1 +++ b/packaging/RepositoryTools.psm1 @@ -41,6 +41,11 @@ function Get-ExecutableProjects { param([Parameter(Mandatory = $true)][string[]]$ProjectPaths,[string]$Configuration = 'Release') $result = @() foreach ($projectPath in $ProjectPaths) { + $isTestProject = Get-MSBuildProperty -ProjectPath $projectPath -Name 'IsTestProject' -Configuration $Configuration + if ('true' -eq $isTestProject.Trim().ToLowerInvariant()) { + continue + } + $outputType = Get-MSBuildProperty -ProjectPath $projectPath -Name 'OutputType' -Configuration $Configuration if ($outputType -in @('Exe', 'WinExe')) { $assemblyName = Get-MSBuildProperty -ProjectPath $projectPath -Name 'AssemblyName' -Configuration $Configuration