feat(chat-server): Phase 6+7 — REST + WS + demo client + multi-review… #9
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Publish @my-own-web-services/react-components docs | |
| # Deploys to https://my-own-web-services.github.io/mows-react-components/ | |
| # | |
| # Publishing model: this workflow builds the docs SPA, then pushes it into | |
| # the org Pages repo `my-own-web-services/my-own-web-services.github.io` | |
| # under the `mows-react-components/` subdirectory. That repo hosts every | |
| # project's docs as siblings (mows-react-components/, mows-vm-supervisor/, | |
| # …) so each docs workflow only owns its own subdir and never touches the | |
| # others. | |
| # | |
| # Prerequisites (one-time, done out-of-band): | |
| # 1. Org Pages repo `my-own-web-services/my-own-web-services.github.io` | |
| # exists, public, Pages enabled with Source = "Deploy from a branch" | |
| # (main, /). | |
| # 2. An SSH deploy key has been generated. The PUBLIC half is added to | |
| # the org Pages repo as a deploy key with write access. The PRIVATE | |
| # half is stored on THIS repo as the `DOCS_DEPLOY_KEY` secret. | |
| on: | |
| push: | |
| branches: | |
| - main | |
| paths: | |
| - 'components/react/**' | |
| - '.github/workflows/publish-docs.yml' | |
| pull_request: | |
| paths: | |
| - 'components/react/**' | |
| - '.github/workflows/publish-docs.yml' | |
| workflow_dispatch: | |
| inputs: | |
| site_base: | |
| description: 'Public base path the site is served from (must start AND end with "/"). Default "/mows-react-components/" matches the org Pages layout.' | |
| required: false | |
| default: '/mows-react-components/' | |
| type: string | |
| # Serialise pushes to the org Pages repo so a newer commit on main always | |
| # wins. PRs run the build alone (no deploy) so they cancel freely. | |
| concurrency: | |
| group: publish-docs-${{ github.ref }} | |
| cancel-in-progress: ${{ github.event_name == 'pull_request' }} | |
| permissions: | |
| contents: read | |
| env: | |
| # Slug used both as the URL path prefix and the subdirectory inside the | |
| # org Pages repo. Changing this in one place keeps the build and the | |
| # deploy in sync. | |
| DOCS_SLUG: mows-react-components | |
| PAGES_REPO: my-own-web-services/my-own-web-services.github.io | |
| jobs: | |
| build: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v4 | |
| - name: Set up Node.js | |
| uses: actions/setup-node@26961cf329f22f6837d5f54c3efd76b480300ace # v4 | |
| with: | |
| node-version: '22' | |
| - name: Set up pnpm | |
| uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4 | |
| with: | |
| version: 9.15.9 | |
| run_install: false | |
| - name: Get pnpm store path | |
| id: pnpm-store | |
| run: echo "path=$(pnpm store path --silent)" >> "$GITHUB_OUTPUT" | |
| - name: Cache pnpm store | |
| uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v4 | |
| with: | |
| path: ${{ steps.pnpm-store.outputs.path }} | |
| key: ${{ runner.os }}-pnpm-${{ hashFiles('components/react/pnpm-lock.yaml') }} | |
| restore-keys: | | |
| ${{ runner.os }}-pnpm- | |
| - name: Build docs site | |
| env: | |
| SITE_BASE: ${{ github.event.inputs.site_base || format('/{0}/', env.DOCS_SLUG) }} | |
| run: | | |
| cd components/react | |
| bash scripts/build-docs.sh | |
| # Hand the built `dist-site/` to the deploy job via the standard | |
| # artifact channel. Plain workflow artifact — NOT a Pages artifact — | |
| # since we publish to a different repo, not this repo's Pages. | |
| - name: Upload built site | |
| uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0 | |
| with: | |
| name: docs-site | |
| path: components/react/dist-site | |
| retention-days: 7 | |
| if-no-files-found: error | |
| deploy: | |
| needs: build | |
| if: github.event_name == 'push' && github.ref == 'refs/heads/main' | |
| runs-on: ubuntu-latest | |
| environment: | |
| name: docs-publish | |
| url: https://my-own-web-services.github.io/${{ env.DOCS_SLUG }}/ | |
| steps: | |
| - name: Download built site | |
| uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 | |
| with: | |
| name: docs-site | |
| path: dist-site | |
| - name: Configure SSH for org Pages repo | |
| env: | |
| DEPLOY_KEY: ${{ secrets.DOCS_DEPLOY_KEY }} | |
| run: | | |
| if [ -z "${DEPLOY_KEY}" ]; then | |
| echo "::error::DOCS_DEPLOY_KEY secret is not configured on this repo." | |
| echo "Generate an ed25519 keypair, add the public half as a deploy key" | |
| echo "(with write access) on ${PAGES_REPO}, and add the private half as" | |
| echo "the DOCS_DEPLOY_KEY secret on this repo." | |
| exit 1 | |
| fi | |
| mkdir -p ~/.ssh | |
| chmod 700 ~/.ssh | |
| printf '%s\n' "${DEPLOY_KEY}" > ~/.ssh/id_ed25519 | |
| chmod 600 ~/.ssh/id_ed25519 | |
| ssh-keyscan -t ed25519,rsa github.com >> ~/.ssh/known_hosts 2>/dev/null | |
| - name: Publish to org Pages repo | |
| env: | |
| SOURCE_SHA: ${{ github.sha }} | |
| run: | | |
| set -euo pipefail | |
| # Shallow clone to keep the deploy fast; we only need HEAD to make | |
| # one new commit on top of it. | |
| git clone --depth 1 "git@github.com:${PAGES_REPO}.git" pages-repo | |
| cd pages-repo | |
| # Replace only OUR subdir; siblings (other docs projects) stay | |
| # untouched. rsync --delete prunes files that disappeared | |
| # between builds, but the --include patterns confine all | |
| # deletes to ${DOCS_SLUG}/. | |
| rm -rf "${DOCS_SLUG}" | |
| mkdir "${DOCS_SLUG}" | |
| cp -a ../dist-site/. "${DOCS_SLUG}/" | |
| git config user.name "mows-docs-bot" | |
| git config user.email "mows-docs-bot@users.noreply.github.com" | |
| git add "${DOCS_SLUG}" | |
| if git diff --staged --quiet; then | |
| echo "No changes to publish (build is byte-identical to the live site)." | |
| exit 0 | |
| fi | |
| SHORT_SHA="${SOURCE_SHA:0:7}" | |
| git commit -m "docs(${DOCS_SLUG}): publish ${SHORT_SHA}" | |
| # Retry on push rejection — another docs workflow (e.g. a sibling | |
| # project) may have pushed concurrently. We only touch our own | |
| # subdir, so a rebase is always trivial; bail after a few tries | |
| # to avoid burning runner time on a genuinely broken state. | |
| for attempt in 1 2 3 4 5; do | |
| if git push origin HEAD:main; then | |
| echo "Published ${DOCS_SLUG}@${SHORT_SHA} -> ${PAGES_REPO}" | |
| exit 0 | |
| fi | |
| echo "Push attempt ${attempt} rejected; rebasing on latest main…" | |
| git fetch --depth 1 origin main | |
| git rebase origin/main | |
| done | |
| echo "::error::Failed to push after 5 attempts." | |
| exit 1 |