Skip to content

Commit d48d38e

Browse files
yamcodesCopilot
andcommitted
fix: derive Renovate example exclusions from metadata
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
1 parent 393d2c9 commit d48d38e

3 files changed

Lines changed: 72 additions & 10 deletions

File tree

.github/renovate.json

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -54,19 +54,23 @@
5454
},
5555
// By Package Manager
5656
{
57-
// Disable the whole sync-generated example tree so new examples are covered
58-
// automatically without updating this list every time.
57+
// Generated from apps/playgrounds/*/package.json arkenvExamples metadata.
5958
"description": "Disable sync-generated example apps",
60-
"matchFileNames": ["examples/**"],
61-
"enabled": false
62-
},
63-
{
64-
"description": "Allow hand-maintained examples to keep updating via the pnpm group",
6559
"matchFileNames": [
66-
"examples/with-zod/**",
67-
"examples/with-valibot/**"
60+
// BEGIN GENERATED SYNC EXAMPLES
61+
"examples/basic/**",
62+
"examples/basic-js/**",
63+
"examples/with-bun/**",
64+
"examples/with-bun-react/**",
65+
"examples/with-nextjs/**",
66+
"examples/with-nextjs-strict/**",
67+
"examples/with-nuxt/**",
68+
"examples/with-solid-start/**",
69+
"examples/with-standard-schema/**",
70+
"examples/with-vite-react/**"
71+
// END GENERATED SYNC EXAMPLES
6872
],
69-
"enabled": true
73+
"enabled": false
7074
},
7175
{
7276
// Group pnpm workspace updates (minor/patch) across selected dirs

scripts/sync-examples.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import { existsSync, readdirSync, readFileSync } from "node:fs";
1717
import { basename, join } from "node:path";
1818
import { argv } from "node:process";
1919
import { PLAYGROUNDS_DIR } from "./sync-lib/constants.js";
20+
import { syncRenovateConfig } from "./sync-lib/renovate.js";
2021
import { syncPlayground } from "./sync-lib/sync.js";
2122
import { parseCatalog } from "./sync-lib/workspace.js";
2223

@@ -39,6 +40,7 @@ function main() {
3940
.map((d) => join(PLAYGROUNDS_DIR, d.name));
4041

4142
let hasChanges = false;
43+
const generatedExampleNames = [];
4244

4345
for (const playgroundPath of playgroundDirs) {
4446
const pkgPath = join(playgroundPath, "package.json");
@@ -65,6 +67,7 @@ function main() {
6567
continue;
6668
}
6769

70+
generatedExampleNames.push(exampleConfig.name);
6871
const changes = syncPlayground(
6972
playgroundPath,
7073
exampleConfig,
@@ -82,6 +85,11 @@ function main() {
8285
}
8386
}
8487

88+
if (syncRenovateConfig(generatedExampleNames, checkOnly)) {
89+
hasChanges = true;
90+
console.log("\n ✗ Renovate config is out of sync with playground metadata.");
91+
}
92+
8593
if (checkOnly) {
8694
if (hasChanges) {
8795
console.log("\n❌ Examples are out of sync with playgrounds.");

scripts/sync-lib/renovate.js

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import { readFileSync, writeFileSync } from "node:fs";
2+
import { join } from "node:path";
3+
import { ROOT_DIR } from "./constants.js";
4+
5+
const RENOVATE_CONFIG_PATH = join(ROOT_DIR, ".github", "renovate.json");
6+
const START_MARKER = "// BEGIN GENERATED SYNC EXAMPLES";
7+
const END_MARKER = "// END GENERATED SYNC EXAMPLES";
8+
9+
function generatedMatchFileNames(exampleNames) {
10+
return [
11+
`\t\t\t${START_MARKER}`,
12+
...exampleNames.flatMap((name, index) => [
13+
`\t\t\t\t"examples/${name}/**"${index === exampleNames.length - 1 ? "" : ","}`,
14+
]),
15+
`\t\t\t${END_MARKER}`,
16+
].join("\n");
17+
}
18+
19+
/**
20+
* Keep Renovate's generated-example exclusion in sync with playground metadata.
21+
*/
22+
export function syncRenovateConfig(exampleNames, checkOnly = false) {
23+
const content = readFileSync(RENOVATE_CONFIG_PATH, "utf8");
24+
const markerStart = content.indexOf(START_MARKER);
25+
const start = content.lastIndexOf("\n", markerStart) + 1;
26+
const end = content.indexOf(END_MARKER);
27+
28+
if (markerStart === -1 || end === -1 || end < start) {
29+
throw new Error(
30+
`Renovate config must contain ${START_MARKER} and ${END_MARKER}`,
31+
);
32+
}
33+
34+
const generated = generatedMatchFileNames([...new Set(exampleNames)].sort());
35+
const current = content.slice(start, end + END_MARKER.length);
36+
const updated =
37+
content.slice(0, start) +
38+
generated +
39+
content.slice(end + END_MARKER.length);
40+
41+
if (checkOnly) {
42+
return current !== generated;
43+
}
44+
45+
if (current !== generated) {
46+
writeFileSync(RENOVATE_CONFIG_PATH, updated);
47+
}
48+
49+
return false;
50+
}

0 commit comments

Comments
 (0)