Skip to content

Commit fd34761

Browse files
authored
Merge pull request #820 from ethersphere/feat/automate-openapi-update
feat: automate OpenAPI sync with Bee releases
2 parents 5790d5e + b494409 commit fd34761

6 files changed

Lines changed: 286 additions & 6 deletions

File tree

.github/PULL_REQUEST_TEMPLATE.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# What does this PR resolve? 🚀
2+
3+
<!-- One-line summary. Then bullets: the key changes and, briefly, the why. -->
4+
5+
# Details 📝
6+
7+
<!-- Implementation specifics, trade-offs, anything a reviewer needs. -->
8+
9+
# Checklist ✅
10+
11+
- [ ] Merged latest `master` and resolved conflicts
12+
- [ ] `npm run build` succeeds
13+
- [ ] Links checked (`npm run check:links`) where relevant
14+
- [ ] `static/llms.txt` updated if pages were added / renamed / deleted
15+
- [ ] Content follows [CODING.md](../CODING.md) conventions (wrap long lines, `Swarm` vs `swarm`)
16+
- [ ] Self-reviewed the diff
17+
- [ ] Commits are signed off (`git commit -s`)
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
name: tag on openapi merge
2+
3+
# When an openapi-auto-update PR (from update-openapi.yaml) is merged, tag the merge
4+
# commit with the matching Bee version (vX.Y.Z). That tag is what gh-pages.yaml deploys on.
5+
#
6+
# Requires the BOT_PAT secret (same token as update-openapi.yaml). It is used so the tag
7+
# push triggers gh-pages.yaml — a tag pushed with the default GITHUB_TOKEN does NOT trigger
8+
# other workflows. The job fails loudly if BOT_PAT is missing/expired.
9+
10+
on:
11+
pull_request:
12+
types: [closed]
13+
14+
permissions:
15+
contents: write
16+
17+
jobs:
18+
tag:
19+
if: >-
20+
github.event.pull_request.merged == true &&
21+
contains(github.event.pull_request.labels.*.name, 'openapi-auto-update') &&
22+
startsWith(github.event.pull_request.head.ref, 'bot/update-openapi-')
23+
runs-on: ubuntu-22.04
24+
steps:
25+
- uses: actions/checkout@v4
26+
with:
27+
ref: ${{ github.event.pull_request.base.ref }}
28+
fetch-depth: 0
29+
token: ${{ secrets.BOT_PAT }}
30+
31+
- name: Derive tag from branch
32+
id: tag
33+
env:
34+
HEAD_REF: ${{ github.event.pull_request.head.ref }}
35+
run: |
36+
set -euo pipefail
37+
NEW_TAG="${HEAD_REF#bot/update-openapi-}"
38+
if ! echo "$NEW_TAG" | grep -qE '^v[0-9]+\.[0-9]+\.[0-9]+$'; then
39+
echo "Refusing to tag: '$NEW_TAG' is not a vX.Y.Z tag" >&2
40+
exit 1
41+
fi
42+
echo "new_tag=$NEW_TAG" >> "$GITHUB_OUTPUT"
43+
44+
- name: Create and push tag
45+
env:
46+
NEW_TAG: ${{ steps.tag.outputs.new_tag }}
47+
run: |
48+
set -euo pipefail
49+
if git rev-parse -q --verify "refs/tags/${NEW_TAG}" >/dev/null; then
50+
echo "Tag ${NEW_TAG} already exists — nothing to do."
51+
exit 0
52+
fi
53+
git config user.name "github-actions[bot]"
54+
git config user.email "github-actions[bot]@users.noreply.github.com"
55+
git tag "$NEW_TAG"
56+
git push origin "$NEW_TAG"
Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
name: update openapi
2+
3+
# Detects a new STABLE ethersphere/bee release tag, pulls its OpenAPI specs into
4+
# openapi/, bumps the Bee version strings in the install docs, and opens (or updates)
5+
# a PR. Prereleases (-rc*, -beta, v2.7.1a, v2.5.0-v8, ...) are ignored.
6+
#
7+
# Requires the BOT_PAT secret (a classic PAT with public_repo scope, or a fine-grained PAT
8+
# with contents + pull-requests write). It is used so the auto-PR triggers build.yaml CI —
9+
# PRs opened with the default GITHUB_TOKEN do NOT trigger other workflows. The job fails
10+
# loudly if BOT_PAT is missing/expired rather than silently skipping CI.
11+
12+
on:
13+
schedule:
14+
- cron: "0 6 * * *" # daily 06:00 UTC
15+
workflow_dispatch:
16+
inputs:
17+
tag:
18+
description: "Force a specific Bee tag (e.g. v2.9.0); blank = latest stable"
19+
required: false
20+
21+
concurrency:
22+
group: update-openapi
23+
cancel-in-progress: true
24+
25+
permissions:
26+
contents: write
27+
pull-requests: write
28+
29+
jobs:
30+
update-openapi:
31+
runs-on: ubuntu-22.04
32+
steps:
33+
- uses: actions/checkout@v4
34+
with:
35+
fetch-depth: 0
36+
37+
- name: Resolve latest stable Bee tag
38+
id: resolve
39+
run: |
40+
set -euo pipefail
41+
if [ -n "${{ github.event.inputs.tag }}" ]; then
42+
NEW_TAG="${{ github.event.inputs.tag }}"
43+
else
44+
NEW_TAG="$(git ls-remote --tags --refs https://github.com/ethersphere/bee.git \
45+
| awk '{print $2}' | sed 's#refs/tags/##' \
46+
| grep -E '^v[0-9]+\.[0-9]+\.[0-9]+$' \
47+
| sort -V | tail -1)"
48+
fi
49+
if [ -z "$NEW_TAG" ]; then
50+
echo "Could not resolve a stable Bee tag" >&2
51+
exit 1
52+
fi
53+
NEW_VER="${NEW_TAG#v}"
54+
echo "new_tag=$NEW_TAG" >> "$GITHUB_OUTPUT"
55+
echo "new_ver=$NEW_VER" >> "$GITHUB_OUTPUT"
56+
echo "Latest stable Bee tag: $NEW_TAG (version $NEW_VER)"
57+
58+
- name: Determine current docs version
59+
id: current
60+
run: |
61+
set -euo pipefail
62+
OLD_VER="$(grep -oE 'TAG=v[0-9]+\.[0-9]+\.[0-9]+' docs/bee/installation/quick-start.md \
63+
| head -1 | sed 's/^TAG=v//')"
64+
if [ -z "$OLD_VER" ]; then
65+
echo "Could not determine current docs version anchor" >&2
66+
exit 1
67+
fi
68+
echo "old_ver=$OLD_VER" >> "$GITHUB_OUTPUT"
69+
echo "Current docs version: $OLD_VER"
70+
71+
- name: Fetch OpenAPI specs from the tag
72+
env:
73+
NEW_TAG: ${{ steps.resolve.outputs.new_tag }}
74+
run: |
75+
set -euo pipefail
76+
for f in Swarm.yaml SwarmCommon.yaml; do
77+
curl -fsSL \
78+
"https://raw.githubusercontent.com/ethersphere/bee/${NEW_TAG}/openapi/$f" \
79+
-o "openapi/$f"
80+
done
81+
82+
- name: Bump Bee version strings in docs
83+
if: ${{ steps.current.outputs.old_ver != steps.resolve.outputs.new_ver }}
84+
env:
85+
OLD_VER: ${{ steps.current.outputs.old_ver }}
86+
NEW_VER: ${{ steps.resolve.outputs.new_ver }}
87+
run: |
88+
set -euo pipefail
89+
FILES=(
90+
docs/bee/installation/build-from-source.md
91+
docs/bee/installation/docker.md
92+
docs/bee/installation/quick-start.md
93+
docs/bee/installation/shell-script.md
94+
docs/bee/working-with-bee/bee-api.md
95+
docs/bee/working-with-bee/configuration.md
96+
docs/bee/working-with-bee/staking.md
97+
)
98+
# Literal substring swap of the semver. This deliberately also rewrites the
99+
# vX.Y.Z, bee:X.Y.Z and X.Y.Z-<hash> forms (the version is a substring of each),
100+
# and is safe because the old version never appears inside an unrelated number
101+
# in these files. ESC_OLD escapes the dots so they match literally.
102+
ESC_OLD="${OLD_VER//./\\.}"
103+
sed -i "s/${ESC_OLD}/${NEW_VER}/g" "${FILES[@]}"
104+
105+
- name: Detect changes
106+
id: changes
107+
run: |
108+
set -euo pipefail
109+
if git diff --quiet; then
110+
echo "changed=false" >> "$GITHUB_OUTPUT"
111+
echo "No changes — already up to date with the latest stable Bee release."
112+
else
113+
echo "changed=true" >> "$GITHUB_OUTPUT"
114+
fi
115+
116+
- name: Create or update PR
117+
if: ${{ steps.changes.outputs.changed == 'true' }}
118+
uses: peter-evans/create-pull-request@v6
119+
with:
120+
token: ${{ secrets.BOT_PAT }}
121+
branch: bot/update-openapi-${{ steps.resolve.outputs.new_tag }}
122+
commit-message: "chore: update OpenAPI specs and version refs to Bee ${{ steps.resolve.outputs.new_tag }}"
123+
title: "Update OpenAPI specs to Bee ${{ steps.resolve.outputs.new_tag }}"
124+
labels: openapi-auto-update
125+
delete-branch: true
126+
body: |
127+
Automated update to Bee **${{ steps.resolve.outputs.new_tag }}**.
128+
129+
Source: https://github.com/ethersphere/bee/tree/${{ steps.resolve.outputs.new_tag }}/openapi
130+
131+
## What changed
132+
- `openapi/Swarm.yaml` and `openapi/SwarmCommon.yaml` pulled from the tagged commit.
133+
- Bee version strings bumped `${{ steps.current.outputs.old_ver }}` → `${{ steps.resolve.outputs.new_ver }}` in the install docs.
134+
135+
## ⚠️ Please review before merging
136+
The version-string replacement is **best-effort** (literal semver swap in a fixed set
137+
of doc files) and can miss or over-match. Skim the doc diff. Merging this PR triggers
138+
the `tag-on-openapi-merge` workflow, which tags the merge commit `${{ steps.resolve.outputs.new_tag }}`
139+
and (with a PAT configured) kicks off the gh-pages deploy.

.gitignore

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
examples
22
.docusaurus
33
.claude
4-
CLAUDE.md
54
node_modules
65
.DS_Store
76
build
@@ -15,6 +14,3 @@ docs/references/awesome-list.mdx
1514
*.zip
1615
*.csv
1716
link-reports/
18-
CLAUDE.md
19-
20-

CLAUDE.md

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# CLAUDE.md
2+
3+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4+
5+
## What this is
6+
7+
Documentation website for the [Swarm Bee client](https://github.com/ethersphere/bee), built with **Docusaurus 3** and deployed at [docs.ethswarm.org](https://docs.ethswarm.org). Content lives in `docs/` as Markdown/MDX; everything else is site config, build tooling, and a few React components.
8+
9+
## Commands
10+
11+
```bash
12+
npm ci # install exact deps (preferred over npm install)
13+
npm start # local dev server with live reload
14+
npm run build # production build into build/ (runs prebuild first)
15+
npm run build:quiet # build with noisy Node deprecation warnings suppressed
16+
npm run serve # serve a built site locally
17+
18+
npm run check:links # check links against an existing local build
19+
npm run build:check # build + check links in one step
20+
```
21+
22+
Link checker flags pass through after `--`:
23+
24+
```bash
25+
npm run check:links -- --mode local --no-external --threads 16
26+
npm run check:links -- --mode live --site-domain docs.ethswarm.org
27+
```
28+
29+
Node >=20, npm >=9.6 (see `.nvmrc` / `package.json` engines).
30+
31+
There is **no test suite and no linter** — validation is the build, the `llms.txt` validator (runs in `prebuild`), and the link checker.
32+
33+
## Build pipeline gotchas
34+
35+
The `prebuild` npm hook runs automatically before `build` and does three things, in order:
36+
1. Copies `openapi/Swarm.yaml``static/openapi.yaml`.
37+
2. `scripts/fetch-awesome-swarm.mjs` — fetches external content at build time.
38+
3. `scripts/validate-llms-txt.mjs` — validates `static/llms.txt` coverage (informational, **always exit 0**, never blocks the build).
39+
40+
`onBrokenLinks: 'warn'` — broken internal links warn rather than fail the build. Use the link checker to catch them.
41+
42+
## Architecture / where things live
43+
44+
- **`docs/`** — all documentation content, grouped into top-level sections: `bee/`, `concepts/`, `desktop/`, `develop/`, `references/`. Page ordering and the sidebar tree are defined manually in **`sidebars.js`** (not auto-generated) — adding a doc file requires adding it to `sidebars.js`.
45+
- **`docusaurus.config.mjs`** — single source of site config: plugins, presets, redirects (`@docusaurus/plugin-client-redirects`), the OpenAPI integration (`redocusaurus`), and three `docusaurus-plugin-llms` slice configs (`llms-api.txt`, `llms-node-ops.txt`, etc.).
46+
- **`openapi/`**`Swarm.yaml` + `SwarmCommon.yaml`. The API reference page is compiled from these at build time via redocusaurus. Kept in sync with the [OpenAPI specs in the Bee repo](https://github.com/ethersphere/bee/tree/master/openapi) by the `update-openapi` workflow (see below) — they are **not** edited by hand.
47+
- **`.github/workflows/`**`build.yaml` (build on push/PR), `gh-pages.yaml` (deploy on `v*.*.*` tag push), and two Bee-sync workflows: `update-openapi.yaml` (daily; pulls openapi specs + bumps version strings from the latest stable Bee tag and opens a PR labelled `openapi-auto-update`) and `tag-on-openapi-merge.yaml` (tags the merge commit `vX.Y.Z` when that PR merges, triggering the deploy). Both need the `BOT_PAT` secret and fail loudly without it.
48+
- **`src/components/`** — interactive calculators embedded in docs via MDX (e.g. `AmountAndDepthCalc.js`, `RedundancyCalc.js`, `VolumeAndDurationCalc.js`). `src/config/globalVariables.js` holds shared constants.
49+
- **`src/theme/SearchBar/`** — a **swizzled** component (ejected from the theme). See the README: upgrading the Docusaurus theme does NOT upgrade swizzled components and can break search; re-swizzle after theme upgrades.
50+
- **`scripts/`** — TypeScript (`tsx`, no separate install) build/CI helpers: link checkers (`check_links.ts`, `check_live_links.ts`) and the build-time `.mjs` scripts above.
51+
52+
## llms.txt (AI-agent docs)
53+
54+
- `static/llms.txt`**hand-curated** index of every doc page, one line each. Edit by hand when pages are added/renamed/deleted.
55+
- `/llms-full.txt` and the sliced variants — **auto-generated** at build time; do not hand-edit.
56+
- When the prebuild validator warns about a stale link or missing coverage, fix `static/llms.txt` (update the path or add a `- [Title](url): description` line in the right section). A few navigation-only landing pages are intentionally excluded — those warnings are expected.
57+
58+
## Content conventions (from CODING.md)
59+
60+
- **Wrap long lines** with newlines — keeps git diffs small and reduces merge conflicts.
61+
- **Minimize unrelated edits** (e.g. don't reflow a whole paragraph to fix one typo) for the same reason.
62+
- **`Swarm` vs `swarm`**: capital `Swarm` = the project / main network; lowercase `swarm` = a swarm of bee nodes (Bee supports running multiple). Capital `Bee` = the Go client; lowercase `bee` = any Swarm-protocol client.
63+
- **Version bumps**: automated by the `update-openapi` workflow on each new stable Bee release (literal find-and-replace of the semver in the install docs). Only bump by hand for out-of-band corrections, across the whole `docs/` folder.

README.md

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,8 +122,17 @@ Reports are written to `link-reports/` (gitignored).
122122

123123
## Bumping Version
124124

125-
Don't forget to find and replace the version number for the whole of the docs folder.
125+
When a new stable Bee version is released, the version number across the `docs/` folder is bumped automatically — see [Keeping in sync with Bee releases](#keeping-in-sync-with-bee-releases) below.
126126

127127
## API Reference
128128

129-
The OpenAPI reference docs are compiled at build time from the OpenAPI yaml files in the `/openapi` directory using the [redocusaurus plugin](https://www.npmjs.com/package/redocusaurus) for Docusaurus. They must be manually updated to stay up to date with the [OpenAPI specs in the Bee repo](https://github.com/ethersphere/bee/tree/master/openapi).
129+
The OpenAPI reference docs are compiled at build time from the OpenAPI yaml files in the `/openapi` directory using the [redocusaurus plugin](https://www.npmjs.com/package/redocusaurus) for Docusaurus. They are kept in sync with the [OpenAPI specs in the Bee repo](https://github.com/ethersphere/bee/tree/master/openapi) automatically — see below.
130+
131+
## Keeping in sync with Bee releases
132+
133+
Two GitHub Actions workflows keep the docs aligned with [ethersphere/bee](https://github.com/ethersphere/bee) releases:
134+
135+
- **`.github/workflows/update-openapi.yaml`** runs daily (and on manual `workflow_dispatch`). It finds the latest **stable** Bee tag (prereleases like `-rc*` are ignored), pulls `Swarm.yaml` + `SwarmCommon.yaml` from that tag into `openapi/`, bumps the Bee version strings in the install docs, and opens (or updates) a PR labelled `openapi-auto-update`. The version-string replacement is best-effort — **review the doc diff before merging**.
136+
- **`.github/workflows/tag-on-openapi-merge.yaml`** runs when such a PR is merged. It tags the merge commit with the matching Bee version (`vX.Y.Z`), which triggers the existing `gh-pages.yaml` deploy.
137+
138+
Both require a repository secret named **`BOT_PAT`** (a classic PAT with `public_repo` scope, or a fine-grained PAT with contents + pull-requests write). The PAT is necessary to allow CI for the auto-PRs and deployment for the auto-release tags. If the token is missing or expired, the workflows fail loudly rather than silently degrading. Renew BOT_PAT in such case.

0 commit comments

Comments
 (0)