[CI] Run API-docs stub regeneration on Linux via Mono#147
Conversation
PoliCheck Scan ReportThe following report lists PoliCheck issues in PR files. Before you merge the PR, you must fix all severity-1 and severity-2 issues. The AI Review Details column lists suggestions for either removing or replacing the terms. If you find a false positive result, mention it in a PR comment and include this text: #policheck-false-positive. This feedback helps reduce false positives in future scans. ✅ No issues foundMore information about PoliCheckInformation: PoliCheck | Severity Guidance | Term |
|
Learn Build status updates of commit 5bcb571: ✅ Validation status: passed
For more details, please refer to the build report. |
…minology (#4200) Make doc generation reproducible and Linux-only; unify "API diff" terminology (#4200) Context: #4200 Companion: mono/SkiaSharp-API-docs#147 (must merge after this) Supersedes the drifted releases/ baseline committed in #4184. The repo generates its release documentation through three independent paths, and two of them produced different output depending on the build host or the local NuGet-cache warmth. That non-determinism made the doc-bot's regenerated output "wobble" between runs and was nearly impossible to reproduce locally, so a reviewer could never tell an intended doc change from host noise. This PR makes all three paths deterministic, gives them one shared set of entry points that behave identically locally / in CI / in Docker (Linux), unifies the "changelog" vs "release notes" terminology onto "API diff", and commits a freshly regenerated, byte-reproducible baseline. ~~ Path 1 — API diffs: deterministic and correct ~~ Self-dependency resolution used a filesystem glob over the warm package cache, so the chosen baseline depended on what happened to be unpacked locally. Simply deleting the glob restored determinism but regressed correctness: ApiInfo must resolve SkiaSharp.dll to see that the two infrastructure interfaces SKObject implements (ISKReferenceCounted, ISKSkipObjectRegistration) are internal and collapse to the public System.IDisposable; without it those internal names leaked into the public diff (8 files). The fix stages each self-dependency per-diff at the exact version pinned in that package's own .nuspec (StageSelfDepsFromNuspecAsync) — contemporaneous, host- and cache-independent. Two more leaks are closed at the source: auto-generated resource designers (Android aapt R.*, Uno/WinUI GlobalStaticResources) are excluded via IgnoreMemberRegex, and the TFM selector now ranks candidates (newest plain .NET → netstandard → portable) instead of taking filesystem-enumeration order, so SkiaSharp is diffed from net10.0 and the choice is stable. ~~ Path 3 — mdoc API docs: ref/ over lib/, on Mono/Linux ~~ mdoc was fed the lib/ implementation assemblies, which still carry ABI-compat members marked [Obsolete(error: true)] (e.g. by-value SetMatrix(SKMatrix)). mdoc's comparer ignores the by-ref marker and sorts unstably, and because it runs in merge mode the pair swapped places every run — a 2-cycle with no fixed point. The C# compiler strips error-obsolete members from ref/, so docs.cake now prefers the ref/ surface (lib/ fallback) and invokes mdoc via Mono so the path runs on Linux. ~~ One home, one set of entry points ~~ The API-diff and release-notes engines moved out of the release-notes skill and scripts/infra/shared into scripts/infra/docs alongside docs.cake (git renames). local / CI / Docker now all call the same git-free shell entry points (generate-{api-diffs,release-notes,api-docs}.sh), and a reproducible Linux image (scripts/infra/docs/docker) matches CI exactly. ~~ CI, terminology, and docs ~~ A new workflow_dispatch source_branch input (default: main, every existing trigger byte-identical) lets a manual run validate a feature branch's doc-gen pipeline before merge, mirroring the docs repo's skiasharp_branch input. The "changelog" vocabulary — which collided with "release notes" and GitHub's own "Full Changelog" compare links — is unified onto "API diff" across scripts, Cake identifiers, log paths, the dev spec, and the recompiled workflow lock; GitHub's literal compare links are intentionally left as-is. The developer docs that describe the system are also added/restructured for readability — a new docs-overview.md map and a re-laid-out release-notes-and-api-diffs.md spec (both gain a TOC); the relayout is information-preserving and keeps the spec's numbered headings byte-identical, since ~120 code comments reference them. ~~ Baseline ~~ The regenerated releases/ tree replaces the drifted #4184 output; a full regeneration in the Linux Docker harness reproduced the committed API-diff baseline byte-for-byte. The 4.148.0/ and harfbuzzsharp/14.2.0/ API-diff trees are deliberately left deleted to prove CI's post-merge self-heal recreates exactly them (the PR description records the expected 33-file recreate set). Co-authored-by: Matthew Leibowitz <mattleibow@live.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The `regenerate-stubs` job in auto-api-docs-writer ran on `windows-latest`
solely because mdoc.exe is a .NET Framework tool. That was the last
non-Linux job across the SkiaSharp + SkiaSharp-API-docs pipeline, leaving
this one workflow on a different OS than everything else that builds the
docs — different paths, different toolchain, harder to reproduce locally.
mdoc.exe runs fine under Mono, and SkiaSharp's docs.cake already invokes it
through `mono`, so the job does not actually need Windows. The managed GTK#
reference assemblies mdoc needs are supplied from NuGet by the cake comparer
(passed to mdoc as `--lib` paths), so no system GTK# install is required —
Mono is the only extra dependency.
Changes:
- regenerate-stubs: windows-latest -> ubuntu-latest
- install mono-complete (apt) instead of the GTK# 2 MSI download/install
- drop the now-redundant `dotnet tool restore` and `docs-download-output`
steps; call the shared `scripts/infra/docs/generate-api-docs.sh` entry
point instead of `dotnet cake --target=update-docs`
- use global.json for the .NET SDK and Linux-style nuget cache paths
- recompiled the .lock.yml via `gh aw compile` (frontmatter hash updated)
This makes the entire two-repo doc-generation pipeline Linux-only, matching
the local Docker image and the SkiaSharp-side CI.
Note: depends on the companion SkiaSharp PR that adds
scripts/infra/docs/generate-api-docs.sh; that PR must merge first.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
5bcb571 to
bf871a2
Compare
PoliCheck Scan ReportThe following report lists PoliCheck issues in PR files. Before you merge the PR, you must fix all severity-1 and severity-2 issues. The AI Review Details column lists suggestions for either removing or replacing the terms. If you find a false positive result, mention it in a PR comment and include this text: #policheck-false-positive. This feedback helps reduce false positives in future scans. ✅ No issues foundMore information about PoliCheckInformation: PoliCheck | Severity Guidance | Term |
|
Learn Build status updates of commit bf871a2: ✅ Validation status: passed
For more details, please refer to the build report. |
The writer runs the full agentic pipeline and opens a PR through safe-outputs. When a PR edits this workflow, the writer fires on that PR and then fails because safe-outputs refuses to create a PR that touches protected workflow files — which is exactly what shows up as a red `safe_outputs` check on #147. Drop the pull_request trigger so the writer only runs on schedule, manual dispatch, and push to main. The push-to-main trigger still validates workflow edits after they land. Recompiled the lock file with gh aw compile. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
PoliCheck Scan ReportThe following report lists PoliCheck issues in PR files. Before you merge the PR, you must fix all severity-1 and severity-2 issues. The AI Review Details column lists suggestions for either removing or replacing the terms. If you find a false positive result, mention it in a PR comment and include this text: #policheck-false-positive. This feedback helps reduce false positives in future scans. ✅ No issues foundMore information about PoliCheckInformation: PoliCheck | Severity Guidance | Term |
|
Learn Build status updates of commit f56aa4f: ✅ Validation status: passed
For more details, please refer to the build report. |
What
Two related CI changes to the
auto-api-docs-writerworkflow:regenerate-stubsjob fromwindows-latesttoubuntu-latest, running mdoc.exe under Mono.pull_requesttrigger so the writer no longer runs the full agentic pipeline on PRs.The Linux flip was the last non-Linux job across the SkiaSharp + SkiaSharp-API-docs doc pipeline. With this change the entire two-repo pipeline runs on Linux, matching the local Docker image and the SkiaSharp-side CI.
Why Windows was no longer needed
The job only used Windows because mdoc.exe is a .NET Framework tool. But:
docs.cakealready invokes it viamono.--libpaths), so no system GTK# install is required. The Windows GTK# 2 MSI download/install was redundant.So Mono is the only extra dependency.
Proven locally: mdoc-under-mono was run end-to-end on Linux (Docker, dotnet10 + mono-complete) against this repo's stub tree. It correctly pruned the orphaned net6-only type files (
ActionHelper,FloatFloatActionHelper) and added the newer[Nullable]attributes, and two consecutive runs produced byte-identical output (hashec15190a) — so the job is both correct and idempotent on Linux.Why drop the
pull_requesttriggerThe writer is a full agentic workflow: it regenerates stubs, fills placeholders with AI, and opens a PR via gh-aw safe-outputs. When a PR edits this workflow, the writer fires on that PR and then fails because safe-outputs refuses to create a PR that touches protected workflow files (
protect_top_level_dot_folders: true). That surfaced as a redsafe_outputscheck on this very PR.Removing the
pull_requesttrigger stops the writer from running on PRs entirely. Thepush: branches:[main]trigger still validates workflow edits after they land, andworkflow_dispatch+scheduleare unaffected.Changes
regenerate-stubs:windows-latest→ubuntu-latestmono-complete(apt) instead of the GTK# 2 MSI download/installdotnet tool restoreanddocs-download-outputstepsscripts/infra/docs/generate-api-docs.shentry point instead ofdotnet cake --target=update-docsglobal.jsonfor the .NET SDK and Linux-style nuget cache pathspull_requesttrigger from the workflowon:block.lock.ymlviagh aw compile(both commits)Merge order
✅ Prerequisite satisfied. The companion SkiaSharp PR mono/SkiaSharp#4200 — which adds
scripts/infra/docs/generate-api-docs.sh(the Linux-everywhere doc-generation infra) — has merged tomain, so the checked-out SkiaSharp tree now has the script. This PR is safe to merge.History
Supersedes the original #144, which gh-aw's
recreate_ref: trueauto-closed when a workflow run was dispatched on its branch. Moved to the dedicatedci/linux-mdoc-regenerate-stubsbranch so the agentic placeholder-fill PRs that reusedev/linux-mdoc-regenerate-stubs(e.g. #145) can't collide with it.Co-authored-by: Copilot 223556219+Copilot@users.noreply.github.com