Skip to content

Commit 044e9ce

Browse files
authored
fix(docs): source Spectrum docs from main (#108)
Refs ENG-1881
1 parent a889b84 commit 044e9ce

5 files changed

Lines changed: 36 additions & 20 deletions

File tree

.github/workflows/deploy-dist.yml

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ on:
44
push:
55
branches: [main]
66
repository_dispatch:
7-
types: [spectrum-cloud-release]
7+
types: [spectrum-cloud-release, spectrum-ts-docs]
88

99
jobs:
1010
deploy:
@@ -23,7 +23,9 @@ jobs:
2323
app-id: ${{ secrets.APP_ID }}
2424
private-key: ${{ secrets.APP_PRIVATE_KEY }}
2525
owner: ${{ steps.parse-repo.outputs.owner }}
26-
repositories: ${{ steps.parse-repo.outputs.name }}
26+
repositories: |
27+
${{ steps.parse-repo.outputs.name }}
28+
spectrum-ts
2729
2830
- uses: actions/checkout@v4
2931
with:
@@ -40,11 +42,10 @@ jobs:
4042

4143
- name: Generate docs from Vellum templates
4244
run: pnpm docs:generate
43-
# sync-docs pulls per-source docs at the tag matching the installed
44-
# package version. While a source still has a `local` fallback it stays
45-
# offline; once a source is git-only, widen the app token's
46-
# `repositories:` above to include that source repo so the clone can auth.
45+
# sync-docs pulls per-source authored docs from the configured git ref
46+
# while Vellum extracts types from the installed package versions.
4747
env:
48+
DOCS_SOURCE_MODE: git
4849
GITHUB_TOKEN: ${{ steps.app-token.outputs.token }}
4950

5051
- name: Push to dist branch

.github/workflows/typecheck-docs.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ jobs:
4141

4242
- name: Generate docs from Vellum templates
4343
run: pnpm docs:generate
44+
env:
45+
DOCS_SOURCE_MODE: git
4446

4547
- name: Typecheck documentation code blocks
4648
run: pnpm typecheck:docs

README.md

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,13 @@ This repo is an **aggregator**: some doc areas are authored here in [`docs-src/`
99
`scripts/sync-docs` assembles a single template tree (`.vellum-src/`, gitignored) before vellum runs, from two places:
1010

1111
- **Local** — most areas still live in [`docs-src/`](docs-src/) in this repo.
12-
- **Source repos** — areas listed in [`scripts/sources.json`](scripts/sources.json) are pulled from their SDK repo's `docs-site/` directory, at the git tag matching the installed package version (so prose stays aligned with the types vellum extracts). Edit those in the SDK repo, not here. Until a source repo has its `docs-site/`, sync falls back to the `local` path in the manifest, so the pilot keeps building offline.
12+
- **Source repos** — areas listed in [`scripts/sources.json`](scripts/sources.json) are pulled from their SDK repo's configured docs directory, at the configured git ref. For Spectrum, that is `photon-hq/spectrum-ts` `main` and the `docs/` directory, so prose fixes can ship without an SDK release. Vellum still extracts types from the installed package versions in this repo, so source-repo docs must stay compatible with the released package. Edit those docs in the SDK repo, not here. Local builds can use the `local` fallback in the manifest, but CI and deploy use `DOCS_SOURCE_MODE=git`.
1313

1414
Navigation works the same way: [`docs.json`](docs.json) is **generated** by `scripts/build-nav` from [`docs.base.json`](docs.base.json) (the site skeleton) plus a `nav.json` fragment contributed by each source. Don't edit `docs.json` directly — edit `docs.base.json` or the fragment.
1515

1616
## How to edit
1717

18-
1. **Edit the source, not the output.** Sources are `.mdx.vel` files in [`docs-src/`](docs-src/) (this repo) or a source repo's `docs-site/`. The rendered `.mdx` files and `docs.json` at the repo root are build artifacts — gitignored on `main`, only present on the `dist` branch. Don't edit them directly; they get overwritten on every deploy.
18+
1. **Edit the source, not the output.** Sources are `.mdx.vel` files in [`docs-src/`](docs-src/) (this repo) or the source repo docs directory configured in [`scripts/sources.json`](scripts/sources.json). The rendered `.mdx` files and `docs.json` at the repo root are build artifacts — gitignored on `main`, only present on the `dist` branch. Don't edit them directly; they get overwritten on every deploy.
1919

2020
2. **Render and preview locally:**
2121

@@ -42,9 +42,13 @@ Push to `main` → [.github/workflows/deploy-dist.yml](.github/workflows/deploy-
4242

4343
The Spectrum API reference is generated from a remote OpenAPI spec configured in [docs.json](docs.json), fetched at build time, so every rebuild picks up the latest API surface without a docs commit.
4444

45+
Source-repo doc updates can also trigger deploy through `repository_dispatch` type `spectrum-ts-docs`. Use that when `photon-hq/spectrum-ts` changes `docs/**` without a package release.
46+
4547
## Auto-updates from SDK releases
4648

47-
When a connected SDK ships a release (e.g., [`spectrum-ts`](https://github.com/photon-hq/spectrum-ts), [`advanced-imessage-ts`](https://github.com/photon-hq/advanced-imessage-ts)), its release workflow calls [`photon-hq/buildspace/.github/workflows/update-docs.yaml`](https://github.com/photon-hq/buildspace/blob/main/.github/workflows/update-docs.yaml). That workflow uses Claude Code to draft a `docs/update-{sdk}-v{version}` PR here, bumping the package and updating any prose or types that drifted. Older PRs for the same SDK are auto-closed by [.github/workflows/close-stale-version-prs.yml](.github/workflows/close-stale-version-prs.yml).
49+
When a connected SDK ships a release (e.g., [`spectrum-ts`](https://github.com/photon-hq/spectrum-ts), [`advanced-imessage-ts`](https://github.com/photon-hq/advanced-imessage-ts)), its release workflow calls [`photon-hq/buildspace/.github/workflows/update-docs.yaml`](https://github.com/photon-hq/buildspace/blob/main/.github/workflows/update-docs.yaml). That workflow uses Claude Code to draft a `docs/update-{sdk}-v{version}` PR here, bumping the package so Vellum extracts the new released types. Older PRs for the same SDK are auto-closed by [.github/workflows/close-stale-version-prs.yml](.github/workflows/close-stale-version-prs.yml).
50+
51+
For docs-only edits in a source repo, merge the change to the source repo's `main` branch and dispatch `spectrum-ts-docs` here. Do not cut a package release just to fix prose.
4852

4953
To enroll a new SDK, add `.github/workflows/update-docs.yaml` to its repo following the pattern in [advanced-imessage-ts](https://github.com/photon-hq/advanced-imessage-ts/blob/main/.github/workflows/update-docs.yaml).
5054

scripts/sources.json

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11
{
2-
"$comment": "Doc sources aggregated into .vellum-src before `vellum build`. Each source mounts under .vellum-src/<mount>/ (mount == page-slug prefix). `docsDir` is the source repo's Mintlify-templates directory; we use `docs-site/` (NOT `docs/`, which several repos already use for internal dev notes). `package` is the installed npm package whose version selects the git tag (`<tagPrefix><version>`) to pull docs from, keeping prose aligned with the types vellum extracts. `local` is a path under this repo used as a fallback when the repo has no docs at that ref yet (transitional) or when forced via DOCS_SOURCE_MODE=local. Per-source ref override: DOCS_REF_<name> env (dots/dashes -> underscores).",
2+
"$comment": "Doc sources aggregated into .vellum-src before `vellum build`. Each source mounts under .vellum-src/<mount>/ (mount == page-slug prefix). `docsDir` is the source repo's Mintlify-template directory. `ref` selects the source repo revision for authored docs; use main so prose fixes can ship without package releases. `package` records the installed npm package tied to the source; Vellum still extracts types from package.json dependencies. `local` is a path under this repo used as a fallback for offline local builds or when forced via DOCS_SOURCE_MODE=local. Per-source ref override: DOCS_REF_<name> env (dots/dashes -> underscores).",
33
"sources": [
44
{
55
"name": "spectrum-ts",
66
"mount": "spectrum-ts",
77
"package": "spectrum-ts",
88
"repo": "photon-hq/spectrum-ts",
9-
"docsDir": "docs-site",
10-
"tagPrefix": "v",
11-
"ref": null,
9+
"docsDir": "docs",
10+
"ref": "main",
1211
"nav": "nav.json",
1312
"local": "docs-src/spectrum-ts"
1413
}

scripts/sync-docs/index.ts

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ import process from 'node:process'
88
// 1. local templates in docs-src/ (areas not yet migrated + site-owned prose),
99
// minus any subtree owned by a source mount, and
1010
// 2. each source in scripts/sources.json, pulled from its repo via git
11-
// (sparse checkout of <docsDir> at the tag matching the installed package
12-
// version) or copied from a local fallback path.
11+
// (sparse checkout of <docsDir> at the configured ref, usually main)
12+
// or copied from a local fallback path.
1313
//
1414
// Each source's nav fragment is copied to .vellum-src/.nav/<mount>.json for
1515
// build-nav to merge. See ENG-1742.
@@ -86,8 +86,9 @@ function gitFetch(src: Source, ref: string): string | null {
8686
return existsSync(dir) ? dir : null
8787
}
8888

89-
// Resolve a source to its on-disk docs directory, honoring DOCS_SOURCE_MODE and
90-
// falling back from git to local when a repo has no docs at the ref yet.
89+
// Resolve a source to its on-disk docs directory, honoring DOCS_SOURCE_MODE.
90+
// In strict git mode, failures are fatal. Without an explicit mode, local
91+
// fallbacks keep development offline while source repos finish migrating.
9192
function resolveContentDir(src: Source): string {
9293
const mode = process.env.DOCS_SOURCE_MODE as Mode | undefined
9394
const localDir = src.local ? resolve(ROOT, src.local) : null
@@ -100,10 +101,19 @@ function resolveContentDir(src: Source): string {
100101
return localDir!
101102
}
102103

103-
const wantGit = mode === 'git' || !hasLocal
104-
if (wantGit) {
104+
if (mode === 'git') {
105105
if (!src.repo)
106-
throw new Error(`source "${src.name}": git mode requested but no "repo" configured`)
106+
throw new Error(`source "${src.name}": DOCS_SOURCE_MODE=git but no "repo" configured`)
107+
const ref = resolveRef(src)
108+
const dir = gitFetch(src, ref)
109+
if (!dir)
110+
throw new Error(`source "${src.name}": repo has no ${src.docsDir ?? 'docs'}/ at ${ref}`)
111+
return dir
112+
}
113+
114+
if (!hasLocal) {
115+
if (!src.repo)
116+
throw new Error(`source "${src.name}": no local fallback and no "repo" configured`)
107117
try {
108118
const dir = gitFetch(src, resolveRef(src))
109119
if (dir)

0 commit comments

Comments
 (0)