Fix grammar in projector.md #144
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: publishing | |
| on: | |
| push: | |
| branches: | |
| # `main` is the ONLY publishing branch. It declares everything it | |
| # publishes in docs-version.yml, including the RIDDL 1.x maintenance | |
| # line, which lives in sites/riddl-1x/ rather than on a branch of its own | |
| # (TASK G, 2026-07-31). Work branches are deliberately absent: work in | |
| # progress must not refresh the production site. | |
| - main | |
| permissions: | |
| contents: write | |
| # Kept even though only one branch publishes now. Two pushes to main in quick | |
| # succession still start two runs, both committing to gh-pages, and the second | |
| # would be rejected with "fetch first" -- its deploy silently lost. That | |
| # happened for real when main and docs/1.x were pushed seconds apart. | |
| # | |
| # cancel-in-progress is deliberately FALSE: these runs publish, so cancelling | |
| # one drops a deploy rather than deferring it. | |
| # | |
| # Do NOT reach for mike's --ignore-remote-status as a workaround. It does not | |
| # serialise anything; it just overwrites whatever the other run published. | |
| concurrency: | |
| group: gh-pages-deploy | |
| cancel-in-progress: false | |
| jobs: | |
| deploy: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| # mike commits into the gh-pages branch, so its history must be | |
| # present locally. The default shallow checkout does not fetch it. | |
| fetch-depth: 0 | |
| - name: Configure Git Credentials | |
| run: | | |
| git config user.name github-actions[bot] | |
| git config user.email 41898282+github-actions[bot]@users.noreply.github.com | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: 3.x | |
| - run: echo "cache_id=$(date --utc '+%V')" >> $GITHUB_ENV | |
| - uses: actions/cache@v4 | |
| with: | |
| key: mkdocs-material-${{ env.cache_id }} | |
| path: .cache | |
| restore-keys: | | |
| mkdocs-material- | |
| - run: pip install -r requirements.txt | |
| - run: pip install -e . | |
| # Shared logos and CSS live once in common/ and are copied into each | |
| # sub-site's docs tree. The copies are gitignored, so this is required | |
| # before any build -- without it every page loses its stylesheet. | |
| - name: Sync shared assets | |
| run: ./scripts/sync-shared-assets.sh | |
| # Cross-site links are absolute, so MkDocs treats them as external and | |
| # never checks them. --strict proves the intra-site links; this proves | |
| # the rest. Run before deploying anything. | |
| - name: Check cross-site links | |
| run: python3 scripts/check-cross-site-links.py | |
| - name: Deploy each versioned sub-site | |
| run: | | |
| python - <<'PY' > /tmp/deploy.sh | |
| import yaml, shlex | |
| cfg = yaml.safe_load(open("docs-version.yml")) | |
| for s in cfg.get("sites") or []: | |
| url = f"https://ossum.tech/{s['prefix']}/{s['version']}/" | |
| args = " ".join(shlex.quote(a) for a in (s.get("aliases") or [])) | |
| # --alias-type copy is REQUIRED, not a preference. mike's default | |
| # is `symlink`, and GitHub Pages does not serve symlinked content | |
| # -- so /riddl/latest/... would 404 in production while working | |
| # perfectly under a local `python -m http.server`, which DOES | |
| # follow symlinks. A passing local rehearsal cannot catch it. | |
| print(f"echo '--> {s['prefix']} {s['version']} [{args}]'") | |
| print(f"DOCS_SITE_URL={shlex.quote(url)} mike deploy --push " | |
| f"--update-aliases --alias-type copy " | |
| f"--deploy-prefix {shlex.quote(s['prefix'])} " | |
| f"-F {shlex.quote(s['config'])} " | |
| f"{shlex.quote(s['version'])} {args}") | |
| # Point <prefix>/index.html at this product's default alias. | |
| # NEVER run set-default without --deploy-prefix: it would write a | |
| # redirect over the shell's index.html at the site root. | |
| # -F is required too -- set-default reads mkdocs.yml from the | |
| # working directory to resolve the remote and branch, and there | |
| # is no config at the repo root any more. | |
| default = (s.get("aliases") or [s["version"]])[0] | |
| print(f"mike set-default --push --deploy-prefix " | |
| f"{shlex.quote(s['prefix'])} -F {shlex.quote(s['config'])} " | |
| f"{shlex.quote(default)}") | |
| PY | |
| cat /tmp/deploy.sh | |
| bash -euo pipefail /tmp/deploy.sh | |
| # The shell is not versioned, so mike is not involved. It is built and | |
| # committed to the gh-pages root, touching only the paths it owns -- | |
| # never the product prefixes or their versions.json. | |
| - name: Deploy the shell and rebuild the search index | |
| run: | | |
| git fetch origin gh-pages | |
| git worktree add /tmp/ghp origin/gh-pages | |
| # The shell is only published by the branch that declares it. Every | |
| # other branch skips this part but still reaches the indexing step | |
| # below -- see the comment there for why that matters. | |
| SHELL_CFG=$(python -c "import yaml;c=yaml.safe_load(open('docs-version.yml'));print((c.get('shell') or {}).get('config',''))") | |
| if [ -n "$SHELL_CFG" ]; then | |
| DOCS_SITE_URL=https://ossum.tech/ mkdocs build -f "$SHELL_CFG" -d /tmp/shell | |
| # rsync --delete, NOT cp. `cp -r` only ever adds, so a page deleted | |
| # from the shell stayed on gh-pages forever -- /coming-soon/ and | |
| # /find/ both kept serving 200 after being removed from the source. | |
| # | |
| # The excludes are what make --delete safe at the site root: they | |
| # cover everything the shell does NOT own -- the product prefixes | |
| # published by mike, the generated search index and robots.txt, the | |
| # 404 handler copied in below, and the worktree's own .git file. | |
| # Getting this list wrong deletes another product's entire site, | |
| # so add a new prefix here whenever one is added to docs-version.yml. | |
| rsync -a --delete \ | |
| --exclude '/riddl/' --exclude '/riddlg/' --exclude '/synapify/' \ | |
| --exclude '/pagefind/' --exclude '/robots.txt' \ | |
| --exclude '/404.html' --exclude '/.nojekyll' --exclude '/.git' \ | |
| /tmp/shell/ /tmp/ghp/ | |
| # Copied after, deliberately: the shell build emits its own 404.html | |
| # and this one -- which redirects legacy unversioned links -- wins. | |
| cp scripts/gh-pages-404.html /tmp/ghp/404.html | |
| else | |
| echo "This branch does not publish the shell." | |
| fi | |
| # The cross-site index is rebuilt on EVERY publishing branch, not | |
| # just the one that owns the shell. It indexes each product's | |
| # `latest` alias, and docs/1.x owns riddl/latest -- so if this only | |
| # ran where the shell is built, a docs/1.x push would update the | |
| # published pages while search kept returning their old text, with | |
| # nothing to indicate the index had gone stale. | |
| "$GITHUB_WORKSPACE/scripts/build-search-index.sh" /tmp/ghp | |
| # robots.txt is generated for the same reason: each build writes its | |
| # own sitemap.xml inside its own version directory, and nothing at the | |
| # root references them. A hand-written file would stop listing new | |
| # versions the day after it was written. | |
| "$GITHUB_WORKSPACE/scripts/build-robots-txt.sh" /tmp/ghp | |
| cd /tmp/ghp | |
| git add -A | |
| if git diff --cached --quiet; then | |
| echo "Shell and search index unchanged." | |
| else | |
| git commit -m "Deploy the shell and refresh the cross-site search index" | |
| git push origin HEAD:gh-pages | |
| fi |