diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index bfe7ffe..fb35384 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -25,6 +25,9 @@ jobs: cache: npm - run: npm ci - run: npm run build + # The site moved to https://refract-org.github.io/refract/, built from + # apps/docs in refract-org/refract. Publish only redirects from here. + - run: node redirects.mjs - uses: actions/configure-pages@v6 - uses: actions/upload-pages-artifact@v5 with: diff --git a/README.md b/README.md index 88a2cc7..d826168 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,19 @@ # Refract Docs +> **This repository has moved.** The documentation source is now +> [`apps/docs`](https://github.com/refract-org/refract/tree/main/apps/docs) in +> [refract-org/refract](https://github.com/refract-org/refract), imported with +> its full history, and the site is published at +> [refract-org.github.io/refract](https://refract-org.github.io/refract/). +> Open issues and pull requests there. This repository publishes only redirects: +> each page under `refract-org.github.io/refract-docs/` sends you to the same +> page at the new address (see `redirects.mjs`). + Public documentation for [Refract](https://github.com/refract-org/refract), a deterministic observation engine for public revision histories. --- -**Live at:** [refract-org.github.io/refract-docs](https://refract-org.github.io/refract-docs/) +**Live at:** [refract-org.github.io/refract](https://refract-org.github.io/refract/) ## Quick start diff --git a/redirects.mjs b/redirects.mjs new file mode 100644 index 0000000..2dca5b6 --- /dev/null +++ b/redirects.mjs @@ -0,0 +1,85 @@ +// Turns the built site in dist/ into a redirect-only site. +// +// The documentation now lives in the refract repository (apps/docs) and is +// published at https://refract-org.github.io/refract/. Run after +// `npm run build`: every page under /refract-docs/ is replaced by one that +// sends the reader to the same page at the new address, keeping any query and +// fragment. Everything that is not a page (images, the notebook, the sitemap) +// stays where it was, so a link straight to an image keeps working. 404.html +// catches any other path, which GitHub Pages serves for a missing one. +import { readdir, writeFile } from "node:fs/promises"; +import { dirname, join, posix, relative, sep } from "node:path"; +import { fileURLToPath } from "node:url"; + +const DIST = join(dirname(fileURLToPath(import.meta.url)), "dist"); +const OLD_BASE = "/refract-docs/"; +const NEW_SITE = "https://refract-org.github.io/refract/"; + +async function* files(dir) { + for (const entry of await readdir(dir, { withFileTypes: true })) { + const path = join(dir, entry.name); + if (entry.isDirectory()) yield* files(path); + else yield path; + } +} + +function escapeAttribute(value) { + return value + .replaceAll("&", "&") + .replaceAll('"', """) + .replaceAll("<", "<"); +} + +function page(target, script) { + const href = escapeAttribute(target); + return ` + + + + +Refract documentation has moved + + + + + +

The Refract documentation has moved to ${href}.

+ + +`; +} + +let redirected = 0; +for await (const path of files(DIST)) { + const rel = relative(DIST, path).split(sep).join(posix.sep); + if (!rel.endsWith(".html")) continue; + const target = + rel === "index.html" + ? NEW_SITE + : rel.endsWith("/index.html") + ? `${NEW_SITE}${rel.slice(0, -"index.html".length)}` + : `${NEW_SITE}${rel}`; + await writeFile( + path, + page( + target, + `location.replace(${JSON.stringify(target)} + location.search + location.hash);`, + ), + ); + redirected++; +} + +const prefix = JSON.stringify(OLD_BASE.slice(0, -1)); +await writeFile( + join(DIST, "404.html"), + page( + NEW_SITE, + `var path = location.pathname; +if (path.indexOf(${prefix}) === 0) path = path.slice(${prefix}.length); +location.replace(${JSON.stringify(NEW_SITE.slice(0, -1))} + path + location.search + location.hash);`, + ), +); + +console.log( + `Replaced ${redirected} pages with redirects to ${NEW_SITE} and wrote 404.html.`, +);