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 |
HarfBuzzSharp + all HarfBuzzSharp.NativeAssets.* | nuget | X.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:
- 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.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).
- Stage ALL changes before committing (DEPS, BUILD.gn if changed)
- 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
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 | 1mo | Review | Advanced |
| superpowers-review | 6 | 6mo | No flags | Intermediate |
| contrib-pr-review | 1 | 27d | Review | Intermediate |
| production-code-audit | 1 | 6mo | 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