diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml new file mode 100644 index 0000000..90ce9a3 --- /dev/null +++ b/.github/workflows/docs.yml @@ -0,0 +1,72 @@ +# Builds web/docs on every PR that touches it, and deploys to Cloudflare Pages +# (project `beardrive-docs`, custom domain docs.beardrive.ai) on push to main. +# +# Deliberately NOT the Pages Git integration: that clones shallow, and the +# sitemap's comes from each page's commit date, so a depth-1 checkout +# silently drops every lastmod. Hence `fetch-depth: 0` below. +# +# Needs two secrets: CLOUDFLARE_API_TOKEN (an account API token with +# "Cloudflare Pages: Edit") and CLOUDFLARE_ACCOUNT_ID. +name: docs +on: + push: + branches: [main] + paths: + - "web/docs/**" + # The palette is generated from the hub frontend's tokens, so a change + # there changes the built docs too. + - "internal/webapp/frontend/src/tw.css" + - ".github/workflows/docs.yml" + pull_request: + paths: + - "web/docs/**" + - "internal/webapp/frontend/src/tw.css" + - ".github/workflows/docs.yml" + workflow_dispatch: + +concurrency: + group: docs-${{ github.ref }} + cancel-in-progress: true + +jobs: + build-deploy: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 # sitemap comes from commit dates + + - uses: actions/setup-node@v4 + with: + node-version: 22 + cache: npm + cache-dependency-path: web/docs/package-lock.json + + # The build reads ../../internal/webapp/frontend/src/tw.css, so the whole + # repo has to be checked out — not just this subdirectory. + - run: npm ci + working-directory: web/docs + - run: npm run build + working-directory: web/docs + + - name: Deploy to Cloudflare Pages + if: github.event_name != 'pull_request' + env: + CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} + CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} + run: > + npx --yes wrangler@4 pages deploy dist + --project-name=beardrive-docs + --branch=main + --commit-dirty=true + working-directory: web/docs + + # Same checks Search Console runs: robots.txt -> index -> every URL 200s. + # Reports, never blocks: half of what it checks (a managed robots.txt + # shadowing ours, cache propagation) is Cloudflare's call, not this + # repo's, and a good deploy must not go red over it. Read the step. + - name: Verify what production actually serves + if: github.event_name != 'pull_request' + continue-on-error: true + run: npm run check:sitemap https://docs.beardrive.ai + working-directory: web/docs diff --git a/CLAUDE.md b/CLAUDE.md index 9e6042a..c5bbee6 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -23,7 +23,7 @@ npm run e2e # Playwright suite against the seeded e2e hub (starts itself ./check-dist.sh # verify committed static/ matches frontend/src (run before releases) ``` -There is no Makefile, linter config, or CI config in-repo. Releases run `goreleaser release` on a tagged commit (see `.goreleaser.yaml`); the version is injected via `-ldflags "-X main.version=..."` into `cmd/bdrive/main.go`. The frontend's built assets are **committed** (go:embed needs them in the module), so `go build` and `go install` never require Node — but a release tag must not ship a stale `internal/webapp/static`: run `frontend/check-dist.sh` first. +There is no Makefile or linter config in-repo. CI is three GitHub Actions workflows: `ci.yml` (build/vet/test on Linux and macOS), `bump-cloud.yml` (pins the new OSS commit in the private cloud repo), and `docs.yml` (builds `web/docs` on PRs, deploys it to the `beardrive-docs` Cloudflare Pages project — docs.beardrive.ai — on pushes to main; see `web/docs/README.md`). Releases run `goreleaser release` on a tagged commit (see `.goreleaser.yaml`); the version is injected via `-ldflags "-X main.version=..."` into `cmd/bdrive/main.go`. The frontend's built assets are **committed** (go:embed needs them in the module), so `go build` and `go install` never require Node — but a release tag must not ship a stale `internal/webapp/static`: run `frontend/check-dist.sh` first. When testing the CLI manually, set `BDRIVE_HOME=/some/tmp/dir` to relocate all beardrive state (device identity, mount registry, volume stores) away from the real `~/.bdrive`. diff --git a/web/docs/README.md b/web/docs/README.md index 4e38086..370f71c 100644 --- a/web/docs/README.md +++ b/web/docs/README.md @@ -117,6 +117,19 @@ to type. Static output in `dist/`. Any static host works; build command `npm run build`, output directory `dist`, project root `web/docs`. +Today that host is **Cloudflare Pages**, project `beardrive-docs` +(`docs.beardrive.ai`), deployed by `.github/workflows/docs.yml` on every push to +`main` that touches `web/docs/**` or the token source. It needs two repository +secrets: `CLOUDFLARE_API_TOKEN` (an account token with *Cloudflare Pages: Edit*) +and `CLOUDFLARE_ACCOUNT_ID`. + +Not the Pages **Git integration**, deliberately: it clones shallow, which costs +every `` (see "Checkout depth"), and it would build the docs on commits +that cannot change them. The Pages project is a direct-upload project — nothing +deploys it but this workflow. That is also the failure mode to watch for: when +deploys were manual, they simply stopped, and the site sat three weeks stale +while every check that only runs *during* a deploy stayed green. + ### Redirects The docs were reorganized around the agent-first path, so three old URLs moved: