-
Notifications
You must be signed in to change notification settings - Fork 0
136 lines (111 loc) · 4.87 KB
/
aggregate-docs.yml
File metadata and controls
136 lines (111 loc) · 4.87 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
name: Aggregate Docs
on:
push:
branches: [main]
repository_dispatch:
types: [docs-updated]
schedule:
- cron: '0 0 * * *'
workflow_dispatch:
concurrency:
group: aggregate-docs
cancel-in-progress: true
permissions:
contents: write
jobs:
aggregate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/github-script@v8
name: Aggregate docs from source repos
env:
PUSH_TOKEN: ${{ secrets.DOCS_TOKEN }}
with:
script: |
const fs = require('fs');
const path = require('path');
// Read config files
const repos = JSON.parse(fs.readFileSync('repos.json', 'utf8'));
const docsConfig = JSON.parse(fs.readFileSync('docs.json', 'utf8'));
// Reset products array (start fresh each run)
docsConfig.navigation.products = [];
// Helper to recursively copy a directory's contents
const copyContents = (src, dest) => {
for (const entry of fs.readdirSync(src, { withFileTypes: true })) {
if (entry.name === 'docs.json' || entry.name === 'assets') continue;
const srcPath = path.join(src, entry.name);
const destPath = path.join(dest, entry.name);
if (entry.isDirectory()) {
fs.mkdirSync(destPath, { recursive: true });
copyContents(srcPath, destPath);
} else {
fs.cpSync(srcPath, destPath);
}
}
};
// Process each source repo
for (const { owner, repo, docsPath = 'docs', ref = 'main' } of repos) {
core.startGroup(`Processing ${owner}/${repo}`);
const cloneDir = path.join(process.env.RUNNER_TEMP, 'repos', repo);
await io.rmRF(cloneDir);
// Clone the repo (shallow, specific branch)
await exec.exec('git', [
'clone', '--depth=1', '--branch', ref,
`https://x-access-token:${process.env.PUSH_TOKEN}@github.com/${owner}/${repo}.git`,
cloneDir
]);
const sourceDir = path.join(cloneDir, docsPath);
const sourceConfig = path.join(sourceDir, 'docs.json');
if (!fs.existsSync(sourceConfig)) {
core.warning(`No docs.json found in ${owner}/${repo}/${docsPath}, skipping`);
core.endGroup();
continue;
}
// Read the source repo's docs.json and merge navigation.products
const subConfig = JSON.parse(fs.readFileSync(sourceConfig, 'utf8'));
const subProducts = subConfig.navigation?.products ?? [];
docsConfig.navigation.products.push(...subProducts);
// Determine which content directories this repo owns
// (e.g., json-schema/ contains json-schema/introduction.mdx, etc.)
// We look at the top-level entries in the source docs folder
// (excluding docs.json and assets) and sync only those into the working tree
const sourceEntries = fs.readdirSync(sourceDir, { withFileTypes: true })
.filter(e => e.name !== 'docs.json' && e.name !== 'assets');
// Remove the old version of this repo's content directories
for (const entry of sourceEntries) {
const target = path.join('.', entry.name);
if (fs.existsSync(target)) {
await io.rmRF(target);
}
}
// Copy fresh content from the source repo
copyContents(sourceDir, '.');
core.endGroup();
}
// Update docs.json with merged navigation (preserving all other fields)
fs.writeFileSync(
'docs.json',
JSON.stringify(docsConfig, null, 4) + '\n'
);
core.info(`Aggregated ${docsConfig.navigation.products.length} product(s)`);
// Commit and push to main (if anything changed)
await exec.exec('git', ['add', '.']);
let hasChanges = false;
try {
await exec.exec('git', ['diff', '--cached', '--quiet']);
} catch {
hasChanges = true;
}
if (!hasChanges) {
core.info('No changes detected, skipping commit');
return;
}
await exec.exec('git', ['config', 'user.name', 'github-actions[bot]']);
await exec.exec('git', [
'config', 'user.email',
'github-actions[bot]@users.noreply.github.com'
]);
await exec.exec('git', ['commit', '-m', 'docs: aggregate from source repos']);
await exec.exec('git', ['push']);
core.info('Docs aggregated and pushed successfully');