NA

native-dependency-update

Automates the process of updating low-level system dependencies like libpng and zlib within SkiaSharp.

Install

mkdir -p .claude/skills/native-dependency-update && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/5241" && unzip -o skill.zip -d .claude/skills/native-dependency-update && rm skill.zip

Installs to .claude/skills/native-dependency-update

Activation

This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.

Update native dependencies (libpng, libexpat, zlib, libwebp, harfbuzz, freetype, libjpeg-turbo, etc.) in SkiaSharp's Skia fork. Handles security CVE fixes, bug fixes, and version bumps. Use when user asks to: - Bump/update a native dependency (libpng, zlib, expat, webp, etc.) - Fix a CVE or security vulnerability in a native library - Update Skia's DEPS file - Check what version of a dependency is currently used - Analyze breaking changes between dependency versions Triggers: "bump libpng", "update zlib", "fix CVE in expat", "update native deps", "what version of libpng", "check for breaking changes". For security audits (finding CVEs, checking PR coverage), use the `security-audit` skill instead.
706 chars✓ has a “when” triggerlonger than Claude Code's old 250-char listing cap (fine on current versions)
Advanced

Key capabilities

  • Update native dependencies in Skia fork
  • Patch security vulnerabilities
  • Update DEPS and cgmanifest files
  • Build and verify native libraries
  • Manage submodule references

How it works

It follows a multi-phase process to update dependency commit hashes, update manifest files, and verify builds before creating PRs.

Inputs & outputs

You give it
Dependency update request
You get back
Updated dependency files and PRs

When to use native-dependency-update

  • Patch CVEs in native libs
  • Update SkiaSharp dependencies
  • Apply security fixes for libpng/zlib

About this skill

Native Dependency Update Skill

Update native dependencies in SkiaSharp's Skia fork (mono/skia).

Key References

⚠️ MANDATORY: Follow Every Phase

You MUST complete ALL phases in order. Do not skip phases to save time.

Pre-Flight Checklist

Before starting, confirm you will:

  • Complete Phase 0-8 in order
  • Update DEPS, externals/skia submodule, cgmanifest.json, AND scripts/VERSIONS.txt (for independently-versioned deps — e.g. harfbuzz)
  • Build and test locally before any PR
  • Create PRs (never push directly to protected branches)
  • Stop and ask at every 🛑 checkpoint

Critical Rules

🛑 STOP AND ASK before: Creating PRs, Merging PRs, Force pushing, Any destructive git operations

🚫 BRANCH PROTECTION (MANDATORY COMPLIANCE)

⛔ POLICY VIOLATION: Direct commits to protected branches are prohibited.

This rule applies to BOTH repositories:

RepositoryProtected BranchesAction Required
mono/SkiaSharp (parent repo)main, release/*Create feature branch first
mono/skia (externals/skia submodule)main, skiasharpCreate feature branch first

Before ANY commit in either repository:

  1. Create a feature branch — Use naming convention: dev/update-{dep}
  2. Never commit directly to protected branches — All changes require a PR
  3. This is a compliance requirement — Direct commits bypass review, CI, and audit trails

🔒 Security Rules (ALWAYS — not just for CVE bumps)

All dependency updates are assumed security-sensitive. These rules apply to EVERY bump:

Commit message: Update {dep} to {version} — NOTHING else (plus Co-authored-by trailer) PR title: Update {dep} to {version} PR body: Version numbers, file changes, build verification results ONLY Branch name: dev/update-{dep} — NEVER include CVE IDs

Prohibited in ALL public artifacts (PRs, commits, branches, PR comments):

  • ❌ CVE IDs (e.g., CVE-2026-XXXXX)
  • ❌ Severity ratings or CVSS scores
  • ❌ Words: "security", "vulnerability", "exploit", "fix CVE", "security bump"
  • ❌ Version ranges like "from X to Y" in commit messages
  • ❌ Branch context like "(release/3.119.x)" in commit messages

Security analysis goes in the session conversation ONLY — report to the user:

  1. Which CVEs are fixed, severity, CVSS scores
  2. Which CVEs affect SkiaSharp's code paths and which don't (with reasoning)
  3. Behavior changes that may need test coverage
  4. Upstream issues that remain unfixed

❌ NEVER Do These

ShortcutWhy It's Wrong
Push directly to protected branchesBypasses PR review and CI
Skip native build phaseCI is too slow; must verify locally first
Manually close issuesBreaks audit trail; PR merge auto-closes
Skip cgmanifest.json updateSecurity compliance requires it
Skip scripts/VERSIONS.txt for an independently-versioned dep (harfbuzz)Native soname, DLL FileVersion, and NuGet version drift out of sync with the actual binary
Skip externals/skia submodule updateSkiaSharp won't use the new dependency version
Revert/undo pushed commitsFix forward with new commit instead
Merge both PRs without updating submodule in betweenSquash-merge creates new SHA; submodule points to orphaned commit; BREAKS USERS
Include security details in public artifactsLeaks vulnerability info before users can update

Environment Reminders

These do NOT persist across bash tool calls. Prefix every relevant command:

CommandPrefix
dotnetexport PATH="/usr/local/share/dotnet:/opt/homebrew/bin:$PATH" &&
gh pr create, gh pr edit, etc.unset GH_TOKEN &&
grep (pattern matching)Use grep -E not grep -P (BSD grep on macOS)

Phase 0: Environment Setup (MANDATORY FIRST STEP)

Run the setup script before any other work. It initializes submodules, unshallows the dependency, creates the skia feature branch, and verifies the environment:

bash .agents/skills/native-dependency-update/scripts/setup.sh {dep} {skia_target_branch} {skiasharp_target_branch}

Arguments:

ArgDefaultExamples
dep(required)libpng, expat, zlib, libwebp, freetype
skia_target_branchskiasharpskiasharp, release/3.119.x
skiasharp_target_branchmainmain, release/3.119.x

Determining the skia target branch

⚠️ NEVER assume the skia target branch. It depends on what the user is asking:

User requestskiasharp_target_branchskia_target_branch
Update on mainmainskiasharp
Backport to release branchrelease/3.119.xAsk the user

If you're unsure which skia branch to target, ask the user. Do not guess.

After the script completes, proceed to Phase 1.


Workflow

Phase 1: Discovery

  1. Check for existing PRs in mono/SkiaSharp and mono/skia
  2. Check current version in externals/skia/DEPS
  3. Find target version — get commit hash with git rev-parse {tag}^{commit}

Phase 2: Analysis

Source File Verification (MANDATORY):

cd externals/skia/third_party/externals/{dep}
git diff {old}..{new} --diff-filter=AD --name-only  # Added/Deleted files

Cross-reference against externals/skia/third_party/{dep}/BUILD.gn — new source files may need to be added.

👉 See references/breaking-changes.md for risk assessment.

Phase 3: Local Changes

  1. Edit externals/skia/DEPS with new commit hash
  2. Update BUILD.gn if needed (rare)
  3. Update cgmanifest.json with new version (required for CVE detection)
  4. Update scripts/VERSIONS.txt — only for deps that ship their own native library / NuGet package. Among the bumpable deps this is currently only harfbuzz (libpng, zlib, expat, libwebp, freetype, libjpeg-turbo are statically linked into libSkiaSharp and have NO VERSIONS.txt entry — skip this step for them). See VERSIONS.txt updates below.
  5. Checkout new version in dependency directory

👉 See documentation/dev/dependencies.md for the cgmanifest format.

VERSIONS.txt updates (harfbuzz)

When bumping harfbuzz to {major}.{minor}.{micro}, update ALL of these lines in scripts/VERSIONS.txt (they otherwise drift out of sync with the binary — the soname/file lines drive the actual native .so soname and DLL FileVersion):

EntryLine formatValue for X.Y.Z
harfbuzzreleaseX.Y.Z
HarfBuzzsoname0.<60000 + X*100 + Y*10 + Z>.0 (e.g. 14.2.1 → 0.61421.0)
HarfBuzzSharpfileX.Y.Z
HarfBuzzSharp + all HarfBuzzSharp.NativeAssets.*nugetX.Y.Z (≈10 lines)

The soname formula is documented in a comment directly above the HarfBuzz soname line. Verify your result with grep -E "harfbuzz|HarfBuzz" scripts/VERSIONS.txt — no stale version should remain.

Phase 4: Build & Test

🛑 MANDATORY: Build locally before creating PRs.

See documentation/dev/building.md for platform-specific build commands.

dotnet cake --target=externals-macos --arch=arm64  # Example

# Run all tests (core + Vulkan + Direct3D). GPU backends are required per
# GpuPolicy — a backend that cannot come up fails.
dotnet test tests/SkiaSharp.Tests.Console.slnx

Use the unfiltered solution for initial and final validation. If it identifies a failure, use the owning core, singleton, Vulkan, or Direct3D test project for filtered diagnostic iterations; filtering the .slnx fails the other projects with zero matches. Rerun the unfiltered solution after the focused test passes.

Build Retry Strategy

Common transient failure: HTTP 429 from chromium.googlesource.com

When running dotnet cake --target=externals-macos, the git-sync-deps step fetches 10+ dependencies from Google's mirrors in parallel. If multiple sessions run concurrently, you'll hit rate limits:

error: RPC failed; HTTP 429 curl 22 The requested URL returned error: 429
Exception: Thread failure detected

Strategy:

  1. Wait a short while (rate limits are transient)
  2. Retry the build command
  3. If it still fails after 3 retries, stop and ask for help

Do NOT attempt to manually clone dependencies from other repos — you may pick wrong versions or SHAs.

Other common build issues:

  • fetch-gn network abort → retry (transient)
  • --no-restore flag on dotnet test → remove it, let NuGet restore run
  • Test TTY noise → pipe to file or use tail -50 to read results

cgmanifest.json Schema

The cgmanifest.json uses different structures per component type:

  • Type "other": component.other.name, component.other.version
  • Type "git": component.git.repositoryUrl, component.git.commitHash

Do NOT assume all entries use the same schema. Check component.type first.

Phase 5: Create PRs

🛑 STOP AND ASK FOR APPROVAL before creating PRs.

Both PRs must be created together — CI requires both.

Both repos use branch name dev/update-{dep}. The skia branch was already created by the setup script.

Step 1: Create mono/skia PR

The branch dev/update-{dep} already exists in externals/skia (created by setup script).

  1. Stage ALL changes before committing (DEPS, BUILD.gn if changed)
  2. Commit ONCE with this exact format:
    Update {dep} 
    

Content truncated.

When not to use it

  • Direct commits to protected branches
  • Skipping local build verification

Prerequisites

SkiaSharp repository accessLocal build environment

Limitations

  • No security details allowed in public artifacts
  • Requires manual submodule synchronization

How it compares

It enforces strict compliance with branch protection and security rules, ensuring audit trails and build verification are maintained.

Compared to similar skills

native-dependency-update side by side with the closest alternatives in the catalog.

SkillInstallsUpdatedSafetyDifficulty
native-dependency-update (this skill)11moReviewAdvanced
superpowers-review66moNo flagsIntermediate
contrib-pr-review127dReviewIntermediate
production-code-audit16moReviewAdvanced

Try saying

Example prompts that trigger this skill in your AI assistant.

add-api

mono

Add new C# APIs to SkiaSharp by wrapping Skia C++ functionality. Structured 6-phase workflow: C++ analysis → C API creation → submodule commits → binding generation → C# wrapper → testing. Triggers: - Issue classified as "New API" (after fetching and classification) - Direct request: "add DrawFoo method", "expose SkSurface::draw", "wrap sk_foo_bar" - Keywords: "add API", "expose function", "wrap method", "create binding for"

68

bug-fix

mono

Fix bugs in SkiaSharp C# bindings. Structured workflow for investigating, fixing, and testing bug reports. Triggers: Crash, exception, AccessViolationException, incorrect output, wrong behavior, memory leak, disposal issues, "fails", "broken", "doesn't work", "investigate issue", "fix issue", "look at #NNNN", any GitHub issue number referencing a bug. For adding new APIs, use `add-api` skill instead.

426

api-docs

mono

Write and review XML API documentation for SkiaSharp following .NET guidelines. Triggers: "document class", "add XML docs", "write XML documentation", "add triple-slash comments", "review documentation quality", "check docs for errors", "fix doc issues", "fill in missing docs", "remove To be added placeholders", API documentation requests.

110

release-branch

mono

Create a release branch for SkiaSharp. Use when user says "release X", "start release X", "create release branch for X", "I want to release", or "release now". This is the FIRST step of releasing - creates branch and pushes to trigger CI. Can auto-detect next preview version from main branch.

12

release-publish

mono

Publish SkiaSharp packages and finalize the release. Use when user says "publish X", "finalize X", "tag X", or "finish release X". This is the FINAL step - after release-testing passes. Publishes to NuGet.org, creates tag, GitHub release, and closes milestone. Triggers: "publish the release", "push to nuget", "create github release", "tag the release", "close the milestone", "annotate release notes", "testing passed what's next", "finalize 3.119.2", "release is ready".

19

release-testing

mono

Run integration tests to verify SkiaSharp NuGet packages work correctly before publishing. Use when user asks to: - Test/verify packages before release - Run integration tests - Test on specific device (iPad, iPhone, Android emulator, Mac, Windows) - Verify SkiaSharp rendering works - Check if packages are ready for publishing - Run smoke/console/blazor/maui tests - Continue with release - Test version X Triggers: "test the release", "verify packages", "run tests on iPad", "check ios tests", "test mac catalyst", "run android tests", "continue", "test 3.119.2-preview.2".

14

Search skills

Search the agent skills registry