From 5bcb571857cde215b6bfe0d3690f4a499f9e9b42 Mon Sep 17 00:00:00 2001 From: Matthew Leibowitz Date: Sat, 20 Jun 2026 00:47:08 +0200 Subject: [PATCH] [CI] Run API-docs stub regeneration on Linux via Mono MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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> --- .../workflows/auto-api-docs-writer.lock.yml | 62 +++++++------------ .github/workflows/auto-api-docs-writer.md | 41 +++++------- 2 files changed, 38 insertions(+), 65 deletions(-) diff --git a/.github/workflows/auto-api-docs-writer.lock.yml b/.github/workflows/auto-api-docs-writer.lock.yml index 86b486ba..f789346b 100644 --- a/.github/workflows/auto-api-docs-writer.lock.yml +++ b/.github/workflows/auto-api-docs-writer.lock.yml @@ -1,4 +1,4 @@ -# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"ee0b83f9557935df28356851297da8f9275b8282c2b09d4c34fea266d3602e16","compiler_version":"v0.71.5","strict":true,"agent_id":"copilot"} +# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"d3b8a031f3294d54d036d742604cf1e7e72e464347fa8a44460fa60cd93f6a1a","compiler_version":"v0.71.5","strict":true,"agent_id":"copilot"} # gh-aw-manifest: {"version":1,"secrets":["COPILOT_GITHUB_TOKEN","GH_AW_CI_TRIGGER_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN"],"actions":[{"repo":"actions/cache","sha":"0057852bfaa89a56745cba8c7296529d2fc39830","version":"v4"},{"repo":"actions/checkout","sha":"34e114876b0b11c390a56381ad16ebd13914f8d5","version":"v4"},{"repo":"actions/checkout","sha":"de0fac2e4500dabe0009e67214ff5f5447ce83dd","version":"v6.0.2"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/download-artifact","sha":"d3f86a106a0bac45b974a628896c90dbdf5c8093","version":"v4"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/setup-dotnet","sha":"67a3573c9a986a3f9c594539f4ab511d57bb3ce9","version":"v4"},{"repo":"actions/setup-node","sha":"48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e","version":"v6.4.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"actions/upload-artifact","sha":"ea165f8d65b6e75b540449e92b4886f43607fa02","version":"v4"},{"repo":"github/gh-aw-actions/setup","sha":"b8068426813005612b960b5ab0b8bd2c27142323","version":"v0.71.5"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.25.40","digest":"sha256:14ff567e8d9d4c2fbc5e55c973488381c71d7e0fdbe72d30ee7b8a738fd86504","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.25.40@sha256:14ff567e8d9d4c2fbc5e55c973488381c71d7e0fdbe72d30ee7b8a738fd86504"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.25.40","digest":"sha256:2883ca3e5ae9f330cafdd9345bfd4ae17fc8da36c96d4c9a1f76e922b4c45280","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.25.40@sha256:2883ca3e5ae9f330cafdd9345bfd4ae17fc8da36c96d4c9a1f76e922b4c45280"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.25.40","digest":"sha256:b084f4a2c771f584ee68084ced52fa6b3245197a1889645d817462d307d3ac51","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.25.40@sha256:b084f4a2c771f584ee68084ced52fa6b3245197a1889645d817462d307d3ac51"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.3.6","digest":"sha256:2bb8eef86006a4c5963c55616a9c51c32f27bfdecb023b8aa6f91f6718d9171c","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.3.6@sha256:2bb8eef86006a4c5963c55616a9c51c32f27bfdecb023b8aa6f91f6718d9171c"},{"image":"ghcr.io/github/github-mcp-server:v1.0.3","digest":"sha256:2ac27ef03461ef2b877031b838a7d1fd7f12b12d4ace7796d8cad91446d55959","pinned_image":"ghcr.io/github/github-mcp-server:v1.0.3@sha256:2ac27ef03461ef2b877031b838a7d1fd7f12b12d4ace7796d8cad91446d55959"},{"image":"node:lts-alpine","digest":"sha256:d1b3b4da11eefd5941e7f0b9cf17783fc99d9c6fc34884a665f40a06dbdfc94f","pinned_image":"node:lts-alpine@sha256:d1b3b4da11eefd5941e7f0b9cf17783fc99d9c6fc34884a665f40a06dbdfc94f"}]} # ___ _ _ # / _ \ | | (_) @@ -219,23 +219,23 @@ jobs: run: | bash "${RUNNER_TEMP}/gh-aw/actions/create_prompt_first.sh" { - cat << 'GH_AW_PROMPT_e5660c6c744a78d6_EOF' + cat << 'GH_AW_PROMPT_ef4b7af94d59d825_EOF' - GH_AW_PROMPT_e5660c6c744a78d6_EOF + GH_AW_PROMPT_ef4b7af94d59d825_EOF cat "${RUNNER_TEMP}/gh-aw/prompts/xpia.md" cat "${RUNNER_TEMP}/gh-aw/prompts/temp_folder_prompt.md" cat "${RUNNER_TEMP}/gh-aw/prompts/markdown.md" cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_prompt.md" - cat << 'GH_AW_PROMPT_e5660c6c744a78d6_EOF' + cat << 'GH_AW_PROMPT_ef4b7af94d59d825_EOF' Tools: create_pull_request, missing_tool, missing_data, noop - GH_AW_PROMPT_e5660c6c744a78d6_EOF + GH_AW_PROMPT_ef4b7af94d59d825_EOF cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_create_pull_request.md" - cat << 'GH_AW_PROMPT_e5660c6c744a78d6_EOF' + cat << 'GH_AW_PROMPT_ef4b7af94d59d825_EOF' - GH_AW_PROMPT_e5660c6c744a78d6_EOF + GH_AW_PROMPT_ef4b7af94d59d825_EOF cat "${RUNNER_TEMP}/gh-aw/prompts/mcp_cli_tools_prompt.md" - cat << 'GH_AW_PROMPT_e5660c6c744a78d6_EOF' + cat << 'GH_AW_PROMPT_ef4b7af94d59d825_EOF' The following GitHub context information is available for this workflow: {{#if __GH_AW_GITHUB_ACTOR__ }} @@ -267,12 +267,12 @@ jobs: - **Note**: If a branch you need is not in the list above and is not listed as an additional fetched ref, it has NOT been checked out. For private repositories you cannot fetch it without proper authentication. If the branch is required and not available, exit with an error and ask the user to add it to the `fetch:` option of the `checkout:` configuration (e.g., `fetch: ["refs/pulls/open/*"]` for all open PR refs, or `fetch: ["main", "feature/my-branch"]` for specific branches). - GH_AW_PROMPT_e5660c6c744a78d6_EOF + GH_AW_PROMPT_ef4b7af94d59d825_EOF cat "${RUNNER_TEMP}/gh-aw/prompts/github_mcp_tools_with_safeoutputs_prompt.md" - cat << 'GH_AW_PROMPT_e5660c6c744a78d6_EOF' + cat << 'GH_AW_PROMPT_ef4b7af94d59d825_EOF' {{#runtime-import .github/workflows/auto-api-docs-writer.md}} - GH_AW_PROMPT_e5660c6c744a78d6_EOF + GH_AW_PROMPT_ef4b7af94d59d825_EOF } > "$GH_AW_PROMPT" - name: Interpolate variables and render templates uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 @@ -480,9 +480,9 @@ jobs: mkdir -p "${RUNNER_TEMP}/gh-aw/safeoutputs" mkdir -p /tmp/gh-aw/safeoutputs mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs - cat > "${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" << 'GH_AW_SAFE_OUTPUTS_CONFIG_c2d4d133de8c2ed7_EOF' + cat > "${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" << 'GH_AW_SAFE_OUTPUTS_CONFIG_99bee74ae459ddd2_EOF' {"create_pull_request":{"base_branch":"main","draft":false,"max":1,"max_patch_files":100,"max_patch_size":1024,"preserve_branch_name":true,"protect_top_level_dot_folders":true,"protected_files":["package.json","bun.lockb","bunfig.toml","deno.json","deno.jsonc","deno.lock","global.json","NuGet.Config","Directory.Packages.props","mix.exs","mix.lock","go.mod","go.sum","stack.yaml","stack.yaml.lock","pom.xml","build.gradle","build.gradle.kts","settings.gradle","settings.gradle.kts","gradle.properties","package-lock.json","yarn.lock","pnpm-lock.yaml","npm-shrinkwrap.json","requirements.txt","Pipfile","Pipfile.lock","pyproject.toml","setup.py","setup.cfg","Gemfile","Gemfile.lock","uv.lock","CODEOWNERS","DESIGN.md","README.md","CONTRIBUTING.md","CHANGELOG.md","SECURITY.md","CODE_OF_CONDUCT.md","AGENTS.md","CLAUDE.md","GEMINI.md"],"recreate_ref":true},"create_report_incomplete_issue":{},"missing_data":{},"missing_tool":{},"noop":{"max":1,"report-as-issue":"true"},"report_incomplete":{}} - GH_AW_SAFE_OUTPUTS_CONFIG_c2d4d133de8c2ed7_EOF + GH_AW_SAFE_OUTPUTS_CONFIG_99bee74ae459ddd2_EOF - name: Generate Safe Outputs Tools env: GH_AW_TOOLS_META_JSON: | @@ -688,7 +688,7 @@ jobs: mkdir -p /home/runner/.copilot GH_AW_NODE=$(which node 2>/dev/null || command -v node 2>/dev/null || echo node) - cat << GH_AW_MCP_CONFIG_25debe57faeea757_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs" + cat << GH_AW_MCP_CONFIG_b08a23930fcde3fa_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs" { "mcpServers": { "github": { @@ -736,7 +736,7 @@ jobs: "payloadDir": "${MCP_GATEWAY_PAYLOAD_DIR}" } } - GH_AW_MCP_CONFIG_25debe57faeea757_EOF + GH_AW_MCP_CONFIG_b08a23930fcde3fa_EOF - name: Mount MCP servers as CLIs id: mount-mcp-clis continue-on-error: true @@ -1332,7 +1332,7 @@ jobs: regenerate-stubs: needs: activation - runs-on: windows-latest + runs-on: ubuntu-latest steps: - name: Configure GH_HOST for enterprise compatibility id: ghes-host-config @@ -1360,32 +1360,18 @@ jobs: - name: Setup .NET uses: actions/setup-dotnet@67a3573c9a986a3f9c594539f4ab511d57bb3ce9 # v4 with: - dotnet-version: 8.0.x + global-json-file: global.json + - name: Setup Mono (runs mdoc.exe on Linux) + run: | + sudo apt-get update + sudo apt-get install -y --no-install-recommends mono-complete - name: Cache NuGet global packages uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4 with: key: nuget-global-${{ hashFiles('scripts/VERSIONS.txt', 'scripts/infra/shared/shared.cake') }} - path: "${{ env.USERPROFILE }}\\.nuget\\packages" + path: ~/.nuget/packages restore-keys: | nuget-global- - - name: "Cache GTK# installer" - id: cache-gtk - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4 - with: - key: gtk-sharp-2.12.45 - path: "${{ runner.temp }}\\gtk-sharp.msi" - - name: "Download GTK# 2" - if: steps.cache-gtk.outputs.cache-hit != 'true' - run: | - $msiUrl = "https://github.com/mono/gtk-sharp/releases/download/2.12.45/gtk-sharp-2.12.45.msi" - Invoke-WebRequest -Uri $msiUrl -OutFile "$env:RUNNER_TEMP\gtk-sharp.msi" - shell: pwsh - - name: "Install GTK# 2" - run: | - Start-Process msiexec.exe -ArgumentList "/i", "$env:RUNNER_TEMP\gtk-sharp.msi", "/quiet", "/norestart" -Wait -NoNewWindow - shell: pwsh - - name: Restore tools - run: dotnet tool restore - name: Cache NuGet package_cache uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4 with: @@ -1393,10 +1379,8 @@ jobs: path: externals/package_cache restore-keys: | docs-package-cache- - - name: Download latest NuGet packages - run: dotnet cake --target=docs-download-output - name: Regenerate API docs - run: dotnet cake --target=update-docs + run: bash scripts/infra/docs/generate-api-docs.sh - name: Extract placeholders and manifest run: | New-Item -ItemType Directory -Path output/docs-work -Force | Out-Null diff --git a/.github/workflows/auto-api-docs-writer.md b/.github/workflows/auto-api-docs-writer.md index ab56fd50..43d7dfeb 100644 --- a/.github/workflows/auto-api-docs-writer.md +++ b/.github/workflows/auto-api-docs-writer.md @@ -21,11 +21,16 @@ on: type: string # -- Custom jobs ------------------------------------------------------- -# Stub regeneration requires Windows (mdoc.exe is .NET Framework). -# Checks out SkiaSharp (public), runs mdoc, uploads result as artifact. +# Stub regeneration runs mdoc to produce the XML reference stubs. mdoc.exe is a +# .NET Framework tool, so on Linux it runs under Mono (docs.cake invokes it via mono); +# this lets the job run on ubuntu-latest instead of windows-latest. The managed GTK# +# reference assemblies mdoc needs are supplied from NuGet by the cake comparer (as --lib +# paths), so no system GTK# install is required — mono is the only extra dependency. +# Checks out SkiaSharp (public), runs scripts/infra/docs/generate-api-docs.sh, uploads +# the result as an artifact. jobs: regenerate-stubs: - runs-on: windows-latest + runs-on: ubuntu-latest steps: - name: Checkout SkiaSharp uses: actions/checkout@v4 @@ -44,32 +49,18 @@ jobs: - name: Setup .NET uses: actions/setup-dotnet@v4 with: - dotnet-version: '8.0.x' + global-json-file: global.json + - name: Setup Mono (runs mdoc.exe on Linux) + run: | + sudo apt-get update + sudo apt-get install -y --no-install-recommends mono-complete - name: Cache NuGet global packages uses: actions/cache@v4 with: - path: ${{ env.USERPROFILE }}\.nuget\packages + path: ~/.nuget/packages key: nuget-global-${{ hashFiles('scripts/VERSIONS.txt', 'scripts/infra/shared/shared.cake') }} restore-keys: | nuget-global- - - name: Cache GTK# installer - id: cache-gtk - uses: actions/cache@v4 - with: - path: ${{ runner.temp }}\gtk-sharp.msi - key: gtk-sharp-2.12.45 - - name: Download GTK# 2 - if: steps.cache-gtk.outputs.cache-hit != 'true' - shell: pwsh - run: | - $msiUrl = "https://github.com/mono/gtk-sharp/releases/download/2.12.45/gtk-sharp-2.12.45.msi" - Invoke-WebRequest -Uri $msiUrl -OutFile "$env:RUNNER_TEMP\gtk-sharp.msi" - - name: Install GTK# 2 - shell: pwsh - run: | - Start-Process msiexec.exe -ArgumentList "/i", "$env:RUNNER_TEMP\gtk-sharp.msi", "/quiet", "/norestart" -Wait -NoNewWindow - - name: Restore tools - run: dotnet tool restore - name: Cache NuGet package_cache uses: actions/cache@v4 with: @@ -77,10 +68,8 @@ jobs: key: docs-package-cache-${{ hashFiles('scripts/VERSIONS.txt', 'scripts/infra/shared/shared.cake') }} restore-keys: | docs-package-cache- - - name: Download latest NuGet packages - run: dotnet cake --target=docs-download-output - name: Regenerate API docs - run: dotnet cake --target=update-docs + run: bash scripts/infra/docs/generate-api-docs.sh - name: Extract placeholders and manifest shell: pwsh run: |