From 1822c6495821e6f2e42d3f8a0d3c0abb046b581e Mon Sep 17 00:00:00 2001 From: justcoding121 Date: Mon, 31 Aug 2026 04:39:43 -0500 Subject: [PATCH 1/7] fix(packaging): repair HTTP/3 bundle, MSI path, and release disk pressure Unblock v7.0.1-beta assets: fix Linux patchelf catch shadowing, macOS Test-Path -or parse, WiX output path, and limit parallel self-contained publishes. --- .github/workflows/release.yml | 13 +++++++++++++ tools/packaging/build-inspector-msi.ps1 | 15 ++++++++++----- tools/packaging/bundle-http3-native.ps1 | 12 +++++++----- 3 files changed, 30 insertions(+), 10 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index cf9eea964..97e14ab9b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -113,6 +113,8 @@ jobs: contents: read strategy: fail-fast: false + # Cap concurrency — many self-contained publishes on shared ubuntu runners run out of disk. + max-parallel: 3 matrix: include: - rid: linux-x64 @@ -131,6 +133,11 @@ jobs: os: macos-latest steps: - uses: actions/checkout@v6 + - name: Free disk space (Linux) + if: runner.os == 'Linux' + run: | + sudo rm -rf /usr/share/dotnet /usr/local/lib/android /opt/ghc /opt/hostedtoolcache/CodeQL || true + df -h - uses: actions/setup-dotnet@v5 with: dotnet-version: '10.0.x' @@ -191,6 +198,7 @@ jobs: contents: read strategy: fail-fast: false + max-parallel: 3 matrix: include: - rid: win-x64 @@ -216,6 +224,11 @@ jobs: msi: false steps: - uses: actions/checkout@v6 + - name: Free disk space (Linux) + if: runner.os == 'Linux' + run: | + sudo rm -rf /usr/share/dotnet /usr/local/lib/android /opt/ghc /opt/hostedtoolcache/CodeQL || true + df -h - uses: actions/setup-dotnet@v5 with: dotnet-version: '10.0.x' diff --git a/tools/packaging/build-inspector-msi.ps1 b/tools/packaging/build-inspector-msi.ps1 index f5a08b8ba..faf5a9615 100644 --- a/tools/packaging/build-inspector-msi.ps1 +++ b/tools/packaging/build-inspector-msi.ps1 @@ -18,14 +18,19 @@ if (-not (Test-Path (Join-Path $PayloadDir "TitaniumInspector.exe"))) { throw "TitaniumInspector.exe missing under $PayloadDir" } +# Always absolute: `dotnet wix -o` is relative to the WiX cwd, while Test-Path after +# Pop-Location is relative to the caller's cwd (repo root on CI). +$msiLeaf = Split-Path -Leaf $OutputMsi +$outDir = Split-Path -Parent $OutputMsi +if ([string]::IsNullOrWhiteSpace($outDir)) { + $outDir = (Get-Location).Path +} +New-Item -ItemType Directory -Force -Path $outDir | Out-Null +$OutputMsi = Join-Path (Resolve-Path $outDir) $msiLeaf + Push-Location $wixDir try { dotnet tool restore - $outDir = Split-Path -Parent $OutputMsi - if ($outDir) { - New-Item -ItemType Directory -Force -Path $outDir | Out-Null - $OutputMsi = Join-Path (Resolve-Path $outDir) (Split-Path -Leaf $OutputMsi) - } & dotnet wix build $wxs ` -b "PayloadDir=$PayloadDir" ` diff --git a/tools/packaging/bundle-http3-native.ps1 b/tools/packaging/bundle-http3-native.ps1 index 59614ce35..aa44b9a69 100644 --- a/tools/packaging/bundle-http3-native.ps1 +++ b/tools/packaging/bundle-http3-native.ps1 @@ -237,13 +237,15 @@ function Ensure-SonameLinks([string] $dir) { function Set-LinuxRpath([string] $dir) { $patchelf = Ensure-Patchelf Get-ChildItem -Path $dir -File -Filter "*.so*" | ForEach-Object { + $soFile = $_ # Skip pure symlinks - if ($_.Attributes -band [IO.FileAttributes]::ReparsePoint) { return } + if ($soFile.Attributes -band [IO.FileAttributes]::ReparsePoint) { return } try { - Invoke-Native $patchelf @("--set-rpath", "`$ORIGIN", $_.FullName) + Invoke-Native $patchelf @("--set-rpath", "`$ORIGIN", $soFile.FullName) } catch { - Write-Info "patchelf skipped $($_.Name): $_" + # Catch uses $_ as the error; keep $soFile for the name. + Write-Info "patchelf skipped $($soFile.Name): $_" } } } @@ -367,10 +369,10 @@ function Bundle-Homebrew { $local = Join-Path $PublishDir $depLeaf if (-not (Test-Path $local)) { # map libssl.3.dylib style - $alt = $dylibs | Where-Object { $_.Name -like ($depLeaf -replace '\..*$','') + "*" } | Select-Object -First 1 + $alt = $dylibs | Where-Object { $_.Name -like (($depLeaf -replace '\..*$','') + "*") } | Select-Object -First 1 if ($alt) { $depLeaf = $alt.Name; $local = $alt.FullName } } - if (Test-Path $local -or ($dylibs.Name -contains $depLeaf)) { + if ((Test-Path $local) -or ($dylibs.Name -contains $depLeaf)) { if ($dep -ne "@loader_path/$depLeaf") { try { Invoke-Native "install_name_tool" @("-change", $dep, "@loader_path/$depLeaf", $lib.FullName) From b3192a04e35ae873c0c673ac4809631c0299422b Mon Sep 17 00:00:00 2001 From: justcoding121 Date: Mon, 31 Aug 2026 05:26:39 -0500 Subject: [PATCH 2/7] fix(tests): skip Windows Root-store CryptUI prompts that hang CI Root Add/Remove dialogs blocked unattended test runs; suppress them under CI and test ModuleInitializers, and stop NullRoot cleanup from targeting the product CA CN. --- .../Certificates/CertificateManager.cs | 46 +++++++++++++++++++ .../PublicAPI.Unshipped.txt | 2 + .../SuppressRootStoreUiModuleInit.cs | 14 ++++++ .../InspectorChromeSystemProxyE2ETests.cs | 14 +++++- .../SuppressRootStoreUiModuleInit.cs | 16 +++++++ .../SuppressRootStoreUiModuleInit.cs | 15 ++++++ .../SuppressRootStoreUiModuleInit.cs | 14 ++++++ .../SuppressRootStoreUiModuleInit.cs | 14 ++++++ .../CertificateManagerTests.cs | 38 ++++++++++++++- .../SuppressRootStoreUiModuleInit.cs | 14 ++++++ 10 files changed, 184 insertions(+), 3 deletions(-) create mode 100644 tests/Titanium.Cli.Tests/SuppressRootStoreUiModuleInit.cs create mode 100644 tests/Titanium.E2E.Tests/SuppressRootStoreUiModuleInit.cs create mode 100644 tests/Titanium.Inspector.Tests/SuppressRootStoreUiModuleInit.cs create mode 100644 tests/Titanium.Plus.Tests/SuppressRootStoreUiModuleInit.cs create mode 100644 tests/Titanium.Web.Proxy.IntegrationTests/SuppressRootStoreUiModuleInit.cs create mode 100644 tests/Titanium.Web.Proxy.UnitTests/SuppressRootStoreUiModuleInit.cs diff --git a/src/Titanium.Web.Proxy/Certificates/CertificateManager.cs b/src/Titanium.Web.Proxy/Certificates/CertificateManager.cs index 6c2cb7396..cf6d73ae1 100644 --- a/src/Titanium.Web.Proxy/Certificates/CertificateManager.cs +++ b/src/Titanium.Web.Proxy/Certificates/CertificateManager.cs @@ -87,6 +87,28 @@ public sealed class CertificateManager : IDisposable private static readonly ConcurrentDictionary _saveCertificateLocks = new(); + /// + /// When , skip Add/Remove that trigger Windows + /// CryptUI "Root Certificate Store" Yes/No dialogs (which hang headless CI and unattended + /// dotnet test). Personal () mutations still run. + /// Also treated as true when CI, GITHUB_ACTIONS, TF_BUILD, or + /// TITANIUM_SKIP_ROOT_STORE_UI=1 is set. Opt back in for intentional interactive Install CA + /// (e.g. local E2E-Slow Chrome) by setting this to in a process that + /// does not set those env vars. + /// + public static bool SuppressInteractiveRootStoreMutations { get; set; } + + /// + /// True when Root-store Add/Remove should be skipped to avoid modal CryptUI prompts. + /// + internal static bool ShouldSuppressInteractiveRootStoreMutations => + SuppressInteractiveRootStoreMutations + || IsTruthyEnv("CI") + || IsTruthyEnv("GITHUB_ACTIONS") + || IsTruthyEnv("TF_BUILD") + || string.Equals(Environment.GetEnvironmentVariable("TITANIUM_SKIP_ROOT_STORE_UI"), "1", + StringComparison.Ordinal); + /// /// Cache dictionary /// @@ -660,6 +682,10 @@ private void RemoveOrphanedSameCommonNameCertificates(StoreLocation storeLocatio private void RemoveMatchingCertificates( StoreName storeName, StoreLocation storeLocation, string expectedCn, string? keepThumbprint) { + // Root Remove shows a blocking "Do you want to DELETE ... from the Root Store?" dialog on Windows. + if (storeName == StoreName.Root && ShouldSuppressInteractiveRootStoreMutations) + return; + try { using var store = new X509Store(storeName, storeLocation); @@ -708,6 +734,10 @@ private bool InstallCertificate(StoreName storeName, StoreLocation storeLocation if (FindCertificates(storeName, storeLocation, certificate.Thumbprint).Count > 0) return false; + // Root Add shows a blocking Trusted Root Yes/No security dialog on Windows. + if (storeName == StoreName.Root && ShouldSuppressInteractiveRootStoreMutations) + return false; + var x509Store = new X509Store(storeName, storeLocation); try @@ -1192,6 +1222,14 @@ internal static CertificateEngine CoerceEngineForPlatform(CertificateEngine valu return value; } + private static bool IsTruthyEnv(string name) + { + var v = Environment.GetEnvironmentVariable(name); + return string.Equals(v, "true", StringComparison.OrdinalIgnoreCase) + || string.Equals(v, "1", StringComparison.OrdinalIgnoreCase) + || string.Equals(v, "yes", StringComparison.OrdinalIgnoreCase); + } + private static bool IsSelfSigned(X509Certificate2 cert) => cert.SubjectName.RawData.SequenceEqual(cert.IssuerName.RawData); @@ -1389,6 +1427,10 @@ public bool TrustRootCertificateAsAdmin(bool machineTrusted = false) : true; // NOSONAR S1125 } + // Elevated certutil shows UAC; skip in CI / test processes that suppress Root UI. + if (ShouldSuppressInteractiveRootStoreMutations) + return false; + // certutil.exe only accepts the PFX password via a plain "-p password" command-line argument - // it has no file/stdin-based alternative (confirmed: no documented option to read it from a // file). ProcessStartInfo.Arguments is visible to any other process/user that lists this @@ -1534,6 +1576,10 @@ public bool RemoveTrustedRootCertificateAsAdmin(bool machineTrusted = false) : true; // NOSONAR S1125 } + // Elevated certutil -delstore shows UAC; skip when Root UI is suppressed. + if (ShouldSuppressInteractiveRootStoreMutations) + return true; + var infos = new List(); if (!machineTrusted) infos.Add(new ProcessStartInfo diff --git a/src/Titanium.Web.Proxy/PublicAPI.Unshipped.txt b/src/Titanium.Web.Proxy/PublicAPI.Unshipped.txt index 02dc461dd..21430d4c6 100644 --- a/src/Titanium.Web.Proxy/PublicAPI.Unshipped.txt +++ b/src/Titanium.Web.Proxy/PublicAPI.Unshipped.txt @@ -25,6 +25,8 @@ Titanium.Web.Proxy.Network.CertificateManager.ApplyFastColdStartLeafSettings() - static Titanium.Web.Proxy.Network.DefaultCertificateDiskCache.GetSharedLeafCertificateDirectory() -> string! static Titanium.Web.Proxy.Network.CertificateManager.LeafRsaKeyPairBufferSize.get -> int static Titanium.Web.Proxy.Network.CertificateManager.LeafRsaKeyPairBufferSize.set -> void +static Titanium.Web.Proxy.Network.CertificateManager.SuppressInteractiveRootStoreMutations.get -> bool +static Titanium.Web.Proxy.Network.CertificateManager.SuppressInteractiveRootStoreMutations.set -> void Titanium.Web.Proxy.Options.ProxyResourceLimits.MaxCertificateDiskCacheEntries.get -> int? Titanium.Web.Proxy.Options.ProxyResourceLimits.MaxOriginHttp2ConnectionsPerAuthority.get -> int Titanium.Web.Proxy.Options.ProxyResourceLimits.WithCertificateCacheBounds(int? maxCertificateCacheEntries, int? maxCertificateDiskCacheEntries) -> Titanium.Web.Proxy.Options.ProxyResourceLimits! diff --git a/tests/Titanium.Cli.Tests/SuppressRootStoreUiModuleInit.cs b/tests/Titanium.Cli.Tests/SuppressRootStoreUiModuleInit.cs new file mode 100644 index 000000000..bdad11c8b --- /dev/null +++ b/tests/Titanium.Cli.Tests/SuppressRootStoreUiModuleInit.cs @@ -0,0 +1,14 @@ +using System.Runtime.CompilerServices; +using Titanium.Web.Proxy.Network; + +namespace Titanium.Cli.Tests; + +/// +/// Prevent Windows CryptUI Root Store Yes/No dialogs from hanging local/CI test runs. +/// +internal static class SuppressRootStoreUiModuleInit +{ + [ModuleInitializer] + internal static void Init() => + CertificateManager.SuppressInteractiveRootStoreMutations = true; +} diff --git a/tests/Titanium.E2E.Tests/InspectorChromeSystemProxyE2ETests.cs b/tests/Titanium.E2E.Tests/InspectorChromeSystemProxyE2ETests.cs index db88b61a9..50a520b1c 100644 --- a/tests/Titanium.E2E.Tests/InspectorChromeSystemProxyE2ETests.cs +++ b/tests/Titanium.E2E.Tests/InspectorChromeSystemProxyE2ETests.cs @@ -4,6 +4,7 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; using Titanium.E2E.Tests.Harness; using Titanium.Inspector.Services; +using Titanium.Web.Proxy.Network; namespace Titanium.E2E.Tests; @@ -43,8 +44,17 @@ public async Task Chrome_ThroughSystemProxy_WithQuicDisabled_CapturesSession() try { await interception.StartAsync(IPAddress.Loopback, proxyPort); - var trusted = interception.InstallRootCertificate(machineStore: false); - Assert.IsTrue(trusted, "CA must be in CurrentUser Root for Chrome"); + var previousSuppress = CertificateManager.SuppressInteractiveRootStoreMutations; + CertificateManager.SuppressInteractiveRootStoreMutations = false; + try + { + var trusted = interception.InstallRootCertificate(machineStore: false); + Assert.IsTrue(trusted, "CA must be in CurrentUser Root for Chrome"); + } + finally + { + CertificateManager.SuppressInteractiveRootStoreMutations = previousSuppress; + } Assert.IsTrue(interception.SetSystemProxy(true), "SetAsSystemProxy failed"); chromeProc = Process.Start(new ProcessStartInfo diff --git a/tests/Titanium.E2E.Tests/SuppressRootStoreUiModuleInit.cs b/tests/Titanium.E2E.Tests/SuppressRootStoreUiModuleInit.cs new file mode 100644 index 000000000..daeb8f96b --- /dev/null +++ b/tests/Titanium.E2E.Tests/SuppressRootStoreUiModuleInit.cs @@ -0,0 +1,16 @@ +using System.Runtime.CompilerServices; +using Titanium.Web.Proxy.Network; + +namespace Titanium.E2E.Tests; + +/// +/// Prevent Windows CryptUI Root Store Yes/No dialogs from hanging automated E2E. +/// Intentional interactive Install CA (e.g. E2E-Slow Chrome) must set +/// to false. +/// +internal static class SuppressRootStoreUiModuleInit +{ + [ModuleInitializer] + internal static void Init() => + CertificateManager.SuppressInteractiveRootStoreMutations = true; +} diff --git a/tests/Titanium.Inspector.Tests/SuppressRootStoreUiModuleInit.cs b/tests/Titanium.Inspector.Tests/SuppressRootStoreUiModuleInit.cs new file mode 100644 index 000000000..92f2b3959 --- /dev/null +++ b/tests/Titanium.Inspector.Tests/SuppressRootStoreUiModuleInit.cs @@ -0,0 +1,15 @@ +using System.Runtime.CompilerServices; +using Titanium.Web.Proxy.Network; + +namespace Titanium.Inspector.Tests; + +/// +/// Prevent Windows CryptUI Root Store Yes/No dialogs from hanging local/CI test runs. +/// Inspector tests should prefer UseInMemoryTrustState; this is a safety net. +/// +internal static class SuppressRootStoreUiModuleInit +{ + [ModuleInitializer] + internal static void Init() => + CertificateManager.SuppressInteractiveRootStoreMutations = true; +} diff --git a/tests/Titanium.Plus.Tests/SuppressRootStoreUiModuleInit.cs b/tests/Titanium.Plus.Tests/SuppressRootStoreUiModuleInit.cs new file mode 100644 index 000000000..23fbb2d63 --- /dev/null +++ b/tests/Titanium.Plus.Tests/SuppressRootStoreUiModuleInit.cs @@ -0,0 +1,14 @@ +using System.Runtime.CompilerServices; +using Titanium.Web.Proxy.Network; + +namespace Titanium.Plus.Tests; + +/// +/// Prevent Windows CryptUI Root Store Yes/No dialogs from hanging local/CI test runs. +/// +internal static class SuppressRootStoreUiModuleInit +{ + [ModuleInitializer] + internal static void Init() => + CertificateManager.SuppressInteractiveRootStoreMutations = true; +} diff --git a/tests/Titanium.Web.Proxy.IntegrationTests/SuppressRootStoreUiModuleInit.cs b/tests/Titanium.Web.Proxy.IntegrationTests/SuppressRootStoreUiModuleInit.cs new file mode 100644 index 000000000..81d2d16fc --- /dev/null +++ b/tests/Titanium.Web.Proxy.IntegrationTests/SuppressRootStoreUiModuleInit.cs @@ -0,0 +1,14 @@ +using System.Runtime.CompilerServices; +using Titanium.Web.Proxy.Network; + +namespace Titanium.Web.Proxy.IntegrationTests; + +/// +/// Prevent Windows CryptUI Root Store Yes/No dialogs from hanging local/CI test runs. +/// +internal static class SuppressRootStoreUiModuleInit +{ + [ModuleInitializer] + internal static void Init() => + CertificateManager.SuppressInteractiveRootStoreMutations = true; +} diff --git a/tests/Titanium.Web.Proxy.UnitTests/CertificateManagerTests.cs b/tests/Titanium.Web.Proxy.UnitTests/CertificateManagerTests.cs index 369923320..3f7afcfa7 100644 --- a/tests/Titanium.Web.Proxy.UnitTests/CertificateManagerTests.cs +++ b/tests/Titanium.Web.Proxy.UnitTests/CertificateManagerTests.cs @@ -852,7 +852,12 @@ public async Task ClearRootCertificate_DisposesPendingEvictionsImmediately() [TestMethod] public void RemoveTrustedRootCertificate_NullRoot_LogsWithoutThrowing() { - using var mgr = new CertificateManager(null, null, false, false, false, NullLogger.Instance) + // Unique CN: must not match the product default "Titanium Root Certificate Authority" + // or Remove walks CurrentUser\Root and Windows shows a blocking DELETE dialog. + using var mgr = new CertificateManager( + "Titanium UnitTest NullRoot CA " + Guid.NewGuid().ToString("N"), + "TitaniumUnitTest", + false, false, false, NullLogger.Instance) { CertificateEngine = CertificateEngine.BouncyCastleFast }; @@ -860,6 +865,37 @@ public void RemoveTrustedRootCertificate_NullRoot_LogsWithoutThrowing() Assert.IsNull(mgr.RootCertificate); } + [TestMethod] + public void SuppressInteractiveRootStoreMutations_SkipsRootAddAndRemove() + { + if (!RunTime.IsWindows) + Assert.Inconclusive("Root-store CryptUI suppression is Windows-focused."); + + var previous = CertificateManager.SuppressInteractiveRootStoreMutations; + CertificateManager.SuppressInteractiveRootStoreMutations = true; + try + { + const string cn = "Titanium UnitTest Suppress Root UI CA"; + using var mgr = new CertificateManager(cn, "TitaniumUnitTest", false, false, false, + NullLogger.Instance) + { + CertificateEngine = CertificateEngine.BouncyCastle + }; + Assert.IsTrue(mgr.CreateRootCertificate(false)); + + // Would otherwise open Trusted Root Yes/No; must no-op under suppress. + mgr.TrustRootCertificate(machineTrusted: false); + Assert.IsFalse(mgr.IsRootCertificateUserTrusted()); + + // Would otherwise open Root DELETE Yes/No for any same-CN leftovers. + mgr.RemoveTrustedRootCertificate(machineTrusted: false); + } + finally + { + CertificateManager.SuppressInteractiveRootStoreMutations = previous; + } + } + /// /// Only DefaultWindows is rewritten off Windows; BouncyCastleFast must remain selectable /// on Linux/macOS (it is fully managed BouncyCastle). diff --git a/tests/Titanium.Web.Proxy.UnitTests/SuppressRootStoreUiModuleInit.cs b/tests/Titanium.Web.Proxy.UnitTests/SuppressRootStoreUiModuleInit.cs new file mode 100644 index 000000000..a6e261360 --- /dev/null +++ b/tests/Titanium.Web.Proxy.UnitTests/SuppressRootStoreUiModuleInit.cs @@ -0,0 +1,14 @@ +using System.Runtime.CompilerServices; +using Titanium.Web.Proxy.Network; + +namespace Titanium.Web.Proxy.UnitTests; + +/// +/// Prevent Windows CryptUI Root Store Yes/No dialogs from hanging local/CI test runs. +/// +internal static class SuppressRootStoreUiModuleInit +{ + [ModuleInitializer] + internal static void Init() => + CertificateManager.SuppressInteractiveRootStoreMutations = true; +} From 93b772de66ade94c7494ebcb9d6c206fa496fe04 Mon Sep 17 00:00:00 2001 From: justcoding121 Date: Mon, 31 Aug 2026 05:31:27 -0500 Subject: [PATCH 3/7] fix(inspector): await ZipArchiveEntry.OpenAsync in session archive I/O EOF --- src/Titanium.Inspector/Services/SessionArchive.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Titanium.Inspector/Services/SessionArchive.cs b/src/Titanium.Inspector/Services/SessionArchive.cs index 34608348e..bb354c5bb 100644 --- a/src/Titanium.Inspector/Services/SessionArchive.cs +++ b/src/Titanium.Inspector/Services/SessionArchive.cs @@ -70,7 +70,7 @@ public static async Task ExportNativeArchiveAsync(IEnumerable s { ct.ThrowIfCancellationRequested(); var entry = zip.CreateEntry($"session-{index:D5}.json"); - await using var stream = entry.Open(); + await using var stream = await entry.OpenAsync(ct); await JsonSerializer.SerializeAsync(stream, session, cancellationToken: ct); index++; } @@ -98,7 +98,7 @@ public static async Task> ImportNativeArchiveAsync(string continue; } - await using var stream = entry.Open(); + await using var stream = await entry.OpenAsync(ct); var snap = await JsonSerializer.DeserializeAsync(stream, cancellationToken: ct); if (snap is not null) { From 6843c7b86a7a0a9e9322be13f9ff995106b1e73d Mon Sep 17 00:00:00 2001 From: justcoding121 Date: Mon, 31 Aug 2026 05:57:07 -0500 Subject: [PATCH 4/7] fix(ci): grant contents:write so DocFX publish can push Publish Documentation failed with 403 because the build job only had contents:read for GITHUB_TOKEN. Other workflows that push already have write. --- .github/workflows/dotnetcore.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/dotnetcore.yml b/.github/workflows/dotnetcore.yml index 1a447a69b..763dd8cfe 100644 --- a/.github/workflows/dotnetcore.yml +++ b/.github/workflows/dotnetcore.yml @@ -34,7 +34,9 @@ jobs: runs-on: windows-latest timeout-minutes: 60 permissions: - contents: read + # write: Publish Documentation (EndBug/add-and-commit) pushes DocFX output to develop. + # GITHUB_TOKEN with contents:read cannot push (403 github-actions[bot]). + contents: write # SonarCloud / PR decoration when token is present pull-requests: write checks: write From abf1e87bff665f9d29d2399ab66b45afc867dee9 Mon Sep 17 00:00:00 2001 From: justcoding121 Date: Mon, 31 Aug 2026 05:59:14 -0500 Subject: [PATCH 5/7] chore(release): bump to 7.0.2 for beta cut Abandon incomplete 7.0.1-beta product assets; NuGet 7.0.1-beta already shipped. Align VersionPrefix, AssemblyVersion, E2E/HAR gates, and docs for 7.0.2-beta / 7.0.2.0. --- README.md | 6 +++--- src/Titanium.Cli/Titanium.Cli.csproj | 2 +- src/Titanium.Inspector/Services/SessionArchive.cs | 2 +- src/Titanium.Inspector/Titanium.Inspector.csproj | 2 +- src/Titanium.Plus/Titanium.Plus.csproj | 2 +- .../Titanium.Web.Proxy.Abstractions.csproj | 2 +- .../Titanium.Web.Proxy.Configuration.csproj | 2 +- src/Titanium.Web.Proxy/Properties/AssemblyInfo.cs | 4 ++-- src/Titanium.Web.Proxy/Titanium.Web.Proxy.csproj | 2 +- tests/Titanium.E2E.Tests/CliCommandE2ETests.cs | 4 ++-- tools/RpsLoadProbe/PERF-GATES.md | 2 +- website/docs/inspector.md | 4 ++-- website/docs/install.md | 4 ++-- website/docs/library.md | 2 +- website/download.md | 4 ++-- 15 files changed, 22 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index 6ad31fbe5..39e92e074 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,7 @@ A lightweight, high-performance HTTP(S) proxy — reverse / edge CLI, desktop In | **Titanium.Cli** (`titanium` / `twp`) | Standalone reverse / edge proxy for any stack: `run`, `test`, `version`, `update` | [Download (Windows, Linux & Mac)](https://titaniumproxy.com/download#cli) | | **Titanium Inspector** | Desktop MITM debugger (session grid, inspectors, AutoResponder, breakpoints, HAR) | [Download (Windows, Linux & Mac)](https://titaniumproxy.com/download#inspector) | | **Titanium.Plus** | Optional advanced features: control plane, ops, observability, and dashboard | After installing CLI, run `titanium update --plus` | -| **Titanium.Web.Proxy** | Core library. Embed a MITM and/or reverse proxy in a .NET app | [NuGet](https://www.nuget.org/packages/Titanium.Web.Proxy/7.0.1-beta) (`dotnet add package Titanium.Web.Proxy --prerelease`) | +| **Titanium.Web.Proxy** | Core library. Embed a MITM and/or reverse proxy in a .NET app | [NuGet](https://www.nuget.org/packages/Titanium.Web.Proxy/7.0.2-beta) (`dotnet add package Titanium.Web.Proxy --prerelease`) | CLI and Plus target reverse-proxy / edge workloads (routing, load balancing, health, discovery) on Windows, Linux, and macOS. Inspector is the MITM debugging product. The Core library is the embed path for .NET. Requires .NET 10 or later. @@ -67,7 +67,7 @@ On Windows, **winget is stable-only**: winget install justcoding121.TitaniumCli ``` -For **beta**, download self-contained zips from [Download](https://titaniumproxy.com/download) / [GitHub Releases](https://github.com/justcoding121/titanium-web-proxy/releases) when a product release includes `Titanium.Cli-*.zip` assets (e.g. `v7.0.1-beta`). Extract and run: +For **beta**, download self-contained zips from [Download](https://titaniumproxy.com/download) / [GitHub Releases](https://github.com/justcoding121/titanium-web-proxy/releases) when a product release includes `Titanium.Cli-*.zip` assets (e.g. `v7.0.2-beta`). Extract and run: ```shell titanium run -c twp.yaml @@ -82,7 +82,7 @@ Optional Plus: run `titanium update --plus` (add `--channel beta` for prerelease ### Titanium Inspector -Prefer [Download](https://titaniumproxy.com/download). On Windows, winget id `justcoding121.TitaniumInspector` is **stable-only**; MSI / portable zip for beta come from the product `v*` release (e.g. `v7.0.1-beta`). Start interception from the Capture menu, install the root CA, then toggle system proxy. +Prefer [Download](https://titaniumproxy.com/download). On Windows, winget id `justcoding121.TitaniumInspector` is **stable-only**; MSI / portable zip for beta come from the product `v*` release (e.g. `v7.0.2-beta`). Start interception from the Capture menu, install the root CA, then toggle system proxy. ## Quick start diff --git a/src/Titanium.Cli/Titanium.Cli.csproj b/src/Titanium.Cli/Titanium.Cli.csproj index 3afa41f7d..b42c8fcb6 100644 --- a/src/Titanium.Cli/Titanium.Cli.csproj +++ b/src/Titanium.Cli/Titanium.Cli.csproj @@ -7,7 +7,7 @@ latest enable false - 7.0.1 + 7.0.2 Jehonathan Thomas Titanium Web Proxy CLI (titanium / twp). MIT diff --git a/src/Titanium.Inspector/Services/SessionArchive.cs b/src/Titanium.Inspector/Services/SessionArchive.cs index bb354c5bb..cd813a204 100644 --- a/src/Titanium.Inspector/Services/SessionArchive.cs +++ b/src/Titanium.Inspector/Services/SessionArchive.cs @@ -18,7 +18,7 @@ public static Task ExportHarAsync(IEnumerable sessions, string log = new { version = "1.2", - creator = new { name = "Titanium Inspector", version = "7.0.1" }, + creator = new { name = "Titanium Inspector", version = "7.0.2" }, entries, }, }; diff --git a/src/Titanium.Inspector/Titanium.Inspector.csproj b/src/Titanium.Inspector/Titanium.Inspector.csproj index 443b7bf6f..98573f442 100644 --- a/src/Titanium.Inspector/Titanium.Inspector.csproj +++ b/src/Titanium.Inspector/Titanium.Inspector.csproj @@ -8,7 +8,7 @@ enable true false - 7.0.1 + 7.0.2 Jehonathan Thomas Titanium Inspector desktop traffic debugger (PolyForm Noncommercial). LICENSE diff --git a/src/Titanium.Plus/Titanium.Plus.csproj b/src/Titanium.Plus/Titanium.Plus.csproj index 8aed67e74..f407670ae 100644 --- a/src/Titanium.Plus/Titanium.Plus.csproj +++ b/src/Titanium.Plus/Titanium.Plus.csproj @@ -7,7 +7,7 @@ enable True StrongNameKey.snk - 7.0.1 + 7.0.2 Jehonathan Thomas Titanium Web Proxy Plus advanced features plugin (PolyForm Noncommercial). LICENSE diff --git a/src/Titanium.Web.Proxy.Abstractions/Titanium.Web.Proxy.Abstractions.csproj b/src/Titanium.Web.Proxy.Abstractions/Titanium.Web.Proxy.Abstractions.csproj index b8d8560ed..edb6dbc36 100644 --- a/src/Titanium.Web.Proxy.Abstractions/Titanium.Web.Proxy.Abstractions.csproj +++ b/src/Titanium.Web.Proxy.Abstractions/Titanium.Web.Proxy.Abstractions.csproj @@ -7,7 +7,7 @@ enable True StrongNameKey.snk - 7.0.1 + 7.0.2 Jehonathan Thomas Shared contracts for Titanium Web Proxy routing, clusters, middleware, and plugins. MIT diff --git a/src/Titanium.Web.Proxy.Configuration/Titanium.Web.Proxy.Configuration.csproj b/src/Titanium.Web.Proxy.Configuration/Titanium.Web.Proxy.Configuration.csproj index f092aa7fd..b0f124c99 100644 --- a/src/Titanium.Web.Proxy.Configuration/Titanium.Web.Proxy.Configuration.csproj +++ b/src/Titanium.Web.Proxy.Configuration/Titanium.Web.Proxy.Configuration.csproj @@ -7,7 +7,7 @@ enable True StrongNameKey.snk - 7.0.1 + 7.0.2 Jehonathan Thomas YAML/JSON configuration binding for Titanium Web Proxy CLI and reverse-proxy documents. MIT diff --git a/src/Titanium.Web.Proxy/Properties/AssemblyInfo.cs b/src/Titanium.Web.Proxy/Properties/AssemblyInfo.cs index fc825435a..8b290dcd1 100644 --- a/src/Titanium.Web.Proxy/Properties/AssemblyInfo.cs +++ b/src/Titanium.Web.Proxy/Properties/AssemblyInfo.cs @@ -65,5 +65,5 @@ // file-properties version disagreed with the package it was published in. Keep both of the values // below equal to (as Major.Minor.Build.0) whenever that property changes. -[assembly: AssemblyVersion("7.0.1.0")] -[assembly: AssemblyFileVersion("7.0.1.0")] +[assembly: AssemblyVersion("7.0.2.0")] +[assembly: AssemblyFileVersion("7.0.2.0")] diff --git a/src/Titanium.Web.Proxy/Titanium.Web.Proxy.csproj b/src/Titanium.Web.Proxy/Titanium.Web.Proxy.csproj index 357563c37..66dd42756 100644 --- a/src/Titanium.Web.Proxy/Titanium.Web.Proxy.csproj +++ b/src/Titanium.Web.Proxy/Titanium.Web.Proxy.csproj @@ -13,7 +13,7 @@ - 7.0.1 + 7.0.2