From a8527cd5b3738a04488340e1e5f99ba456af457b Mon Sep 17 00:00:00 2001 From: Thomas Pinder Date: Sat, 1 Aug 2026 23:44:07 +0200 Subject: [PATCH 1/2] docs: serve the documentation from docs.quantclimate.com Repoints the published docs at docs.quantclimate.com. GitHub Pages serves exactly one custom domain per site, so this is a move rather than an addition. - docs/CNAME and html_baseurl, which between them drive the Pages custom domain, the sitemap, the canonical link, og:url and the absolute og:image URL. All four were verified in a clean build. - The Documentation URL in pyproject.toml and the 15 documentation links in README.md. Deliberately NOT changed: the three https://jaxgaussianprocesses.com/contact/ links in README.md, GOVERNANCE.md and CODE_OF_CONDUCT.md. That is the separate marketing site, not the docs host. The 87 sphinx-reredirects entries are unaffected: their targets are written site-absolute, so they resolve against whatever domain serves them. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01QXcSotTJspF11tgaJfrXrZ --- README.md | 30 +++++++++++++++--------------- docs/CNAME | 2 +- docs/conf.py | 7 +++++-- pyproject.toml | 2 +- 4 files changed, 22 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index d99d4ed32..10c4acaed 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ [**Quickstart**](#simple-example) | [**Install guide**](#installation) -| [**Documentation**](https://docs.jaxgaussianprocesses.com/) +| [**Documentation**](https://docs.quantclimate.com/) | [**Slack Community**](https://join.slack.com/t/gpjax/shared_invite/zt-3cesiykcx-nzajjRdnV3ohw7~~eMlCYA) GPJax aims to provide a low-level interface to Gaussian process (GP) models in @@ -47,7 +47,7 @@ As a contributor to GPJax, you are expected to abide by our [code of conduct](docs/CODE_OF_CONDUCT.md). If you feel that you have either experienced or witnessed behaviour that violates this standard, then we ask that you report any such behaviours through [this form](https://jaxgaussianprocesses.com/contact/) or reach out to -one of the project's [_gardeners_](https://docs.jaxgaussianprocesses.com/GOVERNANCE.html#roles). +one of the project's [_gardeners_](https://docs.quantclimate.com/GOVERNANCE.html#roles). Feel free to join our [Slack Channel](https://join.slack.com/t/gpjax/shared_invite/zt-3cesiykcx-nzajjRdnV3ohw7~~eMlCYA), @@ -62,22 +62,22 @@ GPJax into the package it is today. ## Notebook examples -> - [**Conjugate Inference**](https://docs.jaxgaussianprocesses.com/examples/regression.html) -> - [**Classification**](https://docs.jaxgaussianprocesses.com/examples/classification.html) -> - [**Sparse Variational Inference**](https://docs.jaxgaussianprocesses.com/examples/collapsed_vi.html) -> - [**Stochastic Variational Inference**](https://docs.jaxgaussianprocesses.com/examples/uncollapsed_vi.html) -> - [**Laplace Approximation**](https://docs.jaxgaussianprocesses.com/examples/classification.html#laplace-approximation) -> - [**Inference on Non-Euclidean Spaces**](https://docs.jaxgaussianprocesses.com/examples/constructing_new_kernels.html#custom-kernel) -> - [**Inference on Graphs**](https://docs.jaxgaussianprocesses.com/examples/graph_kernels.html) -> - [**Heteroscedastic Inference**](https://docs.jaxgaussianprocesses.com/examples/heteroscedastic_inference.html) -> - [**Learning Gaussian Process Barycentres**](https://docs.jaxgaussianprocesses.com/examples/barycentres.html) -> - [**Deep Kernel Regression**](https://docs.jaxgaussianprocesses.com/examples/deep_kernels.html) -> - [**Poisson Regression**](https://docs.jaxgaussianprocesses.com/examples/poisson.html) +> - [**Conjugate Inference**](https://docs.quantclimate.com/examples/regression.html) +> - [**Classification**](https://docs.quantclimate.com/examples/classification.html) +> - [**Sparse Variational Inference**](https://docs.quantclimate.com/examples/collapsed_vi.html) +> - [**Stochastic Variational Inference**](https://docs.quantclimate.com/examples/uncollapsed_vi.html) +> - [**Laplace Approximation**](https://docs.quantclimate.com/examples/classification.html#laplace-approximation) +> - [**Inference on Non-Euclidean Spaces**](https://docs.quantclimate.com/examples/constructing_new_kernels.html#custom-kernel) +> - [**Inference on Graphs**](https://docs.quantclimate.com/examples/graph_kernels.html) +> - [**Heteroscedastic Inference**](https://docs.quantclimate.com/examples/heteroscedastic_inference.html) +> - [**Learning Gaussian Process Barycentres**](https://docs.quantclimate.com/examples/barycentres.html) +> - [**Deep Kernel Regression**](https://docs.quantclimate.com/examples/deep_kernels.html) +> - [**Poisson Regression**](https://docs.quantclimate.com/examples/poisson.html) ## Guides for customisation > -> - [**Custom kernels**](https://docs.jaxgaussianprocesses.com/examples/constructing_new_kernels.html#custom-kernel) -> - [**UCI regression**](https://docs.jaxgaussianprocesses.com/examples/yacht.html) +> - [**Custom kernels**](https://docs.quantclimate.com/examples/constructing_new_kernels.html#custom-kernel) +> - [**UCI regression**](https://docs.quantclimate.com/examples/yacht.html) ## Conversion between `.ipynb` and `.py` Above examples are stored in [examples](docs/examples) directory in the double diff --git a/docs/CNAME b/docs/CNAME index a4878b9df..0df52cb58 100644 --- a/docs/CNAME +++ b/docs/CNAME @@ -1 +1 @@ -docs.jaxgaussianprocesses.com +docs.quantclimate.com diff --git a/docs/conf.py b/docs/conf.py index 2e16ea00c..5fdd1267a 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -295,7 +295,9 @@ # -- HTML output ------------------------------------------------------------- html_theme = "shibuya" html_title = "GPJax" -html_baseurl = "https://docs.jaxgaussianprocesses.com/" # for sitemap + canonical +# Sitemap, canonical link, og:url and the absolute og:image URL all derive from +# this, so it must match the domain GitHub Pages is actually serving (docs/CNAME). +html_baseurl = "https://docs.quantclimate.com/" sitemap_url_scheme = "{link}" html_static_path = ["stylesheets"] html_css_files = ["extra.css"] @@ -367,7 +369,8 @@ } # -- Redirects from the retired MkDocs site (sphinx-reredirects) ------------- -# docs.jaxgaussianprocesses.com served the MkDocs site with `use_directory_urls` +# The retired MkDocs site (then at docs.jaxgaussianprocesses.com) ran with +# `use_directory_urls` # (the default), so every old page lived at `/`, i.e. the file # `/index.html`. The keys below therefore end in `/index`, which is what # puts the emitted meta-refresh stub exactly where the old URL pointed. diff --git a/pyproject.toml b/pyproject.toml index 93c93d251..4eff63b23 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -120,7 +120,7 @@ dev = [ [project.urls] -Documentation = "https://docs.jaxgaussianprocesses.com/" +Documentation = "https://docs.quantclimate.com/" Issues = "https://github.com/thomaspinder/GPJax/issues" Source = "https://github.com/thomaspinder/GPJax" From 8c6c5d2fd3ebceed265a2dc40f13ce25d55e16cc Mon Sep 17 00:00:00 2001 From: Thomas Pinder Date: Sun, 2 Aug 2026 00:14:33 +0200 Subject: [PATCH 2/2] docs: use gpjax.quantclimate.com, and 301 the retired docs host Renames the target host from docs.quantclimate.com to gpjax.quantclimate.com, matching the .quantclimate.com convention that impulso will also use. Adds legacy-docs-redirect/, the complete contents of the Netlify site that keeps docs.jaxgaussianprocesses.com alive as a permanent redirect. GitHub Pages serves one custom domain per site and cannot answer for both hosts, so without this every published link to the old domain 404s -- the JOSS paper, the PyPI project page, search results and third-party citations. The rule is a bare wildcard carrying `:splat` through unchanged. That is deliberate: old MkDocs-era URLs are still in circulation and the new site ships 87 sphinx-reredirects stubs keyed on exactly those paths, so preserving the path lets the chain complete as legacy host -> new host -> stub -> final page. Rewriting paths in the redirect would break it. Deployed by hand, never by CI, and documented as such -- `--prod` belongs in that one manual command and must never reach the PR preview step, which uses `--alias` precisely so a pull request cannot overwrite a production deploy. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01QXcSotTJspF11tgaJfrXrZ --- README.md | 30 ++++++++--------- docs/CNAME | 2 +- docs/conf.py | 2 +- legacy-docs-redirect/README.md | 57 +++++++++++++++++++++++++++++++++ legacy-docs-redirect/_redirects | 18 +++++++++++ pyproject.toml | 2 +- 6 files changed, 93 insertions(+), 18 deletions(-) create mode 100644 legacy-docs-redirect/README.md create mode 100644 legacy-docs-redirect/_redirects diff --git a/README.md b/README.md index 10c4acaed..479a801c2 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ [**Quickstart**](#simple-example) | [**Install guide**](#installation) -| [**Documentation**](https://docs.quantclimate.com/) +| [**Documentation**](https://gpjax.quantclimate.com/) | [**Slack Community**](https://join.slack.com/t/gpjax/shared_invite/zt-3cesiykcx-nzajjRdnV3ohw7~~eMlCYA) GPJax aims to provide a low-level interface to Gaussian process (GP) models in @@ -47,7 +47,7 @@ As a contributor to GPJax, you are expected to abide by our [code of conduct](docs/CODE_OF_CONDUCT.md). If you feel that you have either experienced or witnessed behaviour that violates this standard, then we ask that you report any such behaviours through [this form](https://jaxgaussianprocesses.com/contact/) or reach out to -one of the project's [_gardeners_](https://docs.quantclimate.com/GOVERNANCE.html#roles). +one of the project's [_gardeners_](https://gpjax.quantclimate.com/GOVERNANCE.html#roles). Feel free to join our [Slack Channel](https://join.slack.com/t/gpjax/shared_invite/zt-3cesiykcx-nzajjRdnV3ohw7~~eMlCYA), @@ -62,22 +62,22 @@ GPJax into the package it is today. ## Notebook examples -> - [**Conjugate Inference**](https://docs.quantclimate.com/examples/regression.html) -> - [**Classification**](https://docs.quantclimate.com/examples/classification.html) -> - [**Sparse Variational Inference**](https://docs.quantclimate.com/examples/collapsed_vi.html) -> - [**Stochastic Variational Inference**](https://docs.quantclimate.com/examples/uncollapsed_vi.html) -> - [**Laplace Approximation**](https://docs.quantclimate.com/examples/classification.html#laplace-approximation) -> - [**Inference on Non-Euclidean Spaces**](https://docs.quantclimate.com/examples/constructing_new_kernels.html#custom-kernel) -> - [**Inference on Graphs**](https://docs.quantclimate.com/examples/graph_kernels.html) -> - [**Heteroscedastic Inference**](https://docs.quantclimate.com/examples/heteroscedastic_inference.html) -> - [**Learning Gaussian Process Barycentres**](https://docs.quantclimate.com/examples/barycentres.html) -> - [**Deep Kernel Regression**](https://docs.quantclimate.com/examples/deep_kernels.html) -> - [**Poisson Regression**](https://docs.quantclimate.com/examples/poisson.html) +> - [**Conjugate Inference**](https://gpjax.quantclimate.com/examples/regression.html) +> - [**Classification**](https://gpjax.quantclimate.com/examples/classification.html) +> - [**Sparse Variational Inference**](https://gpjax.quantclimate.com/examples/collapsed_vi.html) +> - [**Stochastic Variational Inference**](https://gpjax.quantclimate.com/examples/uncollapsed_vi.html) +> - [**Laplace Approximation**](https://gpjax.quantclimate.com/examples/classification.html#laplace-approximation) +> - [**Inference on Non-Euclidean Spaces**](https://gpjax.quantclimate.com/examples/constructing_new_kernels.html#custom-kernel) +> - [**Inference on Graphs**](https://gpjax.quantclimate.com/examples/graph_kernels.html) +> - [**Heteroscedastic Inference**](https://gpjax.quantclimate.com/examples/heteroscedastic_inference.html) +> - [**Learning Gaussian Process Barycentres**](https://gpjax.quantclimate.com/examples/barycentres.html) +> - [**Deep Kernel Regression**](https://gpjax.quantclimate.com/examples/deep_kernels.html) +> - [**Poisson Regression**](https://gpjax.quantclimate.com/examples/poisson.html) ## Guides for customisation > -> - [**Custom kernels**](https://docs.quantclimate.com/examples/constructing_new_kernels.html#custom-kernel) -> - [**UCI regression**](https://docs.quantclimate.com/examples/yacht.html) +> - [**Custom kernels**](https://gpjax.quantclimate.com/examples/constructing_new_kernels.html#custom-kernel) +> - [**UCI regression**](https://gpjax.quantclimate.com/examples/yacht.html) ## Conversion between `.ipynb` and `.py` Above examples are stored in [examples](docs/examples) directory in the double diff --git a/docs/CNAME b/docs/CNAME index 0df52cb58..9f0176801 100644 --- a/docs/CNAME +++ b/docs/CNAME @@ -1 +1 @@ -docs.quantclimate.com +gpjax.quantclimate.com diff --git a/docs/conf.py b/docs/conf.py index 5fdd1267a..200ead07b 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -297,7 +297,7 @@ html_title = "GPJax" # Sitemap, canonical link, og:url and the absolute og:image URL all derive from # this, so it must match the domain GitHub Pages is actually serving (docs/CNAME). -html_baseurl = "https://docs.quantclimate.com/" +html_baseurl = "https://gpjax.quantclimate.com/" sitemap_url_scheme = "{link}" html_static_path = ["stylesheets"] html_css_files = ["extra.css"] diff --git a/legacy-docs-redirect/README.md b/legacy-docs-redirect/README.md new file mode 100644 index 000000000..43312130b --- /dev/null +++ b/legacy-docs-redirect/README.md @@ -0,0 +1,57 @@ +# Legacy docs domain redirect + +The documentation moved to `gpjax.quantclimate.com` (GitHub Pages). This +directory is the entire contents of the Netlify site that keeps the **old** +host, `docs.jaxgaussianprocesses.com`, alive as a permanent redirect. + +It is not part of the docs build and is not deployed by CI. It is deployed by +hand, once, and then only again if the redirect target changes. + +## Why this exists + +GitHub Pages serves exactly one custom domain per site, so it cannot answer for +both hosts. Without this, every published link to the old domain 404s — the JOSS +paper, the PyPI project page, search results, and any third-party citation. + +## Deploying it + +> [!WARNING] +> Deploy this to the Netlify site that serves **`docs.jaxgaussianprocesses.com`**. +> That is a different site from the one serving the `jaxgaussianprocesses.com` +> apex and `www` (the marketing site). Deploying this bundle to the marketing +> site would replace it with a redirect to the GPJax docs. +> +> Confirm before deploying — `netlify sites:list`, then check which site claims +> the `docs.` subdomain under Domain management. + +The docs site is the same one this repo already uses for PR previews, i.e. the +site behind the `NETLIFY_SITE_ID` repository secret. + +```bash +npx --yes netlify-cli@latest deploy \ + --prod \ + --dir=legacy-docs-redirect \ + --site="" \ + --message="301 legacy docs host to gpjax.quantclimate.com" +``` + +`--prod` is correct **here** and only here: this is a deliberate, manual +replacement of that site's production deploy. It must never appear in +`.github/workflows/test_docs.yml`, whose preview step uses `--alias` so a pull +request can never overwrite a production deploy. + +Deploying this does not affect PR previews. Those are alias deploys at +`pr---.netlify.app` and are independent of the production deploy. + +## Verifying + +```bash +# Expect: 301, and a Location on the new host with the path preserved. +curl -sI https://docs.jaxgaussianprocesses.com/examples/regression.html \ + | grep -iE '^HTTP|^location' + +# Expect: the same, through an old MkDocs-era URL. The new site's reredirect +# stub then completes the hop to /examples/classification.html. +curl -sI https://docs.jaxgaussianprocesses.com/_examples/classification/ \ + | grep -iE '^HTTP|^location' +``` diff --git a/legacy-docs-redirect/_redirects b/legacy-docs-redirect/_redirects new file mode 100644 index 000000000..0ae70183b --- /dev/null +++ b/legacy-docs-redirect/_redirects @@ -0,0 +1,18 @@ +# Netlify redirect rules for the RETIRED docs host, docs.jaxgaussianprocesses.com. +# +# `:splat` carries the whole matched path across, so deep links survive: +# /examples/regression.html -> /examples/regression.html +# /_examples/classification/ -> /_examples/classification/ +# +# That second form matters. Old MkDocs URLs are still in the wild, and the new +# site ships 87 sphinx-reredirects stubs for exactly those paths — so the chain +# is: legacy host -> (301, path preserved) -> new host -> stub -> final page. +# Rewriting paths here would break that, which is why this is a bare wildcard. +# +# URL fragments are not sent to the server; browsers reattach them after a +# redirect, so `#laplace-approximation` style deep links survive too. +# +# `301!` — permanent, and the `!` forces the rule even if a file of the same +# name exists in the deploy. This directory contains no other files, so the +# force is belt-and-braces against a stale build lingering on the site. +/* https://gpjax.quantclimate.com/:splat 301! diff --git a/pyproject.toml b/pyproject.toml index 4eff63b23..98e6bbc66 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -120,7 +120,7 @@ dev = [ [project.urls] -Documentation = "https://docs.quantclimate.com/" +Documentation = "https://gpjax.quantclimate.com/" Issues = "https://github.com/thomaspinder/GPJax/issues" Source = "https://github.com/thomaspinder/GPJax"