Skip to content

Commit d5cc0bc

Browse files
Merge build fix
1 parent 856d394 commit d5cc0bc

6 files changed

Lines changed: 13 additions & 2 deletions

File tree

‎AGENTS.md‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,9 @@ CI RIDs: `win-x64`, `win-x86`, `win-arm64`, `linux-x64`, `linux-arm64`, `osx-x64
310310
- `GlobalConstants.ReadMetadata` must never adopt an implausible tag as this build's version. The GitInfo generator embeds whatever `git describe` printed, and a tagless checkout makes it embed the tool's stderr (`fatal: No names found, cannot describe anything.`), which then leaks into the crash report, `producer_version`, the Sentry release, and the update gate — `producer_version` would no longer be version-shaped and the import gate could reject this build's own archives. `LooksLikeVersionTag` therefore requires a numeric `MAJOR.MINOR` and otherwise falls back to `v3.0.0-dev`, whose major must stay in step with `SecRandom.PluginSdk/PluginApiVersions.Current`; the same fallback replaces the old `v0.0.0.0` placeholder, because major `0` disagrees with every archive this build writes. The commit hash is still kept.
311311
- `OverlayAssetLoader` is the desktop's only asset path: the desktop head sets `SecRandomBundleAssetsInAssembly=false` (`SecRandom.Desktop.csproj`), so `Assets` ships as loose files and is deliberately not embedded — a lookup that misses has no fallback and surfaces as `Could not create glyphtypeface` at the first measured glyph. Its URI matching must therefore stay **case-insensitive**: the authority casing that reaches this loader is not guaranteed to preserve the assembly name's `SecRandom`, and a case-sensitive comparison turns that into a total failure. Observed: an installed layout delivered a lowercase `avares://secrandom/...` while a portable build of the same commit worked, because the portable path happened to keep the original casing — the same defect, exposed on one path only. When a startup failure looks like a font/image error, check this loader first, and keep the `Assets`-root diagnostic in `Program.BindAssetLoader`.
312312
- In PowerShell, a hash-table value holding a **single-element array of arrays** collapses: `@{ pairs = @( @('old','new') ) }` makes `$job.pairs` the inner pair itself, so `foreach ($pair in $job.pairs)` iterates the two **strings** and `$pair[0]`/`$pair[1]` become their first characters — an "old→new" replacement silently degrades into "O→n" character substitution and rewrites the whole file. When scripting bulk text replacements, keep at least two pairs per group, use the comma operator to force an array, or prefer an exact-match editor. Always diff-stat the result: a multi-line source file showing every line changed is a corrupted rewrite, not an edit.
313+
- A fork parameter added to a type's constructor silently breaks upstream's **new** test files. The merge produces no conflict marker for a file only one side touched, and no release build job compiles the test projects, so the first CI run can be green on the app build while six call sites are already broken. After changing any constructor signature, grep every construction site in the repository and verify the argument count by hand — the conflict list is not evidence of completeness.
314+
- A `public` member that references a type upstream made `internal` fails with CS0051 (`Inconsistent accessibility`), and the error appears only in the assembly that owns the public type. The fix that stays inside fork-owned code is to narrow the fork type (`internal sealed class`) so it matches its siblings, rather than widening upstream's type.
315+
- **Written summaries meant for the maintainer belong in Chinese; internal reasoning stays English.** This covers session summaries, handover notes, and review lists: the maintainer uses the language to tell a report apart from the agent's own thinking. It does **not** relax the script rule below — a `.ps1`/shell body stays ASCII, so carry Chinese as data read from a UTF-8 file rather than as a literal in the script.
313316
- Every `Get Latest Tag` / `Get Version` step in `build_publish.yml` must tolerate a repository with no tags: a fork starts tagless, `git describe --tags --abbrev=0` then exits non-zero, and the runner's native-command error preference turns that into a terminating error that fails the whole build. Resolve the tag behind `try`/`catch` (or `|| true` in bash), fall back to `git tag --sort=-v:refname`, and only then to a dev version whose major is parsed from `PluginApiVersions.Current` (`v<major>.0.0-dev` / `<major>.0.0-dev`) with a `::warning::`. The fallback major must come from that file rather than a hardcoded `0.0.0-dev`: `build_pluginsdk` enforces that the packed major equals the Plugin SDK API major, and the app/API majors must stay in step. Tag-push and manual-dispatch releases still take precedence over the fallback.
314317
- The desktop `Publish Desktop` and UIAccess publish steps must run `dotnet publish` with `-p:BuildInParallel=false -p:UseSharedCompilation=false` and must check `$LASTEXITCODE` after every publish. The two full/light publishes share the same `obj/` tree, so parallel builds and the shared `VBCSCompiler` race intermittently with `CS2012` file-lock failures on Windows; a masked (unchecked) failure leaves `publish/full` incomplete and breaks downstream portable/installer packaging with confusing "file does not exist" errors. Keep the `Verify bundled audio runtime` step enabled so an incomplete self-contained publish is caught at its source instead of silently producing broken artifacts.
315318
- The mobile `Build Android APK` and `Publish unsigned iOS arm64 IPA` steps must also pass `-p:BuildInParallel=false -p:UseSharedCompilation=false` (and the iOS step runs with `set -euo pipefail`). The shared `SecRandom.Core`/app graph is otherwise scheduled twice in parallel within a single build, racing on `obj/Release/net10.0` resource outputs with `MSB3554`/`CS1566`/`MSB4018` "being used by another process" failures on any platform. The iOS publish is the release critical path: the Mono/LLVM AOT step is ~95% of that job, and the SDK parallelizes it only to `Environment.ProcessorCount / 2`, which is integer 1 on the 3 vCPU macOS runner; the step therefore passes `-p:AotCompileMaxDegreeOfParallelism=2` to keep two cores busy inside the runner's 7 GB. `MtouchUseLlvm` stays at the SDK's Release default (`true`) — clearing it would trade runtime code quality for build time.

‎DownStream_Change.md‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -685,7 +685,7 @@
685685
| 类别 | 冲突数 | 处置 |
686686
|------|--------|------|
687687
| `.resx` | 23 | 取两侧并集,逐文件验证「键集 = 双方并集、无重复键、XML 合法、无标记」 |
688-
| 测试调用点 | 3 | `SectlAuthService` 构造签名取两侧并集 |
688+
| 测试调用点 | 3 | `SectlAuthService` 构造签名取两侧并集。**实际有 9 处调用,其中 6 处在上游新增的测试文件里仍是 5 参调用——没有冲突标记,桌面发布任务又不编译测试工程,所以首轮 CI 也看不到**(见下) |
689689
| `SectlAuthService.cs` | 2 | 构造函数**同时**保留 `configHandler`(我方出境闸门)与 `redirectBrokerFactory`(上游移动端回调);`SignInAsync` 保留我方闸门,丢弃上游删掉的 `port`/`redirectUri` 两行 |
690690
| `SecuritySettingsPage.axaml.cs` | 1 | using 取并集 |
691691
| `THIRD-PARTY-NOTICES.md` | 1 | 上游版详尽许可分析 + 保留我方 `## SecRandom` 上游署名段 |
@@ -697,6 +697,8 @@
697697

698698
**必须记住的三个坑(本次合并亲历)**:
699699
- **上游把 `SecuritySettingsConfig` 移出 `MainConfigModel`**(移入加密的 `data/config/security/settings.json`,经 `SecuritySettingsStore`)。这**不会产生冲突标记**,却会让本分支 §17 的代码编译失败。已改为:`ConfigPolicyDigest.Compute(model, securitySettings, rosterDigest)` 显式接收安全设置;`ConfigPolicySignatureService` 注入 `SecuritySettingsStore`。**每次同步上游都要优先复查这一点**。
700+
- **给某个类型的构造函数加参数时,上游新增的测试文件会静默编译失败**。本分支把 `MainConfigHandler configHandler` 插进 `SectlAuthService` 的主构造函数(第 5 位、`IAuthRedirectBrokerFactory` 之前),而上游 v3.1.5 新增的 `ControlNodeEnrollmentChannelTests`、`NodeEnrollmentTests`、`MobileRemoteDrawTests` 仍按 5 参调用——**没有冲突标记**,且桌面发布任务不编译测试工程,连首轮 CI 也照不出来。**结论:改完任何构造签名后,必须全仓检索该类型的全部构造点逐个核对参数个数,不能只信冲突列表。**
701+
- 同一处还触发了 **CS0051**:`ConfigPolicySignatureService`(我方 §17 的 `public` 服务)持有上游的 `internal` 类型 `SecuritySettingsStore`,`public` 类的构造函数不能暴露更不可见的参数类型。已把它改为 `internal sealed class`,与其三个同类(`SecurityService`、`SettingsIntegrityService`、`SettingsIntegrityRecoveryService`)保持一致——它只在应用程序集内被 `IAppHost` 解析,改 internal 不涉及任何上游分歧。
700702
- **取 git 里的文件内容绝不能走 PowerShell 管道**:`& git show ":2:路径"` 会让输出经控制台代码页处理,CJK 被替换成 `?`,写回即污染文件。必须用 `cmd /c 'git show ... > 文件'` 或 .NET 文件 API。失败特征是「纯 ASCII 文件全部通过、CJK 文件成片失败」。
701703
- **CJK 不得写进 `.ps1` 字面量**(本次在文档合并脚本里又犯了一次)。中文只应作为从文件读出的数据出现。
702704

‎SecRandom.Core.Tests/ControlNodeEnrollmentChannelTests.cs‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -487,6 +487,7 @@ private static SectlAuthService CreateAuthService()
487487
new StubHttpClientFactory(new HttpClient()),
488488
new DeviceUuidStore(configHandler, NullLogger<DeviceUuidStore>.Instance),
489489
NullLogger<SectlAuthService>.Instance,
490+
configHandler,
490491
new LoopbackAuthRedirectBrokerFactory());
491492
}
492493

‎SecRandom.Core.Tests/MobileRemoteDrawTests.cs‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -938,6 +938,7 @@ public async Task 加载态_被更新的请求取代时旧请求不清新请求
938938
new StubHttpClientFactory(new HttpClient()),
939939
new DeviceUuidStore(configHandler, NullLogger<DeviceUuidStore>.Instance),
940940
NullLogger<SectlAuthService>.Instance,
941+
configHandler,
941942
new LoopbackAuthRedirectBrokerFactory());
942943
await auth.InitializeAsync();
943944

@@ -966,6 +967,7 @@ public async Task 加载态_被更新的请求取代时旧请求不清新请求
966967
new StubHttpClientFactory(new HttpClient()),
967968
new DeviceUuidStore(configHandler, NullLogger<DeviceUuidStore>.Instance),
968969
NullLogger<SectlAuthService>.Instance,
970+
configHandler,
969971
new LoopbackAuthRedirectBrokerFactory());
970972

971973
var store = new FakeEnrollmentStore();
@@ -1019,6 +1021,7 @@ public async Task 加载态_被更新的请求取代时旧请求不清新请求
10191021
new StubHttpClientFactory(new HttpClient()),
10201022
new DeviceUuidStore(configHandler, NullLogger<DeviceUuidStore>.Instance),
10211023
NullLogger<SectlAuthService>.Instance,
1024+
configHandler,
10221025
new LoopbackAuthRedirectBrokerFactory());
10231026

10241027
var endpoint = new FakeEndpointStore("https://control.example", customEndpoint);
@@ -1455,6 +1458,7 @@ public void 接入_自建基址下即使已接入也给入口()
14551458
new StubHttpClientFactory(new HttpClient()),
14561459
deviceUuidStore,
14571460
NullLogger<SectlAuthService>.Instance,
1461+
configHandler,
14581462
new LoopbackAuthRedirectBrokerFactory());
14591463

14601464
var client = new RecordingControlPlaneClient();

‎SecRandom.Core.Tests/NodeEnrollmentTests.cs‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -408,6 +408,7 @@ private static SectlAuthService CreateAuthService()
408408
new FakeHttpClientFactory(new RecordingHandler(_ => Json(HttpStatusCode.OK, "{}"))),
409409
new DeviceUuidStore(configHandler, NullLogger<DeviceUuidStore>.Instance),
410410
NullLogger<SectlAuthService>.Instance,
411+
configHandler,
411412
new LoopbackAuthRedirectBrokerFactory());
412413
}
413414

‎SecRandom/Services/Security/ConfigPolicySignatureService.cs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ public sealed record ConfigPolicyVerification(
4646
/// never reaches this class — signing takes it as a parameter, which is what lets the draw machine
4747
/// verify a policy it could not have authored.
4848
/// </summary>
49-
public sealed class ConfigPolicySignatureService(
49+
internal sealed class ConfigPolicySignatureService(
5050
MainConfigHandler configHandler,
5151
SecuritySettingsStore settingsStore,
5252
ILogger<ConfigPolicySignatureService> logger)

0 commit comments

Comments
 (0)