Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .changeset/nice-moments-prove.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
---
---
2 changes: 2 additions & 0 deletions .changeset/quiet-pins-start.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
---
---
2 changes: 2 additions & 0 deletions .changeset/steady-pins-restart.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
---
---
10 changes: 5 additions & 5 deletions .claude/skills/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ relevant.

## Skills in this repo

| Skill | Use it for |
| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| `clerk-monorepo` | Day-to-day work in the monorepo: setup, build/test loops, the package map, changesets, commits, PRs, breaking-change checks. |
| `mosaic` | Mosaic flow UI: authoring machines, controllers, and views, and migrating a legacy component into the split (with parity verification). |
| `verify-clerk-expo` | Proving a `@clerk/expo` change on an iOS simulator or Android emulator, local or borrowed on a CI runner, with video and screenshots as evidence. |
| Skill | Use it for |
| ------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| `clerk-monorepo` | Day-to-day work in the monorepo: setup, build/test loops, the package map, changesets, commits, PRs, breaking-change checks. |
| `mosaic` | Mosaic flow UI: authoring machines, controllers, and views, and migrating a legacy component into the split (with parity verification). |
| `verify-clerk-expo` | Proving a `@clerk/expo` change on an iOS simulator or Android emulator, local or borrowed on a CI runner, with a video or screenshots as evidence. |
4 changes: 2 additions & 2 deletions .claude/skills/verify-clerk-expo/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ $ integration/expo-native/bin/control-clerk-expo attach <run-id> --pr <n> --vide

`attach` posts what you choose, and with neither `--screenshot` nor `--video` it fails with a usage error. Make two choices.

Choose screenshots or the video by what changed, and post one kind. A change to behavior, to movement or animation, or to a flow shows in a video, so pass `--video`: one before and after video for each change, and no screenshots beside it. A still change, such as wording or a layout, shows in screenshots, so pass `--screenshot <label>` once for each screen the change touches, each with its before. `attach` refuses both flags together unless you add `--both`, which is for the rare change a reviewer cannot see in one kind alone.
Choose screenshots or the video by what changed, and post one kind. A change to behavior, to movement or animation, or to a flow shows in a video, so pass `--video`: one video for each change, with its before when the flow already exists, and no screenshots beside it. A still change, such as wording or a layout, shows in screenshots, so pass `--screenshot <label>` once for each screen the change touches, each with its before when the screen already exists. Never post both kinds, and `attach` refuses `--video` with `--screenshot`. When a brief, a prompt or a reviewer asks for both, post the one kind the change calls for, and say in your hand-back that you did and why.

A video shows only the part of the run that you mark. Wrap the steps that show the change in `host.evidence`, and leave sign-in, seeding and navigation outside it:

Expand All @@ -234,7 +234,7 @@ For screenshots, show each screen the change touches, and each state of a screen

Some states are out of reach for a test user on the standard settings with the default roles. Try a settings file for the spec, or test data that the spec seeds, first. When neither reaches it, force the state with a small local patch to the build. Never commit or push the patch. Put the same patch on the before build and the after build, and run both on a local device, because `attach` refuses a run on a session build with uncommitted changes. In the pull request, say exactly what the patch changed and why no test user could reach the state without it.

`attach` puts the files in the description of the pull request with `gh pr edit --attach`. It writes one block for the platform of the run, between the comments `<!-- verify-evidence:ios -->` and `<!-- /verify-evidence:ios -->`, or the same two with `android`. The block is a line and one or two tables. The line leads with the result and names the run, the device, the commit, and how many tests passed. With `--before` it also names the before run, its commit, and how many of its tests passed. With `--before`, a table has a `Before` and an `After` column and one row for each screenshot. Without it, the screenshots are two across, each under its label in code font. Each screenshot is 280 pixels wide. The video is in a table of its own under the screenshots.
`attach` puts the files in the description of the pull request with `gh pr edit --attach`. It writes one block for the platform of the run, between the comments `<!-- verify-evidence:ios -->` and `<!-- /verify-evidence:ios -->`, or the same two with `android`. The block is a line and then one or more tables. The line leads with the result and names the run, the device, the commit, and how many tests passed. With `--before` it also names the before run, its commit, and how many of its tests passed. With `--before`, one table has a `Before` and an `After` column, and a row for each screenshot or one row for the video. Without it, the screenshots are two across, each under its label in code font, and the video is alone in a table under its name. Each screenshot is 280 pixels wide.

The first `attach` of a platform adds its block after the description. A later `attach` of that platform replaces its block, so the description holds the latest run of each platform and the media does not pile up. `attach` changes nothing outside the block. Keep both comments of a block or remove both: `attach` refuses a description that has one without the other, or either one twice. A comment counts only when it is a whole line outside a code fence, so a description can quote one in a sentence or show a whole block as an example.

Expand Down
6 changes: 3 additions & 3 deletions integration/expo-native/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion integration/expo-native/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"typecheck": "tsc -p ."
},
"devDependencies": {
"@clerk/internal-mobile-e2e": "github:clerk/internal-mobile-e2e#ad396e6014ad86cd3d29e58933c75ab59905b7ab",
"@clerk/internal-mobile-e2e": "github:clerk/internal-mobile-e2e#882bf691eabba1e1d30bfe525544f5659c708f95",
"@types/node": "24.19.1",
"typescript": "7.0.2"
},
Expand Down
37 changes: 15 additions & 22 deletions scripts/verify-attach.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -432,35 +432,28 @@ function mediaTables(files, hasBefore, uploaded) {
const label = stem(name);
const cell = (url, alt) => (isVideo(name) ? url : `<img src="${url}" width="${IMAGE_WIDTH}" alt="${alt}">`);
return {
video: isVideo(name),
label,
after: cell(uploaded[at], hasBefore ? `After: ${label}` : label),
before: hasBefore ? cell(uploaded[files.length + at], `Before: ${label}`) : '',
};
});
return [false, true].flatMap(video => {
const some = shown.filter(item => item.video === video);
if (some.length === 0) {
return [];
}
if (hasBefore) {
return [
table(
['Before', 'After'],
some.map(item => [item.before, item.after]),
),
];
}
const rows = Array.from({ length: Math.ceil(some.length / ACROSS) }, (_, row) =>
some.slice(row * ACROSS, (row + 1) * ACROSS),
);
return rows.map(row =>
if (hasBefore) {
return [
table(
row.map(item => `\`${item.label}\``),
[row.map(item => item.after)],
['Before', 'After'],
shown.map(item => [item.before, item.after]),
),
);
});
];
}
const rows = Array.from({ length: Math.ceil(shown.length / ACROSS) }, (_, row) =>
shown.slice(row * ACROSS, (row + 1) * ACROSS),
);
return rows.map(row =>
table(
row.map(item => `\`${item.label}\``),
[row.map(item => item.after)],
),
);
}

// `gh pr edit --attach` rewrites only a markdown reference to a file, so the files go up as a list first, and the tables are written from the addresses GitHub gave them.
Expand Down
22 changes: 7 additions & 15 deletions scripts/verify-attach.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -1289,13 +1289,9 @@ describe('the step that edits the description', () => {
['<!-- verify-evidence:ios -->', '', ...lines, '', '<!-- /verify-evidence:ios -->'].join('\n');
const AFTER_ONLY = [
'',
'| `profile` |',
'| :---: |',
`| <img src="${asset(2)}" width="280" alt="profile"> |`,
'',
'| `video` |',
'| :---: |',
`| ${asset(1)} |`,
'| `video` | `profile` |',
'| :---: | :---: |',
`| ${asset(1)} | <img src="${asset(2)}" width="280" alt="profile"> |`,
];

it('adds the block after the description and attaches the files from their own directory, under names the description could not have guessed', async () => {
Expand Down Expand Up @@ -1494,22 +1490,18 @@ describe('the step that edits the description', () => {
assert.equal(await published(CLIP), laidOut(SAID, '', '| `video` |', '| :---: |', `| ${asset(1)} |`));
});

it('lays out both kinds when the hand-off holds both: the screenshots first, then the video, each as it is alone', async () => {
it('lays out a hand-off that holds both kinds with a before as one Before and After table, in the order of the manifest', async () => {
assert.equal(
await published([...CLIP, ...SHOT], [...WAS_CLIP, ...WAS_SHOT]),
laidOut(
`${SAID}${WAS}`,
'',
'| Before | After |',
'| :---: | :---: |',
`| <img src="${asset(4)}" width="280" alt="Before: profile"> | <img src="${asset(2)}" width="280" alt="After: profile"> |`,
'',
'| Before | After |',
'| :---: | :---: |',
`| ${asset(3)} | ${asset(1)} |`,
`| <img src="${asset(4)}" width="280" alt="Before: profile"> | <img src="${asset(2)}" width="280" alt="After: profile"> |`,
),
);
assert.equal(await published([...CLIP, ...SHOT]), laidOut(SAID, ...AFTER_ONLY));
});

const ASCII = Array.from({ length: 128 }, (_, code) => String.fromCharCode(code));
Comment thread
mikepitre marked this conversation as resolved.
Expand Down Expand Up @@ -1732,7 +1724,7 @@ describe('the step that edits the description', () => {
);
assert.match(
fake.state.laidOutBody,
/, 3 of 3 passed\. The pull request has newer commits\.\r\n\r\n\| `profile` \|/,
/, 3 of 3 passed\. The pull request has newer commits\.\r\n\r\n\| `video` \| `profile` \|/,
);
});

Expand Down Expand Up @@ -1764,7 +1756,7 @@ describe('the step that edits the description', () => {
);
assert.match(
fake.state.laidOutBody,
/, 3 of 3 passed\. The pull request has newer commits\.\r\n\r\n\| `profile` \|/,
/, 3 of 3 passed\. The pull request has newer commits\.\r\n\r\n\| `video` \| `profile` \|/,
);
});

Expand Down
Loading