Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions .github/workflows/deploy-docs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
name: deploy-docs

on:
workflow_dispatch:

permissions:
contents: read

concurrency:
group: github-pages
cancel-in-progress: false

jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read
pages: read
steps:
- name: Checkout
uses: actions/checkout@v7
- name: Read GitHub Pages configuration
id: pages
uses: actions/configure-pages@v5
- name: Build and upload the website
uses: withastro/action@v6
with:
path: website
node-version: 24
env:
SITE_URL: ${{ steps.pages.outputs.origin }}
SITE_BASE: ${{ steps.pages.outputs.base_path }}

deploy:
needs: build
runs-on: ubuntu-latest
permissions:
pages: write
id-token: write
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v5
41 changes: 41 additions & 0 deletions .github/workflows/website.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
name: Website

on:
pull_request:
branches: [main]
paths:
- 'website/**'
- '.github/workflows/website.yml'
push:
branches: [main]
paths:
- 'website/**'
- '.github/workflows/website.yml'

permissions:
contents: read

concurrency:
group: website-${{ github.ref }}
cancel-in-progress: true

jobs:
check:
runs-on: ubuntu-latest
defaults:
run:
working-directory: website
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
with:
package_json_file: website/package.json
- uses: actions/setup-node@v4
with:
node-version: 24
cache: pnpm
cache-dependency-path: website/pnpm-lock.yaml
- run: pnpm install --frozen-lockfile
- run: pnpm build
- run: pnpm exec playwright install --with-deps chromium
- run: pnpm test
8 changes: 8 additions & 0 deletions website/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
node_modules/
dist/
.astro/
.env
.env.*
!.env.example
test-results/
playwright-report/
97 changes: 97 additions & 0 deletions website/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
# Keryx website

One static Astro project: a custom landing page at `/` and Starlight documentation at `/docs/`.

## Development

Use Node.js 24 and the pnpm version pinned in `package.json`.

```sh
cd website
pnpm install --frozen-lockfile
pnpm dev
```

The development server normally listens on `http://localhost:4321`. Starlight search is indexed during production builds, so test search with `pnpm preview` after building.

## Build and verify

```sh
pnpm build
pnpm exec playwright install chromium
pnpm test
```

`build` runs Astro's type checker and creates the static site in `dist/`. Browser tests start a separate preview on port 4329 and check colour modes, persistence between the landing page and docs, blocked storage, mobile layout and search. Set `PLAYWRIGHT_CHROMIUM_EXECUTABLE` to reuse an existing compatible Chromium installation.

## Production URL

Set `SITE_URL` to the final public HTTPS origin when building:

```sh
SITE_URL=https://your-domain.example pnpm build
```

This sets canonical URLs and enables Starlight's sitemap. Without it, local builds still work, but the sitemap is skipped. Serve `dist/` with a static host that supports directory index files and uses `404.html` for missing routes. No backend or deployment credentials are required to build.

## GitHub Pages

`.github/workflows/deploy-docs.yml` publishes both the landing page and docs.
It only runs via **workflow_dispatch**. Pushes, pull requests and releases do
not deploy. The separate `website.yml` workflow only builds and tests.

1. Make the website files, lockfile and workflow available on the default
branch through your normal review process. GitHub requires a dispatch
workflow on the default branch before it appears in the Actions UI.
Adding it does not trigger deployment.
2. Open repository **Settings → Pages → Build and deployment**. Set
**Source** to **GitHub Actions**.
3. Check **Settings → Environments → github-pages**. Its deployment branch
rules must allow the branch you intend to publish. Keep any required
reviewers you want.
4. Open **Actions → deploy-docs → Run workflow**. Select the branch you want
to publish, then run it. This replaces the published website with that
branch's build. The deployment job reports the resulting URL.

The workflow uses `withastro/action@v6` with `path: website`, Node 24 and
the pnpm version pinned in `package.json`. It builds and uploads the static
artifact, then `actions/deploy-pages@v5` publishes it. No PAT, extra secrets,
repository variables, or `gh-pages` branch are needed.

`actions/configure-pages` reads the configured Pages origin and base path.
The build passes these as `SITE_URL` and `SITE_BASE`, so the GitHub project
URL and a later custom domain both work. To reproduce the project URL locally:

```sh
SITE_URL=https://simcubeltd.github.io SITE_BASE=/keryx pnpm build
SITE_URL=https://simcubeltd.github.io SITE_BASE=/keryx pnpm test
```

Keep handwritten Markdown links relative, and use `import.meta.env.BASE_URL`
for landing-page and custom component links and assets. Starlight handles
its generated navigation and assets.

### Optional custom domain later

In **Settings → Pages**, add the chosen custom domain. For
`keryx.simcube.co.uk`, add a DNS CNAME record for `keryx` pointing to
`simcubeltd.github.io`, with no repository path. Wait for GitHub's DNS and
certificate checks, then enable **Enforce HTTPS** when available. Manually
run `deploy-docs` again so canonical links and the sitemap use the new
domain. For an Actions deployment, GitHub manages the domain through Pages
settings; a committed `public/CNAME` file is not required.

References: [Astro action](https://github.com/withastro/action),
[GitHub Pages workflows](https://docs.github.com/en/pages/getting-started-with-github-pages/using-custom-workflows-with-github-pages),
[manual workflow runs](https://docs.github.com/en/actions/managing-workflow-runs-and-deployments/managing-workflow-runs/manually-running-a-workflow),
[custom domains](https://docs.github.com/en/pages/configuring-a-custom-domain-for-your-github-pages-site/managing-a-custom-domain-for-your-github-pages-site).

## Content and styling

- `src/pages/index.astro` owns the landing page.
- `src/content/docs/docs/` holds usage documentation. The nested `docs` directory creates the URL prefix.
- `src/styles/theme.css` supplies shared colours and self-hosted fonts.
- `src/styles/landing.css` styles the landing page; `docs.css` maps the theme into Starlight.
- `ThemeProvider.astro` and `ThemeSelect.astro` are shared by both parts of the site. Auto follows the system and is the default. Explicit choices persist in local storage.

Keep usage commands and documented defaults aligned with the repository README and CLI. The logo in `public/favicon.svg` is copied from `crates/keryx-render/assets/keryx-logo.svg`; update the copy when that asset changes.
30 changes: 30 additions & 0 deletions website/astro.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { defineConfig } from 'astro/config';
import starlight from '@astrojs/starlight';

export default defineConfig({
site: process.env.SITE_URL,
base: process.env.SITE_BASE || '/',
output: 'static',
trailingSlash: 'always',
integrations: [
starlight({
title: 'Keryx',
description: 'Self-hosted publishing for agents. Publish HTML documents, keep every version, and export PDFs.',
favicon: '/favicon.svg',
social: [{ icon: 'github', label: 'GitHub', href: 'https://github.com/SimCubeLtd/keryx' }],
customCss: ['./src/styles/theme.css', './src/styles/docs.css'],
components: {
ThemeProvider: './src/components/ThemeProvider.astro',
ThemeSelect: './src/components/ThemeSelect.astro',
SiteTitle: './src/components/DocsTitle.astro',
},
sidebar: [
{ label: 'Keryx', link: '/' },
{ label: 'Start here', items: ['docs', 'docs/installation', 'docs/quickstart', 'docs/skills', 'docs/agents'] },
{ label: 'Publish and manage', items: ['docs/versions', 'docs/pdf', 'docs/availability', 'docs/sharing'] },
{ label: 'Run Keryx', items: ['docs/configuration', 'docs/storage', 'docs/html-policy'] },
{ label: 'Reference', items: ['docs/cli'] },
],
}),
],
});
30 changes: 30 additions & 0 deletions website/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"name": "keryx-website",
"version": "0.1.0",
"private": true,
"type": "module",
"scripts": {
"dev": "astro dev",
"build": "astro check && astro build",
"preview": "astro preview",
"check": "astro check",
"test": "playwright test"
},
"dependencies": {
"@astrojs/markdown-remark": "^7.3.0",
"@astrojs/starlight": "^0.42.0",
"@fontsource-variable/inter": "^5.2.8",
"@fontsource-variable/jetbrains-mono": "^5.2.8",
"@fontsource-variable/plus-jakarta-sans": "^5.2.8",
"astro": "^7.2.10"
},
"devDependencies": {
"@astrojs/check": "^0.9.4",
"@playwright/test": "^1.63.0",
"typescript": "^5.9.0"
},
"engines": {
"node": ">=22.12.0"
},
"packageManager": "pnpm@11.22.0"
}
14 changes: 14 additions & 0 deletions website/playwright.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { defineConfig } from '@playwright/test';

export default defineConfig({
testDir: './tests',
use: {
baseURL: 'http://127.0.0.1:4329',
launchOptions: { executablePath: process.env.PLAYWRIGHT_CHROMIUM_EXECUTABLE },
},
webServer: {
command: 'node tests/preview.mjs',
url: 'http://127.0.0.1:4329' + (process.env.SITE_BASE || '') + '/',
reuseExistingServer: false,
},
});
Loading
Loading