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.zipInstalls 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.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
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
- documentation/dev/dependencies.md — Complete dependency list, cgmanifest.json format, CVE database names
- references/breaking-changes.md — Breaking change analysis guidance
⚠️ 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/skiasubmodule,cgmanifest.json, ANDscripts/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:
| Repository | Protected Branches | Action Required |
|---|---|---|
| mono/SkiaSharp (parent repo) | main, release/* | Create feature branch first |
mono/skia (externals/skia submodule) | main, skiasharp | Create feature branch first |
Before ANY commit in either repository:
- Create a feature branch — Use naming convention:
dev/update-{dep} - Never commit directly to protected branches — All changes require a PR
- 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:
- Which CVEs are fixed, severity, CVSS scores
- Which CVEs affect SkiaSharp's code paths and which don't (with reasoning)
- Behavior changes that may need test coverage
- Upstream issues that remain unfixed
❌ NEVER Do These
| Shortcut | Why It's Wrong |
|---|---|
| Push directly to protected branches | Bypasses PR review and CI |
| Skip native build phase | CI is too slow; must verify locally first |
| Manually close issues | Breaks audit trail; PR merge auto-closes |
Skip cgmanifest.json update | Security 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 update | SkiaSharp won't use the new dependency version |
| Revert/undo pushed commits | Fix forward with new commit instead |
| Merge both PRs without updating submodule in between | Squash-merge creates new SHA; submodule points to orphaned commit; BREAKS USERS |
| Include security details in public artifacts | Leaks vulnerability info before users can update |
Environment Reminders
These do NOT persist across bash tool calls. Prefix every relevant command:
| Command | Prefix |
|---|---|
dotnet | export 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:
| Arg | Default | Examples |
|---|---|---|
dep | (required) | libpng, expat, zlib, libwebp, freetype |
skia_target_branch | skiasharp | skiasharp, release/3.119.x |
skiasharp_target_branch | main | main, release/3.119.x |
Determining the skia target branch
⚠️ NEVER assume the skia target branch. It depends on what the user is asking:
| User request | skiasharp_target_branch | skia_target_branch |
|---|---|---|
| Update on main | main | skiasharp |
| Backport to release branch | release/3.119.x | Ask 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
- Check for existing PRs in mono/SkiaSharp and mono/skia
- Check current version in
externals/skia/DEPS - 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
- Edit
externals/skia/DEPSwith new commit hash - Update BUILD.gn if needed (rare)
- Update
cgmanifest.jsonwith new version (required for CVE detection) - 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 intolibSkiaSharpand have NOVERSIONS.txtentry — skip this step for them). See VERSIONS.txt updates below. - 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):
| Entry | Line format | Value for X.Y.Z |
|---|---|---|
harfbuzz | release | X.Y.Z |
HarfBuzz | soname | 0.<60000 + X*100 + Y*10 + Z>.0 (e.g. 14.2.1 → 0.61421.0) |
HarfBuzzSharp | file | X.Y.Z (N = 0) |
HarfBuzzSharp + all HarfBuzzSharp.NativeAssets.* | nuget | X.Y.Z (N = 0, ≈10 lines) |
HarfBuzz upgrades are made on main and are not backported to older release
lines. The upgrade resets package revision N to zero and makes the current
Skia milestone the base for X.Y.Z; the normalized 3-part form represents
X.Y.Z.0.
If later Skia milestones continue using the same native HarfBuzz version, each milestone adds 100 to the bucket base. For example, if M152 adopts 14.3.1, M152 uses revisions 0–99, M153 uses 100–199, and M154 uses 200–299.
The soname formula and package bucket formula are documented in comments next
to their lines. Verify the result with
grep -E "harfbuzz|HarfBuzz" scripts/VERSIONS.txt: the native release and
soname must match X.Y.Z, while every HarfBuzzSharp file/NuGet entry must
reset to the same X.Y.Z package version.
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:
- Wait a short while (rate limits are transient)
- Retry the build command
- 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-gnnetwork abort → retry (transient)--no-restoreflag ondotnet test→ remove it, let NuGet restore run- Test TTY noise → pipe to file or use
tail -50to 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.commit
Content truncated.
When not to use it
- →Direct commits to protected branches
- →Skipping local build verification
Prerequisites
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.
| Skill | Installs | Updated | Safety | Difficulty |
|---|---|---|---|---|
| native-dependency-update (this skill) | 1 | 3mo | Review | Advanced |
| superpowers-review | 6 | 8mo | No flags | Intermediate |
| contrib-pr-review | 1 | 2mo | Review | Intermediate |
| production-code-audit | 1 | 8mo | Review | Advanced |
Try saying
Example prompts that trigger this skill in your AI assistant.
More by mono
View all by mono →You might also like
superpowers-review
anthonylee991
Reviews changes for correctness, edge cases, style, security, and maintainability with severity levels (Blocker/Major/Minor/Nit). Use before finalizing changes.
contrib-pr-review
homeassistant-ai
Review a contribution PR for safety, quality, and readiness. Checks for security concerns, test coverage, size appropriateness, and intent alignment. Use when reviewing external contributions.
production-code-audit
davila7
Autonomously deep-scan entire codebase line-by-line, understand architecture and patterns, then systematically transform it to production-grade, corporate-level professional quality with optimizations
tech-debt
vm0-ai
Technical debt management - scan codebase for bad smells and create tracking issues
dependency-updater
davila7
Smart dependency management for any language. Auto-detects project type, applies safe updates automatically, prompts for major versions, diagnoses and fixes dependency issues.
deps
matteocervelli
Audit dependency freshness — scan outdated deps and CVEs, classify severity, record update/defer/skip decisions in Atrium, gate PASS/WARN/FAIL. Use when checking for outdated packages or deciding whether to upgrade. Trigger on "outdated dependencies", "dependency audit", "are my deps up to date", "s