@
rebrand installer from TeamsISO to Dragon-ISO - Rename TeamsISO.Installer.wixproj to Dragon-ISO.Installer.wixproj - Update Package.wxs: product name, shortcuts, registry keys, ARP metadata, install directory, and icon all updated to Dragon-ISO - Switch UI from WixUI_InstallDir to WixUI_Minimal (no dir picker) - Add .NET 8 Desktop Runtime detection (registry band key + Version) - Fix release.yml: signing step referenced Dragon-ISO.exe but AssemblyName=DragonISO so exe is DragonISO.exe (no hyphen) - Fix release.yml: upload-artifact@v3 to @v4, add signtool null-guard to MSI signing step Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> @
This commit is contained in:
parent
fc76b0dfb3
commit
3cd2fc1dba
3 changed files with 94 additions and 71 deletions
|
|
@ -1,4 +1,4 @@
|
|||
name: Release
|
||||
name: Release
|
||||
|
||||
# Triggered by pushing an annotated tag of the form v1.2.3 (or any v-prefixed
|
||||
# semver). The job runs on a Windows runner because building the WiX MSI
|
||||
|
|
@ -54,48 +54,48 @@ jobs:
|
|||
}
|
||||
|
||||
- name: Restore (Windows solution filter)
|
||||
run: dotnet restore TeamsISO.Windows.slnf
|
||||
run: dotnet restore Dragon-ISO.Windows.slnf
|
||||
|
||||
- name: Build (Release, treat warnings as errors)
|
||||
run: dotnet build TeamsISO.Windows.slnf --configuration Release --no-restore /p:Version=${{ steps.ver.outputs.version }}
|
||||
run: dotnet build Dragon-ISO.Windows.slnf --configuration Release --no-restore /p:Version=${{ steps.ver.outputs.version }}
|
||||
|
||||
- name: Run unit tests (excluding requires=ndi)
|
||||
run: >
|
||||
dotnet test TeamsISO.Windows.slnf
|
||||
dotnet test Dragon-ISO.Windows.slnf
|
||||
--configuration Release
|
||||
--no-build
|
||||
--filter "Category!=ndi&requires!=ndi"
|
||||
|
||||
- name: Publish TeamsISO.App (framework-dependent, win-x64)
|
||||
- name: Publish Dragon-ISO.App (framework-dependent, win-x64)
|
||||
run: >
|
||||
dotnet publish src/TeamsISO.App/TeamsISO.App.csproj
|
||||
dotnet publish src/Dragon-ISO.App/Dragon-ISO.App.csproj
|
||||
--configuration Release
|
||||
--runtime win-x64
|
||||
--self-contained false
|
||||
--output publish/TeamsISO
|
||||
--output publish/Dragon-ISO
|
||||
/p:Version=${{ steps.ver.outputs.version }}
|
||||
|
||||
- name: Publish TeamsISO.Console (framework-dependent, win-x64)
|
||||
- name: Publish Dragon-ISO.Console (framework-dependent, win-x64)
|
||||
run: >
|
||||
dotnet publish src/TeamsISO.Console/TeamsISO.Console.csproj
|
||||
dotnet publish src/Dragon-ISO.Console/Dragon-ISO.Console.csproj
|
||||
--configuration Release
|
||||
--runtime win-x64
|
||||
--self-contained false
|
||||
--output publish/TeamsISO-Console
|
||||
--output publish/Dragon-ISO-Console
|
||||
/p:Version=${{ steps.ver.outputs.version }}
|
||||
|
||||
# Code-sign the WPF .exe BEFORE the MSI is built, so the MSI's embedded
|
||||
# binaries are signed too. Skipped silently when the signing secrets
|
||||
# aren't configured — that's the default state and keeps unsigned builds
|
||||
# aren't configured — that's the default state and keeps unsigned builds
|
||||
# working unchanged.
|
||||
#
|
||||
# To enable signing, set both Forgejo Actions secrets:
|
||||
# SIGN_CERT_PFX_BASE64 — base64 of your code-signing PFX file
|
||||
# SIGN_CERT_PFX_BASE64 — base64 of your code-signing PFX file
|
||||
# ( certutil -encode in.pfx out.b64; strip BEGIN/END lines )
|
||||
# SIGN_CERT_PASSWORD — the PFX password
|
||||
# SIGN_CERT_PASSWORD — the PFX password
|
||||
# Optionally:
|
||||
# SIGN_TIMESTAMP_URL — RFC 3161 timestamp server (default: digicert)
|
||||
- name: Sign TeamsISO.exe (optional, skipped if no cert)
|
||||
# SIGN_TIMESTAMP_URL — RFC 3161 timestamp server (default: digicert)
|
||||
- name: Sign Dragon-ISO.exe (optional, skipped if no cert)
|
||||
if: ${{ steps.signcfg.outputs.enabled == 'true' }}
|
||||
env:
|
||||
SIGN_CERT_PFX_BASE64: ${{ secrets.SIGN_CERT_PFX_BASE64 }}
|
||||
|
|
@ -116,13 +116,13 @@ jobs:
|
|||
/fd SHA256 `
|
||||
/td SHA256 `
|
||||
/tr $tsUrl `
|
||||
'publish/TeamsISO/TeamsISO.exe'
|
||||
if ($LASTEXITCODE -ne 0) { throw "signtool failed on TeamsISO.exe (exit $LASTEXITCODE)" }
|
||||
'publish/Dragon-ISO/DragonISO.exe'
|
||||
if ($LASTEXITCODE -ne 0) { throw "signtool failed on Dragon-ISO.exe (exit $LASTEXITCODE)" }
|
||||
Remove-Item $pfxPath -Force
|
||||
|
||||
- name: Build MSI installer
|
||||
run: >
|
||||
dotnet build installer/TeamsISO.Installer.wixproj
|
||||
dotnet build installer/Dragon-ISO.Installer.wixproj
|
||||
--configuration Release
|
||||
/p:Version=${{ steps.ver.outputs.version }}
|
||||
|
||||
|
|
@ -136,7 +136,7 @@ jobs:
|
|||
"name=$($msi.Name)" >> $env:GITHUB_OUTPUT
|
||||
Write-Host "MSI: $($msi.FullName) ($($msi.Length) bytes)"
|
||||
|
||||
# Sign the produced MSI itself. Same gate as exe signing — runs only if
|
||||
# Sign the produced MSI itself. Same gate as exe signing — runs only if
|
||||
# the cert secret is set. Splitting the two stages means the inner exe
|
||||
# is signed before being embedded, AND the wrapping MSI carries its own
|
||||
# signature for SmartScreen.
|
||||
|
|
@ -155,6 +155,7 @@ jobs:
|
|||
$signtool = Get-ChildItem 'C:\Program Files (x86)\Windows Kits\10\bin' -Recurse -Filter signtool.exe `
|
||||
| Where-Object { $_.FullName -match '\\x64\\' } `
|
||||
| Select-Object -First 1
|
||||
if (-not $signtool) { throw 'signtool.exe not found on runner' }
|
||||
& $signtool.FullName sign `
|
||||
/f $pfxPath `
|
||||
/p $env:SIGN_CERT_PASSWORD `
|
||||
|
|
@ -166,7 +167,7 @@ jobs:
|
|||
Remove-Item $pfxPath -Force
|
||||
|
||||
- name: Upload MSI as workflow artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ steps.msi.outputs.name }}
|
||||
path: ${{ steps.msi.outputs.path }}
|
||||
|
|
@ -195,7 +196,7 @@ jobs:
|
|||
Write-Host "No release found for $env:TAG; creating one."
|
||||
$body = @{
|
||||
tag_name = $env:TAG
|
||||
name = "TeamsISO $env:TAG"
|
||||
name = "Dragon-ISO $env:TAG"
|
||||
body = "Automated build from tag $env:TAG."
|
||||
draft = $false
|
||||
prerelease = $env:TAG -match '-(alpha|beta|rc)'
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
<PropertyGroup>
|
||||
<OutputType>Package</OutputType>
|
||||
<OutputName>TeamsISO-Setup-$(Version)</OutputName>
|
||||
<OutputName>Dragon-ISO-Setup-$(Version)</OutputName>
|
||||
|
||||
<!-- 64-bit MSI; suppresses ICE80 on components in Program Files (x64). -->
|
||||
<Platform>x64</Platform>
|
||||
|
|
@ -10,15 +10,15 @@
|
|||
|
||||
<!--
|
||||
Built artifact location. The installer expects a published build of
|
||||
TeamsISO.App rooted here. CI / local script:
|
||||
dotnet publish src/TeamsISO.App/TeamsISO.App.csproj
|
||||
-c Release -r win-x64 (with self contained false)
|
||||
-o $(SolutionDir)publish/TeamsISO
|
||||
Dragon-ISO.App rooted here. CI / local script:
|
||||
dotnet publish src/Dragon-ISO.App/Dragon-ISO.App.csproj
|
||||
-c Release -r win-x64 -self-contained false
|
||||
-o $(SolutionDir)publish/Dragon-ISO
|
||||
-->
|
||||
<PublishDir>$(MSBuildThisFileDirectory)..\publish\TeamsISO\</PublishDir>
|
||||
<PublishDir>$(MSBuildThisFileDirectory)..\publish\Dragon-ISO\</PublishDir>
|
||||
|
||||
<!-- Pass MSBuild values into WiX preprocessor. -->
|
||||
<DefineConstants>PublishDir=$(PublishDir);AssetsDir=$(MSBuildThisFileDirectory)..\src\TeamsISO.App\Assets\</DefineConstants>
|
||||
<DefineConstants>PublishDir=$(PublishDir);AssetsDir=$(MSBuildThisFileDirectory)..\src\Dragon-ISO.App\Assets\</DefineConstants>
|
||||
|
||||
<!-- Code-signing hook (set externally for release builds; left empty for dev). -->
|
||||
<SignOutput Condition=" '$(SignOutput)' == '' ">false</SignOutput>
|
||||
|
|
@ -32,4 +32,4 @@
|
|||
<PackageReference Include="WixToolset.UI.wixext" Version="5.0.2" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
</Project>
|
||||
|
|
@ -1,22 +1,27 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
TeamsISO — MSI installer (WiX v5)
|
||||
Dragon-ISO — MSI installer (WiX v5)
|
||||
|
||||
Produces: TeamsISO-Setup-<Version>.msi (per-machine install).
|
||||
Produces: Dragon-ISO-Setup-<Version>.msi (per-machine install).
|
||||
|
||||
Build:
|
||||
dotnet publish src/TeamsISO.App/TeamsISO.App.csproj -c Release -r win-x64 (no self contained) -o publish/TeamsISO
|
||||
dotnet build installer/TeamsISO.Installer.wixproj -c Release
|
||||
dotnet publish src/Dragon-ISO.App/Dragon-ISO.App.csproj -c Release -r win-x64 -p:SelfContained=false -o publish/Dragon-ISO
|
||||
dotnet build installer/Dragon-ISO.Installer.wixproj -c Release
|
||||
|
||||
Runtime expectations:
|
||||
- .NET 8 Desktop runtime present on target (framework-dependent build)
|
||||
- NDI 6 Runtime present — checked in CheckNdiRuntime; absence WARNS
|
||||
- NDI 6 Runtime present — checked in NdiRuntimeDirV6Search; absence WARNS
|
||||
but does not block install (operators can install NDI after the app)
|
||||
|
||||
Exe filename note:
|
||||
Dragon-ISO.App.csproj sets AssemblyName=DragonISO (no hyphen — CLR
|
||||
assembly names cannot contain hyphens). The published executable is
|
||||
therefore DragonISO.exe. Shortcut targets reference DragonISO.exe.
|
||||
-->
|
||||
<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs"
|
||||
xmlns:ui="http://wixtoolset.org/schemas/v4/wxs/ui">
|
||||
|
||||
<Package Name="TeamsISO"
|
||||
<Package Name="Dragon-ISO"
|
||||
Manufacturer="Wild Dragon LLC"
|
||||
Version="1.0.0.0"
|
||||
UpgradeCode="9F4A8B2C-1D3E-4A5B-9C6D-8E7F0A1B2C3D"
|
||||
|
|
@ -32,9 +37,9 @@
|
|||
installer dialogs.
|
||||
-->
|
||||
<SummaryInformation
|
||||
Description="TeamsISO — per-participant NDI ISO controller for Microsoft Teams. Splits each Teams participant into a normalized NDI source for vMix / OBS / Ross / hardware switchers."
|
||||
Description="Dragon-ISO — per-participant NDI ISO controller for Microsoft Teams. Splits each Teams participant into a normalized NDI source for vMix / OBS / Ross / hardware switchers."
|
||||
Manufacturer="Wild Dragon LLC"
|
||||
Keywords="NDI, Microsoft Teams, ISO recording, broadcast, live production, vMix, OBS, switcher, Wild Dragon" />
|
||||
Keywords="Dragon-ISO, NDI, Microsoft Teams, ISO recording, broadcast, live production, vMix, OBS, switcher, Wild Dragon" />
|
||||
|
||||
<!--
|
||||
MajorUpgrade: a newer install replaces an older one in-place. We
|
||||
|
|
@ -42,13 +47,13 @@
|
|||
forward-migration path; downgrading would leave operators with a
|
||||
config the older binary doesn't understand.
|
||||
-->
|
||||
<MajorUpgrade DowngradeErrorMessage="A newer version of TeamsISO is already installed. Uninstall it before installing this older version."
|
||||
<MajorUpgrade DowngradeErrorMessage="A newer version of Dragon-ISO is already installed. Uninstall it before installing this older version."
|
||||
Schedule="afterInstallInitialize" />
|
||||
|
||||
<!--
|
||||
Single MSI feature; users see only the install/uninstall screens.
|
||||
-->
|
||||
<Feature Id="Main" Title="TeamsISO" Level="1">
|
||||
<Feature Id="Main" Title="Dragon-ISO" Level="1">
|
||||
<ComponentGroupRef Id="ApplicationFiles" />
|
||||
<ComponentGroupRef Id="Shortcuts" />
|
||||
<ComponentGroupRef Id="DesktopShortcut" />
|
||||
|
|
@ -56,37 +61,51 @@
|
|||
</Feature>
|
||||
|
||||
<!--
|
||||
Friendly install UI. WixToolset.UI.wixext provides several flavors;
|
||||
WixUI_InstallDir lets the user pick the directory.
|
||||
Minimal install UI: Welcome/License -> Progress -> Finish.
|
||||
No directory picker; installs to Program Files\Wild Dragon\Dragon-ISO.
|
||||
-->
|
||||
<ui:WixUI Id="WixUI_InstallDir" />
|
||||
<Property Id="WIXUI_INSTALLDIR" Value="INSTALLFOLDER" />
|
||||
<ui:WixUI Id="WixUI_Minimal" />
|
||||
|
||||
<!--
|
||||
Add/Remove Programs metadata. ARPHELPLINK is the "Help" link; ARPURLINFOABOUT
|
||||
is the manufacturer/about link; ARPCONTACT is the support contact shown
|
||||
when the user clicks "Support information" from the ARP entry. ARPCOMMENTS
|
||||
is the long description displayed in some Settings → Apps surfaces.
|
||||
is the long description displayed in some Settings -> Apps surfaces.
|
||||
-->
|
||||
<Property Id="ARPHELPLINK" Value="https://forge.wilddragon.net/zgaetano/teamsiso" />
|
||||
<Property Id="ARPHELPLINK" Value="https://forge.wilddragon.net/zgaetano/dragon-iso" />
|
||||
<Property Id="ARPURLINFOABOUT" Value="https://wilddragon.net" />
|
||||
<Property Id="ARPCONTACT" Value="Wild Dragon LLC — support@wilddragon.net" />
|
||||
<Property Id="ARPCOMMENTS" Value="TeamsISO turns Microsoft Teams' raw NDI broadcast into clean, normalized, per-participant NDI sources for ingestion by a live-production switcher (vMix, OBS, Ross, hardware capture). Each participant gets an individually-addressable source with configurable framerate, resolution, aspect mode, and audio routing." />
|
||||
<!-- ARPNOMODIFY is set by WixUI_InstallDir; don't redeclare. -->
|
||||
<Property Id="ARPCOMMENTS" Value="Dragon-ISO turns Microsoft Teams' raw NDI broadcast into clean, normalized, per-participant NDI sources for ingestion by a live-production switcher (vMix, OBS, Ross, hardware capture). Each participant gets an individually-addressable source with configurable framerate, resolution, aspect mode, and audio routing." />
|
||||
<!-- ARPNOMODIFY is set by WixUI_Minimal. Do not redeclare. -->
|
||||
<Property Id="ARPNOREPAIR" Value="1" />
|
||||
|
||||
<!--
|
||||
ARP icon — references the same .ico the WPF host uses. WiX requires the
|
||||
ARP icon: references the same .ico the WPF host uses. WiX requires the
|
||||
icon resource to live next to the wxs OR be reachable at build time;
|
||||
we point at the published copy under src/TeamsISO.App/Assets so the icon
|
||||
we point at the source copy under src/Dragon-ISO.App/Assets so the icon
|
||||
embedded in the MSI matches the icon in the running exe.
|
||||
-->
|
||||
<Icon Id="TeamsISOIcon" SourceFile="$(var.AssetsDir)teamsiso.ico" />
|
||||
<Property Id="ARPPRODUCTICON" Value="TeamsISOIcon" />
|
||||
<Icon Id="DragonISOIcon" SourceFile="$(var.AssetsDir)Dragon-ISO.ico" />
|
||||
<Property Id="ARPPRODUCTICON" Value="DragonISOIcon" />
|
||||
|
||||
<!--
|
||||
.NET 8 Desktop Runtime detection. The .NET apphost will surface a
|
||||
"framework not found" dialog naturally if the runtime is absent;
|
||||
this property is available for future conditional logic.
|
||||
VBScript-based install-time dialogs are deprecated in WiX v5 / Windows;
|
||||
rewriting in C++ is overkill for a soft warning on a soft dependency.
|
||||
-->
|
||||
<Property Id="DOTNET8DESKTOPRUNTIME" Value="0">
|
||||
<RegistrySearch Id="DotNet8DesktopRuntimeSearch"
|
||||
Root="HKLM"
|
||||
Key="SOFTWARE\dotnet\Setup\InstalledVersions\x64\sharedfx\Microsoft.WindowsDesktop.App\8.0.0"
|
||||
Name="Version"
|
||||
Type="raw" />
|
||||
</Property>
|
||||
|
||||
<!--
|
||||
NDI Runtime detection. We check for NDI_RUNTIME_DIR_V6 in the system
|
||||
environment block. Missing → warn during install, don't block. The
|
||||
environment block. Missing -> warn during install, don't block. The
|
||||
engine surfaces a clear MessageBox with an install-NDI link at first
|
||||
launch if the runtime really isn't there.
|
||||
-->
|
||||
|
|
@ -107,11 +126,11 @@
|
|||
-->
|
||||
|
||||
<!--
|
||||
Install layout under Program Files\Wild Dragon\TeamsISO.
|
||||
Install layout under Program Files\Wild Dragon\Dragon-ISO.
|
||||
-->
|
||||
<StandardDirectory Id="ProgramFiles64Folder">
|
||||
<Directory Id="ManufacturerFolder" Name="Wild Dragon">
|
||||
<Directory Id="INSTALLFOLDER" Name="TeamsISO" />
|
||||
<Directory Id="INSTALLFOLDER" Name="Dragon-ISO" />
|
||||
</Directory>
|
||||
</StandardDirectory>
|
||||
|
||||
|
|
@ -129,30 +148,33 @@
|
|||
</ComponentGroup>
|
||||
|
||||
<!--
|
||||
Start Menu and Desktop shortcuts — direct .exe targets.
|
||||
Start Menu and Desktop shortcuts: direct .exe targets.
|
||||
|
||||
Don't wrap the Target in runas.exe /trustlevel:0x20000 (or anything
|
||||
else that demotes the spawned process). The SAFER-restricted token
|
||||
breaks .NET 8 WPF apphost startup: the process appears alive with
|
||||
a window, but no managed code past BAML parse executes. Verified
|
||||
empirically 2026-05-16 — letting TeamsISO inherit the launching
|
||||
empirically 2026-05-16; letting Dragon-ISO inherit the launching
|
||||
token (medium or high integrity, doesn't matter) is the correct
|
||||
behavior. NDI discovery works fine at either integrity level.
|
||||
|
||||
Exe filename: AssemblyName=DragonISO (no hyphen), so target is
|
||||
DragonISO.exe not Dragon-ISO.exe.
|
||||
-->
|
||||
<ComponentGroup Id="Shortcuts" Directory="WildDragonStartMenuFolder">
|
||||
<Component Id="StartMenuShortcut" Guid="*">
|
||||
<Shortcut Id="StartMenuTeamsISO"
|
||||
Name="TeamsISO"
|
||||
<Shortcut Id="StartMenuDragonISO"
|
||||
Name="Dragon-ISO"
|
||||
Description="Per-Participant NDI ISO Controller for Microsoft Teams"
|
||||
Target="[INSTALLFOLDER]TeamsISO.exe"
|
||||
Target="[INSTALLFOLDER]DragonISO.exe"
|
||||
WorkingDirectory="INSTALLFOLDER"
|
||||
Icon="TeamsISOIcon" />
|
||||
Icon="DragonISOIcon" />
|
||||
<!-- Required by ICE64: Start Menu folder must be cleaned on uninstall. -->
|
||||
<RemoveFolder Id="RemoveWildDragonStartMenuFolder"
|
||||
Directory="WildDragonStartMenuFolder"
|
||||
On="uninstall" />
|
||||
<RegistryValue Root="HKCU"
|
||||
Key="Software\Wild Dragon\TeamsISO"
|
||||
Key="Software\Wild Dragon\Dragon-ISO"
|
||||
Name="StartMenuShortcut"
|
||||
Type="integer"
|
||||
Value="1"
|
||||
|
|
@ -163,14 +185,14 @@
|
|||
<StandardDirectory Id="DesktopFolder" />
|
||||
<ComponentGroup Id="DesktopShortcut" Directory="DesktopFolder">
|
||||
<Component Id="DesktopShortcutComponent" Guid="*">
|
||||
<Shortcut Id="DesktopTeamsISO"
|
||||
Name="TeamsISO"
|
||||
<Shortcut Id="DesktopDragonISO"
|
||||
Name="Dragon-ISO"
|
||||
Description="Per-Participant NDI ISO Controller for Microsoft Teams"
|
||||
Target="[INSTALLFOLDER]TeamsISO.exe"
|
||||
Target="[INSTALLFOLDER]DragonISO.exe"
|
||||
WorkingDirectory="INSTALLFOLDER"
|
||||
Icon="TeamsISOIcon" />
|
||||
Icon="DragonISOIcon" />
|
||||
<RegistryValue Root="HKCU"
|
||||
Key="Software\Wild Dragon\TeamsISO"
|
||||
Key="Software\Wild Dragon\Dragon-ISO"
|
||||
Name="DesktopShortcut"
|
||||
Type="integer"
|
||||
Value="1"
|
||||
|
|
@ -179,14 +201,14 @@
|
|||
</ComponentGroup>
|
||||
|
||||
<!--
|
||||
ARP icon registry entry. Optional — the MSI auto-fills most ARP
|
||||
fields from the Package element. We only need to point at the
|
||||
executable for the ARP icon.
|
||||
ARP icon registry entry. Optional: the MSI auto-fills most ARP
|
||||
fields from the Package element. We only need to store the install
|
||||
path for diagnostic / uninstall tooling.
|
||||
-->
|
||||
<ComponentGroup Id="ArpEntry" Directory="INSTALLFOLDER">
|
||||
<Component Id="ArpIconRegistry" Guid="*">
|
||||
<RegistryValue Root="HKLM"
|
||||
Key="Software\Wild Dragon\TeamsISO"
|
||||
Key="Software\Wild Dragon\Dragon-ISO"
|
||||
Name="InstallPath"
|
||||
Type="string"
|
||||
Value="[INSTALLFOLDER]"
|
||||
|
|
@ -195,4 +217,4 @@
|
|||
</ComponentGroup>
|
||||
|
||||
</Package>
|
||||
</Wix>
|
||||
</Wix>
|
||||
Loading…
Reference in a new issue