Skip to content

Commit 51e7374

Browse files
authored
Split API reference into separate TypeDoc manuals (#32)
* Removed git submodules and switched to direct repository cloning * Remove repos directory from git tracking and add to .gitignore * Update page styles for root page * Improve header nav bar * Update deployment action * Update README * Update README * Update README * Remove unused files
1 parent 16fa2d9 commit 51e7374

18 files changed

+1131
-637
lines changed

.github/workflows/deploy.yml

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
1-
name: "typedoc"
1+
name: "Build and Deploy API Reference"
22

33
on:
44
workflow_dispatch:
55
push:
66
branches: [main]
7+
paths-ignore:
8+
- "README.md"
9+
- "LICENSE"
10+
- ".gitignore"
711

812
permissions:
913
contents: read
@@ -14,25 +18,36 @@ jobs:
1418
build:
1519
runs-on: ubuntu-latest
1620
steps:
17-
- uses: actions/checkout@v4
21+
- name: Checkout repository
22+
uses: actions/checkout@v4
23+
24+
- name: Setup Node.js
25+
uses: actions/setup-node@v4
1826
with:
19-
submodules: true
20-
- uses: actions/setup-node@v4
21-
- run: npm ci
22-
# Generate your TypeDoc documentation
23-
- run: npm run build
24-
# https://github.com/actions/upload-pages-artifact
25-
- uses: actions/upload-pages-artifact@v3
27+
node-version: '18'
28+
cache: 'npm'
29+
30+
- name: Install dependencies
31+
run: npm ci
32+
33+
- name: Build API Reference
34+
run: npm run build
35+
36+
- name: Setup Pages
37+
uses: actions/configure-pages@v4
38+
39+
- name: Upload artifact
40+
uses: actions/upload-pages-artifact@v3
2641
with:
27-
path: ./docs # This should be your TypeDoc "out" path.
42+
path: ./docs
43+
2844
deploy:
29-
runs-on: ubuntu-latest
3045
environment:
3146
name: github-pages
3247
url: ${{ steps.deployment.outputs.page_url }}
48+
runs-on: ubuntu-latest
3349
needs: build
3450
steps:
3551
- name: Deploy to GitHub Pages
3652
id: deployment
37-
# https://github.com/actions/deploy-pages
3853
uses: actions/deploy-pages@v4

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
docs/
22
node_modules/
3-
.npmrc
3+
.npmrc
4+
repos/

.gitmodules

Lines changed: 0 additions & 18 deletions
This file was deleted.

README.md

Lines changed: 65 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,88 @@
11
# PlayCanvas API Reference
22

3-
This repository builds the [PlayCanvas API Reference](https://api.playcanvas.com/). It is built using [TypeDoc](https://typedoc.org/).
3+
This repository builds the combined PlayCanvas API Reference. The API reference is a collection of documentation from multiple PlayCanvas repositories.
44

5-
## Installation
5+
## Requirements
66

77
Ensure you have Node.js 18+ installed.
88

9-
After cloning the repo, initialize the submodules:
9+
## Configuration
1010

11-
git submodule init
12-
git submodule update --remote
11+
Repository configuration is stored in `repos-config.json`. This file defines the repositories to be cloned, their URLs, and default branches:
1312

14-
Then install all NPM dependencies:
13+
```json
14+
{
15+
"repositories": [
16+
{
17+
"name": "engine",
18+
"url": "https://github.com/playcanvas/engine.git",
19+
"branch": "main"
20+
},
21+
...
22+
]
23+
}
24+
```
1525

16-
npm install
26+
You can modify this file to change default branches, add new repositories, or remove existing ones.
1727

18-
## Building
28+
## Building the API Reference
1929

20-
To build the API reference manual locally, run:
30+
To build the combined API reference, run:
2131

22-
npm run build
32+
```bash
33+
npm run build
34+
```
2335

24-
The manual will be output to the `docs` folder.
36+
This cross-platform script will:
2537

26-
## Viewing
38+
1. Load the repository configuration from `repos-config.json`
39+
2. Clone the configured PlayCanvas repositories
40+
3. Install dependencies for each repository
41+
4. Build the TypeDoc documentation for each repository
42+
5. Copy the documentation to a central `docs` folder
43+
6. Create a main index.html file that allows navigation between the different API references
2744

28-
To view the build manual, run:
45+
> [!NOTE]
46+
> The build script automatically cleans and recreates the `repos` directory each time it's run, ensuring you always get a fresh build with the latest code from the configured branches.
2947
30-
npm run serve
48+
### Specifying Repository Branches
3149

32-
Then point your browser at `http://localhost:3000`.
50+
The default branches for all repositories are defined in the `repos-config.json` file. This is the recommended place to set your branch configurations:
51+
52+
```json
53+
{
54+
"repositories": [
55+
{
56+
"name": "engine",
57+
"url": "https://github.com/playcanvas/engine.git",
58+
"branch": "release-2.6"
59+
},
60+
// ... other repositories
61+
]
62+
}
63+
```
64+
65+
For temporary changes without modifying the configuration file, you can override branches using command-line arguments in the format `repo=branch`:
66+
67+
```bash
68+
# Override the engine branch for a single build
69+
npm run build engine=dev
3370

34-
## Updating Submodules
71+
# Override multiple repositories for a single build
72+
npm run build engine=dev pcui=feature/new-components
73+
```
3574

36-
To update any of the submodules to latest commit of the `main` branch, do:
75+
The repository names used in the command line must match the `name` fields in the `repos-config.json` file.
3776

38-
cd submodules
39-
cd engine (or pcui, pcui-graph, etc)
40-
git pull origin main
41-
cd ..
42-
cd ..
43-
git add submodules
44-
git commit -m "Updated submodule X to latest"
45-
git push
77+
## Viewing
78+
79+
To view the built API reference, run:
80+
81+
```bash
82+
npm run serve
83+
```
84+
85+
Then point your browser at `http://localhost:3000`.
4686

4787
## Deployment
4888

build.mjs

Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
#!/usr/bin/env node
2+
3+
import { execSync } from 'child_process';
4+
import fs from 'fs';
5+
import path from 'path';
6+
import { fileURLToPath } from 'url';
7+
8+
const __filename = fileURLToPath(import.meta.url);
9+
const __dirname = path.dirname(__filename);
10+
11+
// Load repository configuration from JSON file
12+
let REPOS = [];
13+
try {
14+
const configPath = path.join(__dirname, 'repos-config.json');
15+
const configData = JSON.parse(fs.readFileSync(configPath, 'utf8'));
16+
REPOS = configData.repositories;
17+
console.log(`Loaded ${REPOS.length} repositories from configuration file`);
18+
} catch (error) {
19+
console.error(`Error loading repository configuration: ${error.message}`);
20+
process.exit(1);
21+
}
22+
23+
/**
24+
* Parse command line arguments to override repository branches
25+
*/
26+
function parseBranchArgs() {
27+
const args = process.argv.slice(2);
28+
29+
// Process arguments in the format: repo=branch (e.g., engine=dev)
30+
for (const arg of args) {
31+
const match = arg.match(/^([^=]+)=(.+)$/);
32+
if (match) {
33+
const [, repoName, branchName] = match;
34+
const repo = REPOS.find(r => r.name === repoName);
35+
36+
if (repo) {
37+
console.log(`Setting custom branch for ${repoName}: ${branchName}`);
38+
repo.branch = branchName;
39+
} else {
40+
console.warn(`Warning: Unknown repository '${repoName}' specified in arguments`);
41+
}
42+
}
43+
}
44+
}
45+
46+
/**
47+
* Execute shell command and display the output
48+
*/
49+
function runCommand(command, options = {}) {
50+
console.log(`Running: ${command}`);
51+
return execSync(command, { stdio: 'inherit', ...options });
52+
}
53+
54+
/**
55+
* Delete directory if it exists
56+
*/
57+
function deleteDir(dir) {
58+
if (fs.existsSync(dir)) {
59+
console.log(`Removing existing directory: ${dir}`);
60+
fs.rmSync(dir, { recursive: true, force: true });
61+
}
62+
}
63+
64+
/**
65+
* Create directory if it doesn't exist
66+
*/
67+
function ensureDir(dir) {
68+
if (!fs.existsSync(dir)) {
69+
console.log(`Creating directory: ${dir}`);
70+
fs.mkdirSync(dir, { recursive: true });
71+
}
72+
}
73+
74+
/**
75+
* Copy directory contents recursively
76+
*/
77+
function copyDirContents(src, dest) {
78+
if (!fs.existsSync(src)) {
79+
console.log(`Source directory doesn't exist: ${src}`);
80+
return;
81+
}
82+
83+
ensureDir(dest);
84+
85+
const entries = fs.readdirSync(src, { withFileTypes: true });
86+
87+
for (const entry of entries) {
88+
const srcPath = path.join(src, entry.name);
89+
const destPath = path.join(dest, entry.name);
90+
91+
if (entry.isDirectory()) {
92+
copyDirContents(srcPath, destPath);
93+
} else {
94+
fs.copyFileSync(srcPath, destPath);
95+
}
96+
}
97+
}
98+
99+
/**
100+
* Main function to build the documentation
101+
*/
102+
async function buildDocs() {
103+
try {
104+
// Parse command line arguments for branch overrides
105+
parseBranchArgs();
106+
107+
// Create docs directory if it doesn't exist
108+
ensureDir('docs');
109+
110+
// Remove existing repos directory and create a new one
111+
deleteDir('repos');
112+
ensureDir('repos');
113+
114+
// Process each repository
115+
for (const repo of REPOS) {
116+
console.log(`\n========== Processing ${repo.name} (branch: ${repo.branch}) ==========`);
117+
118+
// Change to repos directory
119+
process.chdir(path.join(process.cwd(), 'repos'));
120+
121+
// Clone the repository with specified branch
122+
runCommand(`git clone -b ${repo.branch} ${repo.url} ${repo.name}`);
123+
124+
// Change to repository directory
125+
process.chdir(path.join(process.cwd(), repo.name));
126+
127+
// Install dependencies
128+
runCommand('npm install');
129+
130+
// Build documentation
131+
runCommand('npm run docs');
132+
133+
// Copy docs to the main docs directory if they exist
134+
const docsDir = path.join(process.cwd(), 'docs');
135+
if (fs.existsSync(docsDir)) {
136+
const targetDir = path.join(process.cwd(), '..', '..', 'docs', repo.name);
137+
console.log(`Copying docs from ${docsDir} to ${targetDir}`);
138+
ensureDir(targetDir);
139+
copyDirContents(docsDir, targetDir);
140+
}
141+
142+
// Return to root directory
143+
process.chdir(path.join(process.cwd(), '..', '..'));
144+
145+
console.log(`Completed processing ${repo.name}`);
146+
}
147+
148+
// Copy the index.html to the docs directory
149+
console.log('\nCopying index.html file...');
150+
const sourceIndexPath = path.join(__dirname, 'index.html');
151+
if (!fs.existsSync(sourceIndexPath)) {
152+
throw new Error(`Source index.html not found: ${sourceIndexPath}`);
153+
}
154+
fs.copyFileSync(sourceIndexPath, path.join('docs', 'index.html'));
155+
156+
// Copy favicon
157+
console.log('Copying favicon...');
158+
fs.copyFileSync('favicon.ico', path.join('docs', 'favicon.ico'));
159+
160+
// Copy assets directory if it exists
161+
if (fs.existsSync('assets')) {
162+
console.log('Copying assets directory...');
163+
ensureDir(path.join('docs', 'assets'));
164+
copyDirContents('assets', path.join('docs', 'assets'));
165+
}
166+
167+
console.log('\nDocumentation build complete. Run "npm run serve" to view it.');
168+
} catch (error) {
169+
console.error(`\nError: ${error.message}`);
170+
process.exit(1);
171+
}
172+
}
173+
174+
// Run the build process
175+
buildDocs();

0 commit comments

Comments
 (0)