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
17 changes: 17 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# What does this PR resolve? πŸš€

<!-- One-line summary. Then bullets: the key changes and, briefly, the why. -->

# Details πŸ“

<!-- Implementation specifics, trade-offs, anything a reviewer needs. -->

# Checklist βœ…

- [ ] Merged latest `master` and resolved conflicts
- [ ] `npm run build` succeeds
- [ ] Links checked (`npm run check:links`) where relevant
- [ ] `static/llms.txt` updated if pages were added / renamed / deleted
- [ ] Content follows [CODING.md](../CODING.md) conventions (wrap long lines, `Swarm` vs `swarm`)
- [ ] Self-reviewed the diff
- [ ] Commits are signed off (`git commit -s`)
56 changes: 56 additions & 0 deletions .github/workflows/tag-on-openapi-merge.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
name: tag on openapi merge

# When an openapi-auto-update PR (from update-openapi.yaml) is merged, tag the merge
# commit with the matching Bee version (vX.Y.Z). That tag is what gh-pages.yaml deploys on.
#
# Requires the BOT_PAT secret (same token as update-openapi.yaml). It is used so the tag
# push triggers gh-pages.yaml β€” a tag pushed with the default GITHUB_TOKEN does NOT trigger
# other workflows. The job fails loudly if BOT_PAT is missing/expired.

on:
pull_request:
types: [closed]

permissions:
contents: write

jobs:
tag:
if: >-
github.event.pull_request.merged == true &&
contains(github.event.pull_request.labels.*.name, 'openapi-auto-update') &&
startsWith(github.event.pull_request.head.ref, 'bot/update-openapi-')
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.base.ref }}
fetch-depth: 0
token: ${{ secrets.BOT_PAT }}

- name: Derive tag from branch
id: tag
env:
HEAD_REF: ${{ github.event.pull_request.head.ref }}
run: |
set -euo pipefail
NEW_TAG="${HEAD_REF#bot/update-openapi-}"
if ! echo "$NEW_TAG" | grep -qE '^v[0-9]+\.[0-9]+\.[0-9]+$'; then
echo "Refusing to tag: '$NEW_TAG' is not a vX.Y.Z tag" >&2
exit 1
fi
echo "new_tag=$NEW_TAG" >> "$GITHUB_OUTPUT"

- name: Create and push tag
env:
NEW_TAG: ${{ steps.tag.outputs.new_tag }}
run: |
set -euo pipefail
if git rev-parse -q --verify "refs/tags/${NEW_TAG}" >/dev/null; then
echo "Tag ${NEW_TAG} already exists β€” nothing to do."
exit 0
fi
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git tag "$NEW_TAG"
git push origin "$NEW_TAG"
139 changes: 139 additions & 0 deletions .github/workflows/update-openapi.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
name: update openapi

# Detects a new STABLE ethersphere/bee release tag, pulls its OpenAPI specs into
# openapi/, bumps the Bee version strings in the install docs, and opens (or updates)
# a PR. Prereleases (-rc*, -beta, v2.7.1a, v2.5.0-v8, ...) are ignored.
#
# Requires the BOT_PAT secret (a classic PAT with public_repo scope, or a fine-grained PAT
# with contents + pull-requests write). It is used so the auto-PR triggers build.yaml CI β€”
# PRs opened with the default GITHUB_TOKEN do NOT trigger other workflows. The job fails
# loudly if BOT_PAT is missing/expired rather than silently skipping CI.

on:
schedule:
- cron: "0 6 * * *" # daily 06:00 UTC
workflow_dispatch:
inputs:
tag:
description: "Force a specific Bee tag (e.g. v2.9.0); blank = latest stable"
required: false

concurrency:
group: update-openapi
cancel-in-progress: true

permissions:
contents: write
pull-requests: write

jobs:
update-openapi:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Resolve latest stable Bee tag
id: resolve
run: |
set -euo pipefail
if [ -n "${{ github.event.inputs.tag }}" ]; then
NEW_TAG="${{ github.event.inputs.tag }}"
else
NEW_TAG="$(git ls-remote --tags --refs https://github.com/ethersphere/bee.git \
| awk '{print $2}' | sed 's#refs/tags/##' \
| grep -E '^v[0-9]+\.[0-9]+\.[0-9]+$' \
| sort -V | tail -1)"
fi
if [ -z "$NEW_TAG" ]; then
echo "Could not resolve a stable Bee tag" >&2
exit 1
fi
NEW_VER="${NEW_TAG#v}"
echo "new_tag=$NEW_TAG" >> "$GITHUB_OUTPUT"
echo "new_ver=$NEW_VER" >> "$GITHUB_OUTPUT"
echo "Latest stable Bee tag: $NEW_TAG (version $NEW_VER)"

- name: Determine current docs version
id: current
run: |
set -euo pipefail
OLD_VER="$(grep -oE 'TAG=v[0-9]+\.[0-9]+\.[0-9]+' docs/bee/installation/quick-start.md \
| head -1 | sed 's/^TAG=v//')"
if [ -z "$OLD_VER" ]; then
echo "Could not determine current docs version anchor" >&2
exit 1
fi
echo "old_ver=$OLD_VER" >> "$GITHUB_OUTPUT"
echo "Current docs version: $OLD_VER"

- name: Fetch OpenAPI specs from the tag
env:
NEW_TAG: ${{ steps.resolve.outputs.new_tag }}
run: |
set -euo pipefail
for f in Swarm.yaml SwarmCommon.yaml; do
curl -fsSL \
"https://raw.githubusercontent.com/ethersphere/bee/${NEW_TAG}/openapi/$f" \
-o "openapi/$f"
done

- name: Bump Bee version strings in docs
if: ${{ steps.current.outputs.old_ver != steps.resolve.outputs.new_ver }}
env:
OLD_VER: ${{ steps.current.outputs.old_ver }}
NEW_VER: ${{ steps.resolve.outputs.new_ver }}
run: |
set -euo pipefail
FILES=(
docs/bee/installation/build-from-source.md
docs/bee/installation/docker.md
docs/bee/installation/quick-start.md
docs/bee/installation/shell-script.md
docs/bee/working-with-bee/bee-api.md
docs/bee/working-with-bee/configuration.md
docs/bee/working-with-bee/staking.md
)
# Literal substring swap of the semver. This deliberately also rewrites the
# vX.Y.Z, bee:X.Y.Z and X.Y.Z-<hash> forms (the version is a substring of each),
# and is safe because the old version never appears inside an unrelated number
# in these files. ESC_OLD escapes the dots so they match literally.
ESC_OLD="${OLD_VER//./\\.}"
sed -i "s/${ESC_OLD}/${NEW_VER}/g" "${FILES[@]}"

- name: Detect changes
id: changes
run: |
set -euo pipefail
if git diff --quiet; then
echo "changed=false" >> "$GITHUB_OUTPUT"
echo "No changes β€” already up to date with the latest stable Bee release."
else
echo "changed=true" >> "$GITHUB_OUTPUT"
fi

- name: Create or update PR
if: ${{ steps.changes.outputs.changed == 'true' }}
uses: peter-evans/create-pull-request@v6
with:
token: ${{ secrets.BOT_PAT }}
branch: bot/update-openapi-${{ steps.resolve.outputs.new_tag }}
commit-message: "chore: update OpenAPI specs and version refs to Bee ${{ steps.resolve.outputs.new_tag }}"
title: "Update OpenAPI specs to Bee ${{ steps.resolve.outputs.new_tag }}"
labels: openapi-auto-update
delete-branch: true
body: |
Automated update to Bee **${{ steps.resolve.outputs.new_tag }}**.

Source: https://github.com/ethersphere/bee/tree/${{ steps.resolve.outputs.new_tag }}/openapi

## What changed
- `openapi/Swarm.yaml` and `openapi/SwarmCommon.yaml` pulled from the tagged commit.
- Bee version strings bumped `${{ steps.current.outputs.old_ver }}` β†’ `${{ steps.resolve.outputs.new_ver }}` in the install docs.

## ⚠️ Please review before merging
The version-string replacement is **best-effort** (literal semver swap in a fixed set
of doc files) and can miss or over-match. Skim the doc diff. Merging this PR triggers
the `tag-on-openapi-merge` workflow, which tags the merge commit `${{ steps.resolve.outputs.new_tag }}`
and (with a PAT configured) kicks off the gh-pages deploy.
4 changes: 0 additions & 4 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
examples
.docusaurus
.claude
CLAUDE.md
node_modules
.DS_Store
build
Expand All @@ -15,6 +14,3 @@ docs/references/awesome-list.mdx
*.zip
*.csv
link-reports/
CLAUDE.md


63 changes: 63 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## What this is

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.

## Commands

```bash
npm ci # install exact deps (preferred over npm install)
npm start # local dev server with live reload
npm run build # production build into build/ (runs prebuild first)
npm run build:quiet # build with noisy Node deprecation warnings suppressed
npm run serve # serve a built site locally

npm run check:links # check links against an existing local build
npm run build:check # build + check links in one step
```

Link checker flags pass through after `--`:

```bash
npm run check:links -- --mode local --no-external --threads 16
npm run check:links -- --mode live --site-domain docs.ethswarm.org
```

Node >=20, npm >=9.6 (see `.nvmrc` / `package.json` engines).

There is **no test suite and no linter** β€” validation is the build, the `llms.txt` validator (runs in `prebuild`), and the link checker.

## Build pipeline gotchas

The `prebuild` npm hook runs automatically before `build` and does three things, in order:
1. Copies `openapi/Swarm.yaml` β†’ `static/openapi.yaml`.
2. `scripts/fetch-awesome-swarm.mjs` β€” fetches external content at build time.
3. `scripts/validate-llms-txt.mjs` β€” validates `static/llms.txt` coverage (informational, **always exit 0**, never blocks the build).

`onBrokenLinks: 'warn'` β€” broken internal links warn rather than fail the build. Use the link checker to catch them.

## Architecture / where things live

- **`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`.
- **`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.).
- **`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.
- **`.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.
- **`src/components/`** β€” interactive calculators embedded in docs via MDX (e.g. `AmountAndDepthCalc.js`, `RedundancyCalc.js`, `VolumeAndDurationCalc.js`). `src/config/globalVariables.js` holds shared constants.
- **`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.
- **`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.

## llms.txt (AI-agent docs)

- `static/llms.txt` β€” **hand-curated** index of every doc page, one line each. Edit by hand when pages are added/renamed/deleted.
- `/llms-full.txt` and the sliced variants β€” **auto-generated** at build time; do not hand-edit.
- 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.

## Content conventions (from CODING.md)

- **Wrap long lines** with newlines β€” keeps git diffs small and reduces merge conflicts.
- **Minimize unrelated edits** (e.g. don't reflow a whole paragraph to fix one typo) for the same reason.
- **`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.
- **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.
13 changes: 11 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,17 @@ Reports are written to `link-reports/` (gitignored).

## Bumping Version

Don't forget to find and replace the version number for the whole of the docs folder.
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.

## API Reference

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).
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.

## Keeping in sync with Bee releases

Two GitHub Actions workflows keep the docs aligned with [ethersphere/bee](https://github.com/ethersphere/bee) releases:

- **`.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**.
- **`.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.

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.
Loading