stream: add (SSE) suffix to title #15
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 AsyncAPI docs to GitHub Pages | |
| on: | |
| push: | |
| branches: [master] | |
| paths: | |
| - 'reference/ldap-subscriber-api-stream.yaml' | |
| - 'reference/ldap-subscriber-api.yaml' | |
| - 'docs/**' | |
| - '.github/workflows/pages.yml' | |
| workflow_dispatch: | |
| permissions: | |
| contents: read | |
| pages: write | |
| id-token: write | |
| concurrency: | |
| group: pages | |
| cancel-in-progress: false | |
| jobs: | |
| build: | |
| name: Render AsyncAPI HTML | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v5 | |
| with: | |
| # Need history + tags for `git describe`-derived version. | |
| fetch-depth: 0 | |
| - uses: actions/setup-node@v5 | |
| with: | |
| node-version: '24' | |
| - name: Compute version | |
| id: version | |
| run: | | |
| sha=$(git rev-parse --short HEAD) | |
| if last_tag=$(git describe --tags --abbrev=0 2>/dev/null); then | |
| count=$(git rev-list "${last_tag}..HEAD" --count) | |
| else | |
| count=$(git rev-list --count HEAD) | |
| fi | |
| # Drop a leading `v` from the tag if present so it composes | |
| # cleanly with the .<count>+<sha> suffix. | |
| base=${last_tag:-1.0} | |
| base=${base#v} | |
| version="${base}-${count}+${sha}" | |
| echo "version=$version" >> "$GITHUB_OUTPUT" | |
| echo "Computed version: $version" | |
| - name: Stamp version into spec | |
| run: | | |
| python3 - <<'PY' | |
| import os, re | |
| v = os.environ['VERSION'] | |
| p = 'reference/ldap-subscriber-api-stream.yaml' | |
| s = open(p).read() | |
| s = re.sub(r"^(\s*version:\s*).*$", lambda m: f"{m.group(1)}'{v}'", s, count=1, flags=re.M) | |
| open(p, 'w').write(s) | |
| print('stamped', v) | |
| PY | |
| env: | |
| VERSION: ${{ steps.version.outputs.version }} | |
| - name: Generate AsyncAPI site | |
| # Output goes under sse/ so the AsyncAPI docs are reachable at | |
| # /sse/ behind a landing page that links to both REST and | |
| # streaming references. Runs from reference/ so cross-file | |
| # $refs in the AsyncAPI doc (e.g. | |
| # './ldap-subscriber-api.yaml#/components/schemas/subscriber') | |
| # resolve relative to the AsyncAPI file rather than to cwd. | |
| run: | | |
| cd reference | |
| npx -y @asyncapi/cli@latest generate fromTemplate \ | |
| ldap-subscriber-api-stream.yaml \ | |
| @asyncapi/html-template@latest \ | |
| --output ../_site/sse \ | |
| --force-write | |
| - name: Assemble landing page | |
| # Copy the hand-written landing page + logo into the root of | |
| # the published site. The Pages root lands the user on the | |
| # landing page; AsyncAPI docs live under /sse/. | |
| run: | | |
| cp docs/index.html _site/index.html | |
| cp docs/logo.png _site/logo.png | |
| - name: Cache-bust assets and add no-cache meta | |
| # GitHub Pages can't set real HTTP cache headers, so we do | |
| # two things in the HTML itself: | |
| # 1. append ?v=<sha> to every script/link src so each deploy | |
| # uses a unique URL (defeats stale browser caches), | |
| # 2. add a Cache-Control meta tag so browsers revalidate | |
| # index.html on every load. | |
| # Target the AsyncAPI page; the landing page is plain HTML | |
| # with no asset references worth busting. | |
| run: | | |
| python3 - <<'PY' | |
| import os, re | |
| sha = os.environ['SHA'] | |
| p = '_site/sse/index.html' | |
| s = open(p).read() | |
| def bust(m): | |
| attr, url = m.group(1), m.group(2) | |
| if '?' in url: | |
| return m.group(0) | |
| return f'{attr}="{url}?v={sha}"' | |
| s = re.sub(r'(src|href)="(js/[^"]+|css/[^"]+)"', bust, s) | |
| meta = ( | |
| '<meta http-equiv="Cache-Control" ' | |
| 'content="no-cache, no-store, must-revalidate" />' | |
| '<meta http-equiv="Pragma" content="no-cache" />' | |
| '<meta http-equiv="Expires" content="0" />' | |
| ) | |
| s = s.replace('<head>', '<head>' + meta, 1) | |
| open(p, 'w').write(s) | |
| print('bust applied with sha=', sha) | |
| PY | |
| env: | |
| SHA: ${{ steps.version.outputs.version }} | |
| - name: Auto-expand collapsibles | |
| # The html-template ships with most disclosure widgets closed. | |
| # Inject a small script that opens everything once the page | |
| # finishes loading. Tries multiple selectors because the | |
| # template mixes native <details> with custom accordions. | |
| run: | | |
| cat >> _site/sse/index.html <<'HTML' | |
| <script> | |
| (function () { | |
| function expandAll() { | |
| document.querySelectorAll('details').forEach(function (d) { d.open = true; }); | |
| document.querySelectorAll('[aria-expanded="false"]').forEach(function (el) { | |
| try { el.click(); } catch (e) { /* swallow */ } | |
| }); | |
| } | |
| // The template renders client-side, so the DOM keeps mutating | |
| // for a moment after load. Run once on DOMContentLoaded, then | |
| // a few more times to catch late additions. | |
| if (document.readyState === 'loading') { | |
| document.addEventListener('DOMContentLoaded', expandAll); | |
| } else { | |
| expandAll(); | |
| } | |
| [50, 200, 600, 1500].forEach(function (t) { setTimeout(expandAll, t); }); | |
| new MutationObserver(expandAll).observe(document.body, { | |
| childList: true, subtree: true, | |
| }); | |
| })(); | |
| </script> | |
| HTML | |
| - uses: actions/upload-pages-artifact@v3 | |
| with: | |
| path: _site | |
| deploy: | |
| name: Deploy to Pages | |
| needs: build | |
| runs-on: ubuntu-latest | |
| environment: | |
| name: github-pages | |
| url: ${{ steps.deployment.outputs.page_url }} | |
| steps: | |
| - id: deployment | |
| uses: actions/deploy-pages@v4 |