Skip to content
Open
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
59 changes: 59 additions & 0 deletions .github/workflows/sync-changelog.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
name: Sync Changelog

on:
schedule:
- cron: "17 * * * *"
workflow_dispatch:
push:
branches: [main]
paths:
- "references/api/changelog.mdx"
- "scripts/build-changelog.mjs"

permissions:
contents: write

concurrency:
group: sync-changelog
cancel-in-progress: false

jobs:
sync:
runs-on: ubuntu-latest
steps:
# Pinned by commit SHA, not tag: this job holds contents:write and pushes to main, so
# a retagged action would be a direct write path into the repo.
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0

- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version: 22

# Needs read access to relayprotocol/relay-kit and relayprotocol/relay-client.
- name: Rebuild changelog.mdx
env:
GITHUB_TOKEN: ${{ secrets.CHANGELOG_SOURCES_TOKEN }}
run: node scripts/build-changelog.mjs

# Nothing serialises this against humans merging PRs, so a push that lost the race is
# rebased and retried rather than failing the run and leaving the page stale.
- name: Commit if changed
run: |
if git diff --quiet -- changelog.mdx; then
echo "No changelog changes"
exit 0
fi
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git add changelog.mdx
git commit -m "docs: sync changelog"

for attempt in 1 2 3; do
if git push; then
exit 0
fi
echo "push rejected (attempt $attempt) — rebasing onto origin/main"
git pull --rebase origin main
done
echo "::error::could not push the changelog after 3 attempts"
exit 1
5 changes: 5 additions & 0 deletions .mintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Internal guidance and repo scaffolding, not docs pages. Without this they are parsed as
# MDX on every edit, so a `<placeholder>` in prose fails the whole deployment.
AGENTS.md
CLAUDE.md
README.md
3 changes: 2 additions & 1 deletion .prettierignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
references/sdk/getting-started.mdx
references/sdk/getting-started.mdx
changelog.mdx
32 changes: 26 additions & 6 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ Parameter tables are the dominant structured element on reference pages.
- Keep cell descriptions concise; move long explanations into prose below the table.
- `Required` column uses ✅ / ❌. **Only include the `Required` column when the table has a mix of required and optional params** — if everything is required (or everything is optional), omit the column entirely. Use a compound value like `✅ (❌ if X)` when requirement is conditional.
- Precede every parameter table with a one-line intro sentence ("Arguments:" / "Parameters:" are acceptable, but a full sentence reads better).
- When the table intentionally shows only a subset of parameters, call that out in the intro sentence and link to the full reference (e.g. "The most commonly used parameters are below; see [<full ref>](/...) for the complete list.").
- When the table intentionally shows only a subset of parameters, call that out in the intro sentence and link to the full reference (e.g. "The most commonly used parameters are below; see [`<full ref>`](/...) for the complete list.").

### 2.8 Code examples

Expand Down Expand Up @@ -252,9 +252,10 @@ Automation design for this flow is intentionally deferred; the current rule is "
Breaking changes are renames, removals, signature changes, return-shape changes, and endpoint path changes.

- **Edit pages in place.** The page describing the changed surface is updated to reflect the new shape. Do not leave an "old version" trace in-line.
- **Log in a per-product changelog.** Breaking-change narratives live in the product's changelog, not on the page itself. The changelogs are:
- `references/api/changelog.mdx` — for API endpoint changes (create this page; wire into the API Reference nav as a top-level entry).
- Future: `references/relay-kit/sdk/changelog.mdx`, `references/relay-kit/ui/changelog.mdx`, etc. — add when the first breaking change in that surface ships.
- **Log in the product's changelog source.** Breaking-change narratives live in a changelog, not on the page itself. Each product line has one source, and all of them roll up into `changelog.mdx` (§4.6):
- `references/api/changelog.mdx` — API endpoint changes, hand-authored in this repo.
- `relay-kit` package `CHANGELOG.md` files — written as changesets in that repo, not here.
- `relay-client` `.changelog/*.md` entries — written in that repo, not here. This line is curated marketing copy rather than a log of merged PRs, so it is empty by default and the App section is omitted until an entry exists.
- **Update inbound links.** Any page that referenced the old name / path / signature must be updated in the same PR.
- **No inline `<Warning>` callout on the updated page.** The changelog is the record. Exception: when the rename has a migration subtlety that every reader must see (e.g. param reordering with silent behavior change), add a one-liner `<Info>` with the date and a pointer to the changelog entry.

Expand All @@ -278,9 +279,9 @@ Deprecation applies when the old surface continues to exist and work, but is mar
- If the fix restores documented behavior, no doc update is required.
- If the fix is invisible to integrators (internal refactor), no doc update is required.

### 4.5 Changelog page format (API only, for now)
### 4.5 API changelog page format

`references/api/changelog.mdx` is a new page introduced by this guide. Structure:
`references/api/changelog.mdx` is the API product line's changelog, hand-authored in this repo. It is deliberately kept out of `docs.json` — readers get the API entries through the unified changelog (§4.6), so this page is a source file, not a published surface. Structure:

```mdx
---
Expand All @@ -299,6 +300,25 @@ description: "Record of breaking changes, deprecations, and notable additions to

Entries are newest-first. Each entry is a `##` heading with the date and a one-line summary. Body uses bolded change-type leads (`**Breaking**`, `**Deprecated**`, `**Added**`) on their own lines — matching the bolded-lead pattern already used on use-case pages (§3.2).

The `## YYYY-MM-DD — <summary>` heading shape is parsed by `scripts/build-changelog.mjs`; an entry that deviates from it is silently dropped from the unified changelog.

### 4.6 Unified changelog (`changelog.mdx`)

`changelog.mdx` is generated — **never edit it by hand.** `scripts/build-changelog.mjs` merges the three sources listed in §4.2 into one date-ordered page of Mintlify `<Update>` blocks, and an hourly GitHub Action commits the result. It is its own tab in `docs.json` (`navigation.tabs`), alongside Overview, API Reference, RelayKit, and Relay Protocol. Because the tab holds this page alone, the page sets `mode: "center"` so no single-item sidebar renders.

- Each day renders as one `<Update>` with `### API` / `### RelayKit` / `### App` sections.
- Entry text is reproduced verbatim from its source. Fix wording upstream, not here.
- **API and App changes group by change type across the whole day** — one `**Breaking**` / `**Deprecated**` / `**Behavior change**` / `**Added**` list per day, not per source entry, so a day reads as "here is what was added, here is what changed". Ordering comes from `CHANGE_TYPE_ORDER`; a type that is not listed there still renders, after the known ones. Source entry titles are dropped, and an API paragraph with no bolded type lead is folded into the change above it.
- RelayKit versions are dated by npm publish time. Changeset bullets that only say "Updated dependencies" are dropped, and one changeset spanning several packages collapses into a single item naming each package.
- **RelayKit entries link to their commit.** relay-kit is public and its changesets config (`@changesets/cli/changelog`) prefixes each bullet with the commit hash, so the generator turns that into a link on the summary line. The commit page names the originating PR, so this covers both without any API lookups. Bullets written without a hash simply get no link. Nothing links for the API or App lines — `solver` and `relay-client` are private.
- **Filtering is custom.** Mintlify's own changelog filters render in the table of contents, which `mode: "center"` hides. Instead, `enhanceChangelogPage()` in `script.js` binds the tags Mintlify already renders under each date (`[data-component-part="update-tag"]`, from the `tags={[…]}` prop): click one to narrow to that product line, click it again to clear, several tags OR together. **The `?tags=` query string is the source of truth**, re-read on every navigation event — a shared link, a back/forward step, and a click on the Changelog tab each land on the filter the URL names, rather than on whatever was last clicked. `style.css` gives those spans their chip look and active state. Both hang off Mintlify's `data-component-part` attributes — verified present on a deployed build, but if an upgrade renames them the filter silently stops working, so re-check it after a Mintlify bump.
- **The page carries the full history** (currently back to 2024-02-05) and renders all of it. Measured on a deployed build at 272 days: 1.8MB of HTML, **113KB gzipped**, **~10.4k DOM elements** — heavier than a normal docs page, and worth re-measuring as it grows. Hiding entries client-side is not the lever: it saves no bytes, and it breaks browser find, which is how readers locate things on a page with no table of contents. If the weight becomes a problem, split by year into real pages (`changelog/2026`), which the generator can emit from the same grouping — client-side fetching of markdown or JSON forfeits RSS, Mintlify's search index, the contextual copy/markdown menu, and crawler visibility. Set `CHANGELOG_SINCE` to truncate.
- Prerelease versions never reach the page. relay-kit publishes `0.0.0-canary-*` builds to npm, and a reader cannot install one.
- Cross-references between API entries resolve to `#YYYY-MM-DD`, the id Mintlify gives each `<Update>`.
- RelayKit dates come from both npm scopes — `@relayprotocol` for anything after the 2025-08-16 rename, `@reservoir0x` before it — because a version dated by neither cannot be placed on the page at all.
- Regenerate locally with `node scripts/build-changelog.mjs`. `--check` fails when the committed page differs from a fresh build; it is a **local** command, not a CI gate — it clones upstream `main` and queries npm live, so it would fail on any PR that happens to be open when relay-kit publishes. Consequence to expect: a PR that edits `references/api/changelog.mdx` gets a preview without that entry, which appears after merge at the next `:17`.
- A failed npm lookup aborts the run rather than emitting a page missing that package — an hourly job that commits its output must not be able to delete history on a transient 502.

---

## 5. Terminology
Expand Down
Loading
Loading