66on :
77 push :
88 branches : [main]
9- tags : ['v*' ]
9+ tags : ["v*" ]
1010 pull_request :
1111 branches : [main]
1212
7575 run : cargo test -p dynwinrt
7676 - name : Test dynwinrt-codegen
7777 run : cargo test -p dynwinrt-codegen
78+ - name : Test raw union MSVC C oracle (x64)
79+ run : cargo test -p jswinrt_rs --features test-hooks com_raw::tests::msvc_c_union_oracle_executes_through_libffi -- --exact
80+ - name : Test raw union MSVC C oracle (live i686)
81+ run : cargo test -p jswinrt_rs --features test-hooks --target i686-pc-windows-msvc com_raw::tests::msvc_c_union_oracle_executes_through_libffi -- --exact
7882 - name : Enforce Classic COM coverage baseline
7983 shell : pwsh
8084 run : |
@@ -93,6 +97,116 @@ jobs:
9397 throw "Classic COM coverage fell below 70%: $($result.coverage_percent)"
9498 }
9599 Write-Host "Classic COM coverage: $($result.complete_interfaces)/$($result.eligible_interfaces) ($($result.coverage_percent)%)"
100+ - name : Enforce Classic COM raw capability baseline
101+ shell : pwsh
102+ run : |
103+ $output = Join-Path $env:RUNNER_TEMP 'classic-com-capability'
104+ cargo run -p dynwinrt-codegen --quiet -- com-capability-census `
105+ --winmd $env:DYNWINRT_WIN32_WINMD `
106+ --output-dir $output | Out-Null
107+ if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
108+ $result = Get-Content (Join-Path $output 'classic-com-capability-summary.json') -Raw |
109+ ConvertFrom-Json
110+ if ($result.eligible_interfaces -ne 7929 -or $result.safe_complete -ne 5567) {
111+ throw "Classic COM safe totals changed in capability census"
112+ }
113+ $support = Import-Csv (Join-Path $output 'classic-com-interface-support.csv')
114+ if (
115+ @($support).Count -ne 7929 -or
116+ @($support | Where-Object { $_.safe_complete -eq 'true' }).Count -ne 5567 -or
117+ @($support | Where-Object { $_.safe_complete -eq 'false' }).Count -ne 2362
118+ ) {
119+ throw "Classic COM compact interface support index changed"
120+ }
121+ $expected = @{
122+ x64 = @(418, 1554, 390)
123+ i686 = @(417, 1531, 414)
124+ arm64 = @(418, 1554, 390)
125+ }
126+ foreach ($target in @('x64', 'i686', 'arm64')) {
127+ $counts = $result.targets.$target
128+ if (
129+ $counts.safe_incomplete_raw_metadata_complete -ne $expected[$target][0] -or
130+ $counts.safe_incomplete_raw_manual_contract -ne $expected[$target][1] -or
131+ $counts.safe_incomplete_raw_runtime_blocked -ne $expected[$target][2]
132+ ) {
133+ throw "Classic COM raw capability totals changed for $target"
134+ }
135+ }
136+ if (
137+ $result.safeEvidence.safeComplete -ne 5567 -or
138+ $result.safeEvidence.standardDerived -ne 5317 -or
139+ $result.safeEvidence.exactRegistryDependent -ne 250 -or
140+ $result.safeEvidence.metadataFactOccurrences -ne 5867 -or
141+ $result.safeEvidence.comStandardFactOccurrences -ne 25526 -or
142+ $result.safeEvidence.registeredExactEntries -ne 334 -or
143+ $result.safeEvidence.metadataMatchedExactEntries -ne 334 -or
144+ $result.safeEvidence.safeConsumedExactEntries -ne 291 -or
145+ $result.safeEvidence.exactEntryInterfaceDependencies -ne 431 -or
146+ $result.safeEvidence.exactFamilyInterfaceDependencies -ne 268
147+ ) {
148+ throw "Classic COM safe evidence dependency census changed"
149+ }
150+ $statuses = @($result.safeEvidence.exactEntryStatus.psobject.Properties.Value)
151+ if (
152+ @($statuses | Where-Object { -not $_.registered -or -not $_.metadataMatched }).Count -ne 0 -or
153+ @($statuses | Where-Object { $_.familyId -eq 'windows.borrowed-hwnd-output.v1' }).Count -ne 22 -or
154+ @($statuses | Where-Object { $_.familyId -eq 'com.enumerator-next-exception.v1' }).Count -ne 73
155+ ) {
156+ throw "Classic COM exact registry entry validation changed"
157+ }
158+ $interfaces = Import-Csv (Join-Path $output 'classic-com-interface-capabilities.csv')
159+ $fsrm = $interfaces | Where-Object { $_.name -eq 'IFsrmFileManagementJob' }
160+ if (@($fsrm.exact_entry_ids | ConvertFrom-Json).Count -ne 7) {
161+ throw "IFsrmFileManagementJob exact SAFEARRAY entry granularity changed"
162+ }
163+ $second = Join-Path $env:RUNNER_TEMP 'classic-com-capability-second'
164+ cargo run -p dynwinrt-codegen --quiet -- com-capability-census `
165+ --winmd $env:DYNWINRT_WIN32_WINMD `
166+ --output-dir $second | Out-Null
167+ if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
168+ $firstFiles = Get-ChildItem $output -File | Sort-Object Name
169+ $secondFiles = Get-ChildItem $second -File | Sort-Object Name
170+ if (($firstFiles.Name -join '|') -ne ($secondFiles.Name -join '|')) {
171+ throw 'Classic COM capability artifact sets differ'
172+ }
173+ foreach ($file in $firstFiles) {
174+ $other = Join-Path $second $file.Name
175+ if (
176+ (Get-FileHash $file.FullName -Algorithm SHA256).Hash -ne
177+ (Get-FileHash $other -Algorithm SHA256).Hash
178+ ) {
179+ throw "Classic COM capability artifact drift: $($file.Name)"
180+ }
181+ }
182+ $retained = Join-Path $env:GITHUB_WORKSPACE 'docs\status\generated'
183+ $retainedNames = @(
184+ 'classic-com-capability-summary.json',
185+ 'classic-com-interface-support.csv'
186+ )
187+ $retainedFiles = Get-ChildItem $retained -File |
188+ Where-Object { $retainedNames -contains $_.Name } |
189+ Sort-Object Name
190+ if (($retainedNames -join '|') -ne ($retainedFiles.Name -join '|')) {
191+ throw 'Retained Classic COM capability artifact set is stale'
192+ }
193+ foreach ($name in $retainedNames) {
194+ $generated = Join-Path $output $name
195+ $committed = Join-Path $retained $name
196+ if (
197+ (Get-FileHash $generated -Algorithm SHA256).Hash -ne
198+ (Get-FileHash $committed -Algorithm SHA256).Hash
199+ ) {
200+ throw "Retained Classic COM capability artifact drift: $name"
201+ }
202+ }
203+ - name : Upload complete Classic COM capability report
204+ uses : actions/upload-artifact@v4
205+ with :
206+ name : classic-com-capability-report
207+ path : ${{ runner.temp }}\classic-com-capability
208+ if-no-files-found : error
209+ retention-days : 14
96210 - name : Test Classic COM failure cleanup contracts
97211 run : |
98212 cargo test -p dynwinrt failing_hresult_releases_written_interface_output
@@ -117,7 +231,7 @@ jobs:
117231 node-version : 24
118232 - uses : actions/setup-python@v5
119233 with :
120- python-version : ' 3.12'
234+ python-version : " 3.12"
121235 - uses : NuGet/setup-nuget@v2
122236 - name : Install Win32 metadata
123237 shell : pwsh
@@ -167,6 +281,9 @@ jobs:
167281 - name : Test JS TSFN lifecycle and queue handling
168282 working-directory : bindings/js
169283 run : npm run test:tsfn
284+ - name : Test actual generated unsafe COM companion
285+ working-directory : bindings/js
286+ run : npm run test:generated-unsafe
170287
171288 # dynwinrt-codegen (x64 + arm64)
172289 dynwinrt-codegen :
@@ -207,6 +324,8 @@ jobs:
207324 - name : Install dependencies
208325 working-directory : bindings/js
209326 run : npm install
327+ - name : Compile raw union MSVC C oracle for ARM64
328+ run : cargo test -p jswinrt_rs --features test-hooks --target aarch64-pc-windows-msvc --no-run
210329 - name : Build x64
211330 working-directory : bindings/js
212331 run : |
0 commit comments