Skip to content

Commit e0f85b3

Browse files
author
v
committed
[migration] Make upstream Skia synchronization portable
Resolve the current SkiaSharp repository at runtime and the paired Skia repository from .gitmodules across detection, metadata, delivery, and direct submodule synchronization. Preserve guarded dual-repository delivery while validating mono, dotnet, and release-line behavior. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 8250c1ca-20e4-461e-bad3-9e2864ad57ea
1 parent 1c28be7 commit e0f85b3

22 files changed

Lines changed: 459 additions & 222 deletions

.agents/skills/ci-status/scripts/tests/test_workflow_registry.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,5 +205,21 @@ def test_documented_schedules_match_the_workflow(self):
205205
f"SKILL.md rows name untracked workflows: {unresolved}")
206206

207207

208+
class SubmoduleSyncIdentityTests(unittest.TestCase):
209+
def test_identity_tooling_is_staged_before_target_checkout(self):
210+
workflow = load_workflow("auto-skia-submodule-sync.yml")
211+
steps = workflow["jobs"]["sync"]["steps"]
212+
names = [step.get("name") for step in steps]
213+
stage_index = names.index("Stage identity tooling")
214+
checkout_index = names.index("Checkout SkiaSharp")
215+
validate_index = names.index("Validate branches")
216+
self.assertLess(stage_index, checkout_index)
217+
self.assertLess(checkout_index, validate_index)
218+
self.assertIn(
219+
'$IDENTITY_SCRIPT" --root "$GITHUB_WORKSPACE"',
220+
steps[validate_index]["run"],
221+
)
222+
223+
208224
if __name__ == "__main__":
209225
unittest.main()

.agents/skills/update-skia/SKILL.md

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
name: update-skia
33
description: >
4-
Update the Skia graphics library to a new Chrome milestone in SkiaSharp's mono/skia fork.
4+
Update the Skia graphics library to a new Chrome milestone in SkiaSharp's paired Skia fork.
55
Handles upstream merge, fork-patch preservation, dependency compatibility, C API adaptation,
66
binding regeneration, full backend testing, and coordinated dual-repo PRs.
77
@@ -17,8 +17,9 @@ The workflow only supplies resolved inputs, a prepared host, and automated PR de
1717

1818
`Skia C++ -> SkiaSharp C API -> generated P/Invoke -> managed wrappers`
1919

20-
Run from the mono/SkiaSharp repository root. Each phase lives in a separate reference so only
21-
the current work enters context.
20+
Run from the current SkiaSharp repository root resolved by
21+
`python3 scripts/infra/repository_identity.py get repository`. Each phase lives in a separate
22+
reference so only the current work enters context.
2223

2324
## Start state
2425

@@ -33,8 +34,8 @@ names.
3334
| `{UPSTREAM_REF}` | `SKIA_SYNC_UPSTREAM_REF` | `chrome/m{TARGET}` or `main` |
3435
| `{BASE_BRANCH}` | `SKIA_SYNC_BASE_BRANCH` | Parent PR base |
3536
| `{PARENT_BASE_SHA}` | `SKIA_SYNC_PARENT_BASE_SHA` | Exact parent base commit used for metadata comparison |
36-
| `{SKIA_BASE_BRANCH}` | `SKIA_SYNC_SKIA_BASE_BRANCH` | mono/skia PR base |
37-
| `{SKIA_BASE_SHA}` | `SKIA_SYNC_SKIA_BASE_SHA` | Exact mono/skia commit recorded by the parent base |
37+
| `{SKIA_BASE_BRANCH}` | `SKIA_SYNC_SKIA_BASE_BRANCH` | Paired Skia PR base |
38+
| `{SKIA_BASE_SHA}` | `SKIA_SYNC_SKIA_BASE_SHA` | Exact paired Skia commit recorded by the parent base |
3839
| `{HEAD_BRANCH}` | `SKIA_SYNC_HEAD_BRANCH` | Feature branch used in both repositories |
3940
| `{IS_RELEASE}` | `SKIA_SYNC_IS_RELEASE` | Whether the selected base is a release line |
4041
| `{BASE_UPSTREAM_SHA}` | `SKIA_SYNC_BASE_UPSTREAM_SHA` | Exact upstream commit recorded by the parent base |
@@ -57,19 +58,19 @@ mkdir -p "$ARTIFACT_DIR"
5758
An update is complete only when:
5859

5960
- The authoritative old-upstream-to-target range was analyzed before merging.
60-
- The mono/skia result is a genuine two-parent merge with every fork patch and dependency
61+
- The paired Skia result is a genuine two-parent merge with every fork patch and dependency
6162
decision accounted for.
6263
- The updated native source builds; downloaded old native artifacts were never substituted.
6364
- Bindings were regenerated and every required managed wrapper was reviewed.
6465
- The final **unfiltered** `tests/SkiaSharp.Tests.Console.slnx` run passes every host, including
6566
every GPU backend required by `GpuPolicy` on the validation host.
66-
- The parent points to the exact tested mono/skia commit.
67+
- The parent points to the exact tested paired Skia commit.
6768
- Both PR descriptions identify untested platforms and are ready for human review.
6869

6970
## Working rules
7071

7172
- Create feature branches in both repositories before changes; never commit to protected branches.
72-
- Use a genuine two-parent merge in mono/skia; never use a tree-override merge.
73+
- Use a genuine two-parent merge in the paired Skia repository; never use a tree-override merge.
7374
- Preserve every fork patch unless upstream contains an equivalent or improved form.
7475
- Mark a removed patch `upstreamed` only after enumerating every independent behavior in its old
7576
delta and locating each one in the target; one upstreamed hunk does not cover another lost hunk.

.agents/skills/update-skia/references/known-gotchas.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ Also watch for renamed/removed GN flags between milestones — obsolete flags ca
4646

4747
### 7. `.gitmodules` Branch Name
4848

49-
When the mono/skia target branch name changes, `.gitmodules` must be updated to track the new branch. Easy to forget; causes silent submodule tracking failures.
49+
When the paired Skia target branch name changes, `.gitmodules` must be updated to track the new branch. Easy to forget; causes silent submodule tracking failures.
5050

5151
### 19. Fork-Only GN `declare_args` Cleanup
5252

@@ -186,7 +186,7 @@ git log --oneline "$MB..{SKIA_BASE_BRANCH}" > "$ARTIFACT_DIR/fork-patches-before
186186
```
187187

188188
For **every conflicted file**, find which fork patch(es) from that list touch it and classify each as
189-
*upstreamed* or *re-applied* (above). Every such patch must appear in the mono/skia PR's "Conflicts
189+
*upstreamed* or *re-applied* (above). Every such patch must appear in the paired Skia PR's "Conflicts
190190
resolved" table with its disposition. A fork patch on a conflicted file that is **neither** upstreamed
191191
nor re-applied is a lost patch — STOP and fix it before committing the merge. (Fork patches whose files
192192
did not conflict merge cleanly and need no listing.)

.agents/skills/update-skia/references/phases/01-03-research.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,15 @@ For a developer-run update:
1010

1111
1. Confirm the parent and `externals/skia` worktrees are clean.
1212
2. Initialize submodules and verify `git`, `gh`, Python 3, and the .NET SDK are available.
13-
3. Fetch the parent base candidates and mono/skia base candidates.
14-
4. Ensure mono/skia has an `upstream` remote for `https://github.com/google/skia.git`.
13+
3. Fetch the parent base candidates and paired Skia base candidates.
14+
4. Ensure the paired Skia repository has an `upstream` remote for `https://github.com/google/skia.git`.
1515
5. Check both repositories for an existing PR or branch for the requested target. Continue an
1616
existing update only when its bases and upstream ref match; never overwrite unrelated work.
1717

1818
Resolve these values, including `IS_RELEASE`, and export the corresponding `SKIA_SYNC_*`
1919
variables from `SKILL.md`:
2020

21-
| Request | Parent base | mono/skia base | Upstream ref | Head |
21+
| Request | Parent base | Paired Skia base | Upstream ref | Head |
2222
|---|---|---|---|---|
2323
| Newest milestone | `main` | `skiasharp` | `chrome/m{TARGET}` | `skia-sync/m{TARGET}` |
2424
| Older supported milestone | existing matching release branch in both repos | same release branch | `chrome/m{TARGET}` | `skia-sync/release-…` |
@@ -36,8 +36,8 @@ For automation, consume the supplied values instead and verify the referenced br
3636
Fetch:
3737

3838
- `origin/{BASE_BRANCH}` in the parent.
39-
- `origin/{SKIA_BASE_BRANCH}` in mono/skia.
40-
- `upstream/{UPSTREAM_REF}` in mono/skia.
39+
- `origin/{SKIA_BASE_BRANCH}` in the paired Skia repository.
40+
- `upstream/{UPSTREAM_REF}` in the paired Skia repository.
4141
- The base branch's recorded `upstream_merge_commit`, by SHA.
4242

4343
Export the exact parent-base submodule pointer as `SKIA_SYNC_SKIA_BASE_SHA`; use it instead of a
@@ -58,7 +58,7 @@ DIFF_RANGE="${BASE_UPSTREAM_SHA}..${TARGET_UPSTREAM_REF}"
5858
```
5959

6060
Use ancestry, not SHA equality, to determine whether the target is already contained in the
61-
selected mono/skia base. If it is, stop before branching. A matching milestone number alone is
61+
selected paired Skia base. If it is, stop before branching. A matching milestone number alone is
6262
not proof of no work; same-milestone bug-fix commits still count.
6363

6464
## Phase 02 — analyze behavior, not only signatures

.agents/skills/update-skia/references/phases/04-05-branch-and-merge.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,9 @@ The helper fails instead of resetting existing branches or dirty files. On succe
2020

2121
- the parent feature branch starts at `{PARENT_BASE_SHA}`;
2222
- every recursive submodule matches that parent commit;
23-
- the mono/skia pointer is verified against `{SKIA_BASE_SHA}` and
23+
- the paired Skia pointer is verified against `{SKIA_BASE_SHA}` and
2424
`origin/{SKIA_BASE_BRANCH}`; and
25-
- the mono/skia feature branch is created from that exact pointer.
25+
- the paired Skia feature branch is created from that exact pointer.
2626

2727
If either feature branch already exists, stop and inspect its base and commits. Reuse it only when
2828
it is the intended continuation; never reset or overwrite unrelated work.
@@ -102,7 +102,7 @@ Before committing:
102102
row names the revision and enabled/commented state actually present in the merged file.
103103
- Run `git diff --check` and confirm no unresolved paths remain.
104104

105-
Create the required two-parent merge commit. Verify its parents are the selected mono/skia base and
105+
Create the required two-parent merge commit. Verify its parents are the selected paired Skia base and
106106
the target upstream commit. Build-driven dependency or C API adaptations belong in later, separate
107107
commits after their need is proven.
108108

@@ -128,7 +128,7 @@ file counts alone.
128128

129129
## Gate
130130

131-
- Parent and mono/skia feature branches have the resolved bases.
131+
- Parent and paired Skia feature branches have the resolved bases.
132132
- The merge commit has exactly two parents.
133133
- Every fork patch and dependency difference is classified.
134134
- `audit_fork_patches.py --validate` passes with no provisional decisions.

.agents/skills/update-skia/references/phases/06-07-update-and-build.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ causes the helper to fail until you:
4242
A revision-only roll may retain the same semantic version, but still requires the final reviewed
4343
identity and source evidence. The helper rejects a manifest version bump when that dependency's
4444
DEPS identity did not change. It is idempotent; rerun it after every final DEPS/native adaptation
45-
and after the final mono/skia fix commit so the parent records the exact tested state.
45+
and after the final paired Skia fix commit so the parent records the exact tested state.
4646
Every tracked registration, including an unchanged legacy entry, must have non-empty
4747
`version_source` evidence. Backfill missing `skia_dependency` evidence from the hydrated source so
4848
supported branches become compliant over time without changing semantic versions unnecessarily.
@@ -101,10 +101,10 @@ affected platform's `native/**/build.cake` and must be reported for cross-platfo
101101
When evidence disproves an earlier dependency or risk conclusion, update
102102
`skia-dependency-decisions.md`, `skia-breaking-change-analysis.md`, and the validation-review
103103
disposition together by replacing the provisional entry; do not append a contradictory "final"
104-
section. Commit each proven post-merge dependency/C API adaptation in mono/skia as a separate
104+
section. Commit each proven post-merge dependency/C API adaptation in the paired Skia repository as a separate
105105
explanatory commit.
106106

107-
After every mono/skia adaptation, rerun `audit_fork_patches.py` with the Phase 05 arguments. Fill
107+
After every paired Skia adaptation, rerun `audit_fork_patches.py` with the Phase 05 arguments. Fill
108108
new or changed rows and require `--validate` to pass again. Reuse the exact Phase 05
109109
`python3 "${SKIA_SYNC_SKILL_DIR:-.agents/skills/update-skia}/scripts/audit_fork_patches.py"`
110110
command rather than searching

.agents/skills/update-skia/references/phases/08-10-bindings-and-tests.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -114,9 +114,9 @@ rm -f "$ARTIFACT_DIR/test-exit-code.txt"
114114
### Final deterministic reconciliation
115115

116116
After the final full solution passes, complete every deterministic gate against the exact tested
117-
mono/skia tree before moving to Phase 11:
117+
paired Skia tree before moving to Phase 11:
118118

119-
1. Ensure every post-merge mono/skia adaptation is committed and the worktree is clean.
119+
1. Ensure every post-merge paired Skia adaptation is committed and the worktree is clean.
120120
2. From the parent root, run the metadata finalizer:
121121

122122
```bash
@@ -126,7 +126,7 @@ mono/skia tree before moving to Phase 11:
126126

127127
If it fails, reconcile every `skia-dependency-changes.json` row with checked-out source,
128128
`cgmanifest.json`, and `skia-dependency-decisions.md`, then rerun until it passes.
129-
3. Refresh the fork audit against the **current final mono/skia HEAD**:
129+
3. Refresh the fork audit against the **current final paired Skia HEAD**:
130130

131131
```bash
132132
python3 "${SKIA_SYNC_SKILL_DIR:-.agents/skills/update-skia}/scripts/audit_fork_patches.py" \
@@ -144,12 +144,12 @@ mono/skia tree before moving to Phase 11:
144144
4. Confirm `skia-dependency-changes.json`, `cgmanifest.json`, and
145145
`skia-dependency-decisions.md` agree on every changed URL/SHA, semantic version, version source,
146146
and manifest action.
147-
5. Confirm `skia-fork-patch-audit.md` has no `TODO` and describes the exact current mono/skia HEAD.
147+
5. Confirm `skia-fork-patch-audit.md` has no `TODO` and describes the exact current paired Skia HEAD.
148148
6. Commit version, binding, wrapper, test, and submodule changes in the parent.
149149
7. Verify no build-time side effects or unrelated files are staged.
150-
8. Verify the parent gitlink equals the mono/skia commit used by the green run.
150+
8. Verify the parent gitlink equals the paired Skia commit used by the green run.
151151

152-
Any subsequent mono/skia or dependency change invalidates this reconciliation: return to step 1.
152+
Any subsequent paired Skia or dependency change invalidates this reconciliation: return to step 1.
153153
Do not read Phase 11 until both commands above pass against final state.
154154

155155
## Gate
@@ -158,8 +158,8 @@ Do not read Phase 11 until both commands above pass against final state.
158158
- No required native function lacks a managed decision.
159159
- Final unfiltered solution passes every host.
160160
- Every `GpuPolicy`-required backend initializes and executes with zero failures.
161-
- Parent points to the exact tested mono/skia commit.
161+
- Parent points to the exact tested paired Skia commit.
162162
- The deterministic dependency metadata gate passes with source-backed version verification for
163163
every tracked DEPS change and no version-only manifest drift.
164-
- `audit_fork_patches.py --validate` passes against final mono/skia HEAD, and every final fork-delta
164+
- `audit_fork_patches.py --validate` passes against final paired Skia HEAD, and every final fork-delta
165165
change has one non-contradictory evidence-backed disposition.

.agents/skills/update-skia/references/phases/11-11-ship.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ template:
99

1010
| Repository | Head | Base |
1111
|---|---|---|
12-
| mono/skia | `{HEAD_BRANCH}` | `{SKIA_BASE_BRANCH}` |
13-
| mono/SkiaSharp | `{HEAD_BRANCH}` | `{BASE_BRANCH}` |
12+
| Paired Skia repository | `{HEAD_BRANCH}` | `{SKIA_BASE_BRANCH}` |
13+
| Current SkiaSharp repository | `{HEAD_BRANCH}` | `{BASE_BRANCH}` |
1414

1515
Cross-link the PRs and include:
1616

@@ -55,7 +55,7 @@ PR. Do not call `noop`: a started automation run either completes this contract
5555

5656
Do not merge without explicit approval.
5757

58-
1. Merge mono/skia first.
58+
1. Merge the paired Skia PR first.
5959
2. Fetch the resulting commit on `{SKIA_BASE_BRANCH}`.
6060
3. Update the parent PR's submodule pointer to that branch commit.
6161
4. Wait for parent CI.

.agents/skills/update-skia/references/typical-changes.md

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,22 @@
22

33
| Repository | File | Change |
44
|-----------|------|--------|
5-
| mono/skia | `BUILD.gn` | Merge conflict resolution (most complex) |
6-
| mono/skia | `DEPS` | Merge conflict resolution |
7-
| mono/skia | `include/core/SkMilestone.h` | New milestone number (from upstream) |
8-
| mono/skia | `include/c/sk_types.h` | Enum/type updates, `SK_C_INCREMENT` reset |
9-
| mono/skia | `src/c/*.cpp` | C API fixes for new C++ APIs |
10-
| mono/skia | `src/c/sk_enums.cpp` | Enum mapping updates |
11-
| mono/skia | `src/c/sk_types_priv.h` | Include path + type conversion updates |
12-
| mono/SkiaSharp | `.gitmodules` | Submodule branch name |
13-
| mono/SkiaSharp | `externals/skia` | Submodule pointer |
14-
| mono/SkiaSharp | `scripts/VERSIONS.txt` | All version numbers |
15-
| mono/SkiaSharp | `cgmanifest.json` | Security tracking |
16-
| mono/SkiaSharp | `scripts/azure-templates-variables.yml` | CI config (`SKIASHARP_VERSION`) |
17-
| mono/SkiaSharp | `native/*/build.cake` | Per-platform GN flag updates (check for removed declare_args) |
18-
| mono/SkiaSharp | `binding/SkiaSharp/SkiaApi.generated.cs` | Regenerated |
19-
| mono/SkiaSharp | `binding/SkiaSharp/Definitions.cs` | Type definitions, new enums |
20-
| mono/SkiaSharp | `binding/SkiaSharp/EnumMappings.cs` | Enum mappings |
21-
| mono/SkiaSharp | `binding/SkiaSharp/GRDefinitions.cs` | GPU type changes |
22-
| mono/SkiaSharp | `binding/libSkiaSharp.json` | Type config |
23-
| mono/SkiaSharp | `tests/Tests/SkiaSharp/*.cs` | Test updates |
5+
| Paired Skia repository | `BUILD.gn` | Merge conflict resolution (most complex) |
6+
| Paired Skia repository | `DEPS` | Merge conflict resolution |
7+
| Paired Skia repository | `include/core/SkMilestone.h` | New milestone number (from upstream) |
8+
| Paired Skia repository | `include/c/sk_types.h` | Enum/type updates, `SK_C_INCREMENT` reset |
9+
| Paired Skia repository | `src/c/*.cpp` | C API fixes for new C++ APIs |
10+
| Paired Skia repository | `src/c/sk_enums.cpp` | Enum mapping updates |
11+
| Paired Skia repository | `src/c/sk_types_priv.h` | Include path + type conversion updates |
12+
| Current SkiaSharp repository | `.gitmodules` | Submodule branch name |
13+
| Current SkiaSharp repository | `externals/skia` | Submodule pointer |
14+
| Current SkiaSharp repository | `scripts/VERSIONS.txt` | All version numbers |
15+
| Current SkiaSharp repository | `cgmanifest.json` | Security tracking |
16+
| Current SkiaSharp repository | `scripts/azure-templates-variables.yml` | CI config (`SKIASHARP_VERSION`) |
17+
| Current SkiaSharp repository | `native/*/build.cake` | Per-platform GN flag updates (check for removed declare_args) |
18+
| Current SkiaSharp repository | `binding/SkiaSharp/SkiaApi.generated.cs` | Regenerated |
19+
| Current SkiaSharp repository | `binding/SkiaSharp/Definitions.cs` | Type definitions, new enums |
20+
| Current SkiaSharp repository | `binding/SkiaSharp/EnumMappings.cs` | Enum mappings |
21+
| Current SkiaSharp repository | `binding/SkiaSharp/GRDefinitions.cs` | GPU type changes |
22+
| Current SkiaSharp repository | `binding/libSkiaSharp.json` | Type config |
23+
| Current SkiaSharp repository | `tests/Tests/SkiaSharp/*.cs` | Test updates |

.agents/skills/update-skia/scripts/audit_fork_patches.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#!/usr/bin/env python3
22

3-
"""Audit mono/skia fork-patch integrity during Phases 05 and 10.
3+
"""Audit paired Skia fork-patch integrity during Phases 05 and 10.
44
55
The upstream merge may silently drop or alter a fork patch without producing a
66
conflict. This helper compares the old and new upstream-relative fork deltas,
@@ -252,7 +252,7 @@ def validate(
252252

253253
def main() -> int:
254254
parser = argparse.ArgumentParser(
255-
description="Audit old and new mono/skia fork deltas and validate dispositions."
255+
description="Audit old and new paired Skia fork deltas and validate dispositions."
256256
)
257257
parser.add_argument("--skia-root", type=Path, default=Path("externals/skia"))
258258
parser.add_argument("--old-upstream", required=True)

0 commit comments

Comments
 (0)