Skip to content

[CI] Run API-docs stub regeneration on Linux via Mono#147

Merged
mattleibow merged 2 commits into
mainfrom
ci/linux-mdoc-regenerate-stubs
Jun 23, 2026
Merged

[CI] Run API-docs stub regeneration on Linux via Mono#147
mattleibow merged 2 commits into
mainfrom
ci/linux-mdoc-regenerate-stubs

Conversation

@mattleibow

@mattleibow mattleibow commented Jun 20, 2026

Copy link
Copy Markdown
Collaborator

What

Two related CI changes to the auto-api-docs-writer workflow:

  1. Flip the regenerate-stubs job from windows-latest to ubuntu-latest, running mdoc.exe under Mono.
  2. Drop the pull_request trigger 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:

  • mdoc.exe runs fine under Mono, and SkiaSharp's docs.cake already invokes it via mono.
  • 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. 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 (hash ec15190a) — so the job is both correct and idempotent on Linux.

Why drop the pull_request trigger

The 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 red safe_outputs check on this very PR.

Removing the pull_request trigger stops the writer from running on PRs entirely. The push: branches:[main] trigger still validates workflow edits after they land, and workflow_dispatch + schedule are unaffected.

Changes

  • regenerate-stubs: windows-latestubuntu-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
  • Remove the pull_request trigger from the workflow on: block
  • Recompiled .lock.yml via gh 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 to main, 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: true auto-closed when a workflow run was dispatched on its branch. Moved to the dedicated ci/linux-mdoc-regenerate-stubs branch so the agentic placeholder-fill PRs that reuse dev/linux-mdoc-regenerate-stubs (e.g. #145) can't collide with it.

Co-authored-by: Copilot 223556219+Copilot@users.noreply.github.com

@learn-build-service-prod

Copy link
Copy Markdown
Contributor

PoliCheck Scan Report

The 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 found

More information about PoliCheck

Information: PoliCheck | Severity Guidance | Term
For any questions: Try searching the learn.microsoft.com contributor guides or post your question in the Learn support channel.

@learn-build-service-prod

Copy link
Copy Markdown
Contributor

Learn Build status updates of commit 5bcb571:

✅ Validation status: passed

File Status Preview URL Details
.github/workflows/auto-api-docs-writer.lock.yml ✅Succeeded
.github/workflows/auto-api-docs-writer.md ✅Succeeded

For more details, please refer to the build report.

mattleibow added a commit to mono/SkiaSharp that referenced this pull request Jun 22, 2026
…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>
@mattleibow mattleibow force-pushed the ci/linux-mdoc-regenerate-stubs branch from 5bcb571 to bf871a2 Compare June 22, 2026 23:16
@learn-build-service-prod

Copy link
Copy Markdown
Contributor

PoliCheck Scan Report

The 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 found

More information about PoliCheck

Information: PoliCheck | Severity Guidance | Term
For any questions: Try searching the learn.microsoft.com contributor guides or post your question in the Learn support channel.

@learn-build-service-prod

Copy link
Copy Markdown
Contributor

Learn Build status updates of commit bf871a2:

✅ Validation status: passed

File Status Preview URL Details
.github/workflows/auto-api-docs-writer.lock.yml ✅Succeeded
.github/workflows/auto-api-docs-writer.md ✅Succeeded

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>
@learn-build-service-prod

Copy link
Copy Markdown
Contributor

PoliCheck Scan Report

The 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 found

More information about PoliCheck

Information: PoliCheck | Severity Guidance | Term
For any questions: Try searching the learn.microsoft.com contributor guides or post your question in the Learn support channel.

@learn-build-service-prod

Copy link
Copy Markdown
Contributor

Learn Build status updates of commit f56aa4f:

✅ Validation status: passed

File Status Preview URL Details
.github/workflows/auto-api-docs-writer.lock.yml ✅Succeeded
.github/workflows/auto-api-docs-writer.md ✅Succeeded

For more details, please refer to the build report.

@mattleibow mattleibow merged commit ea6c47e into main Jun 23, 2026
3 checks passed
@mattleibow mattleibow deleted the ci/linux-mdoc-regenerate-stubs branch June 23, 2026 17:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant