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
10 changes: 8 additions & 2 deletions .github/workflows/site-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,20 @@ jobs:
with:
node-version: "22"
cache: npm
cache-dependency-path: package-lock.json
cache-dependency-path: |
package-lock.json
website/package-lock.json

- name: Install JS dependencies
run: npm ci

- name: Build web SPAs
run: npm run build

- name: Build documentation site
working-directory: website
run: npm ci && npm run build

- name: Prepare deploy bundle
run: |
set -euo pipefail
Expand All @@ -43,7 +49,7 @@ jobs:
mkdir -p _bundle/public/admin
cp -a web/dist/admin/. _bundle/public/admin/
mkdir -p _bundle/public/docs
cp -a web/dist/docs/. _bundle/public/docs/
cp -a website/dist/. _bundle/public/docs/
mkdir -p _bundle/worker
cp -a cloudflare_site/worker/. _bundle/worker/

Expand Down
6 changes: 6 additions & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
layout: page
title: Fullsend Docs
---

<meta http-equiv="refresh" content="0; url=guides/getting-started/">
File renamed without changes
File renamed without changes
10 changes: 5 additions & 5 deletions docs/site-deployment.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@

## Overview

This repository publishes a static documentation site. The root landing page is [`web/public/index.html`](../web/public/index.html); the interactive document graph is [`web/public/graph.html`](../web/public/graph.html) (served at `/graph.html`). **Vite** builds the **admin** SPA under **`web/dist/admin/`** (see [`web/admin/README.md`](../web/admin/README.md)). The **docs site** is built by **Docusaurus** from the **`website/`** directory, reading markdown from **`docs/`** and producing static HTML in **`website/build/`**. CI copies **`assets/`**, **`admin/`**, and **`docs/`** into **`_bundle/public/`** so the Worker serves **`/admin/`** and **`/docs/`** from the same static asset tree. OAuth/CORS hardening for that Worker is summarized in [`docs/admin-oauth-worker.md`](admin-oauth-worker.md) (path-specific CORS for `/api/github/user`, no separate “OAuth enabled” env flag).
This repository publishes a static documentation site. The root landing page is [`web/public/index.html`](../web/public/index.html); the interactive document graph is [`web/public/graph.html`](../web/public/graph.html) (served at `/graph.html`). **Vite** builds the **admin** SPA under **`web/dist/admin/`** (see [`web/admin/README.md`](../web/admin/README.md)). The **docs site** is built by **VitePress** from the **`website/`** directory, reading markdown from **`docs/`** and producing static HTML in **`website/dist/`**. CI copies **`assets/`**, **`admin/`**, and **`docs/`** into **`_bundle/public/`** so the Worker serves **`/admin/`** and **`/docs/`** from the same static asset tree. OAuth/CORS hardening for that Worker is summarized in [`docs/admin-oauth-worker.md`](admin-oauth-worker.md) (path-specific CORS for `/api/github/user`, no separate “OAuth enabled” env flag).

**Build Site** runs **`npm ci`** and **`npm run build`** at the repository root, then packs **`public/`** (static files, including `assets/` and `admin/` from `web/dist/`, plus `docs/` from `website/build/`) and **`worker/`** (TypeScript Worker from the same checkout—PR head on PR builds) under **`_bundle/`** in one artifact. **Deploy Site** checks out **only the default branch** (trusted [`cloudflare_site/wrangler.toml`](../cloudflare_site/wrangler.toml); never PR-controlled config on the secret-bearing runner), downloads the artifact to **`_bundle/`**, then **copies only** **`_bundle/public/`** and **`_bundle/worker/`** into **`cloudflare_site/`** (so a malicious artifact cannot overwrite `wrangler.toml` or other repo files), then runs Wrangler. Deployment uses **Cloudflare Workers with [static assets](https://developers.cloudflare.com/workers/static-assets/)** (not the legacy **Pages direct-upload** / `wrangler pages deploy` flow).
**Build Site** runs **`npm ci`** and **`npm run build`** at the repository root, then packs **`public/`** (static files, including `assets/` and `admin/` from `web/dist/`, plus `docs/` from `website/dist/`) and **`worker/`** (TypeScript Worker from the same checkout—PR head on PR builds) under **`_bundle/`** in one artifact. **Deploy Site** checks out **only the default branch** (trusted [`cloudflare_site/wrangler.toml`](../cloudflare_site/wrangler.toml); never PR-controlled config on the secret-bearing runner), downloads the artifact to **`_bundle/`**, then **copies only** **`_bundle/public/`** and **`_bundle/worker/`** into **`cloudflare_site/`** (so a malicious artifact cannot overwrite `wrangler.toml` or other repo files), then runs Wrangler. Deployment uses **Cloudflare Workers with [static assets](https://developers.cloudflare.com/workers/static-assets/)** (not the legacy **Pages direct-upload** / `wrangler pages deploy` flow).

Two GitHub Actions workflows:

- **Build Site** — on `pull_request` and `push` to `main`, checks out the PR head when relevant, installs Node dependencies, builds the admin SPA (Vite) and docs site (Docusaurus), assembles **`_bundle/public/`** and **`_bundle/worker/`**, uploads artifact **`site`** (`_bundle/` contents).
- **Build Site** — on `pull_request` and `push` to `main`, checks out the PR head when relevant, installs Node dependencies, builds the admin SPA (Vite) and docs site (VitePress), assembles **`_bundle/public/`** and **`_bundle/worker/`**, uploads artifact **`site`** (`_bundle/` contents).
- **Deploy Site** — on successful **Build Site** via `workflow_run`, checks out the repo default ref (trusted Wrangler project files), downloads artifact **`site`** into **`_bundle/`**, copies **`public/`** and **`worker/`** into **`cloudflare_site/`**, then:
- **push to `main`:** `wrangler deploy` → production Worker traffic.
- **pull_request:** `wrangler versions upload --preview-alias pr-<pr-number>` → preview URL on `*.workers.dev` without changing production (alias falls back to `pr-<workflow_run.id>` only when the same fork branch matches more than one open PR).
Expand Down Expand Up @@ -65,7 +65,7 @@ Disable **GitHub Pages** under **Settings → Pages** if it was only used for th

**Full stack (recommended for admin OAuth):** from the repository root, run **`npm run dev`** so Vite serves the SPA and Wrangler runs the site Worker with shared process env — see [`web/admin/README.md`](../web/admin/README.md).

**Static tree + Worker (closer to production asset layout):** install dependencies, build admin SPA and Docusaurus site, copy the same layout CI uses under `cloudflare_site/public/`, then run Wrangler:
**Static tree + Worker (closer to production asset layout):** install dependencies, build admin SPA and VitePress docs site, copy the same layout CI uses under `cloudflare_site/public/`, then run Wrangler:

```bash
npm ci
Expand All @@ -78,7 +78,7 @@ cp web/public/index.html cloudflare_site/public/index.html
cp web/public/graph.html cloudflare_site/public/graph.html
cp -a web/dist/assets/. cloudflare_site/public/assets/
cp -a web/dist/admin/. cloudflare_site/public/admin/
cp -a website/build/. cloudflare_site/public/docs/
cp -a website/dist/. cloudflare_site/public/docs/
cd cloudflare_site && npx wrangler@4 dev
```

Expand Down
14 changes: 7 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@
"build": "vite build",
"preview": "vite preview",
"test": "vitest run --config vite.config.ts && vitest run --config cloudflare_site/worker/vitest.config.mts",
"check": "svelte-check --tsconfig web/admin/tsconfig.json && svelte-check --tsconfig web/docs/tsconfig.json",
"lint": "eslint web/admin/src/ web/docs/src/",
"lint:fix": "eslint web/admin/src/ web/docs/src/ --fix",
"format": "prettier --write 'web/{admin,docs}/src/**/*.{svelte,ts,js,css}'",
"format:check": "prettier --check 'web/{admin,docs}/src/**/*.{svelte,ts,js,css}'",
"stylelint": "stylelint 'web/{admin,docs}/src/**/*.{svelte,css}'",
"stylelint:fix": "stylelint 'web/{admin,docs}/src/**/*.{svelte,css}' --fix"
"check": "svelte-check --tsconfig web/admin/tsconfig.json",
"lint": "eslint web/admin/src/",
"lint:fix": "eslint web/admin/src/ --fix",
"format": "prettier --write 'web/admin/src/**/*.{svelte,ts,js,css}'",
"format:check": "prettier --check 'web/admin/src/**/*.{svelte,ts,js,css}'",
"stylelint": "stylelint 'web/admin/src/**/*.{svelte,css}'",
"stylelint:fix": "stylelint 'web/admin/src/**/*.{svelte,css}' --fix"
},
"devDependencies": {
"@cloudflare/vitest-pool-workers": "^0.14.7",
Expand Down
12 changes: 0 additions & 12 deletions vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { normalizePath } from "vite";
import { svelte } from "@sveltejs/vite-plugin-svelte";
import { defineConfig } from "vitest/config";
import type { Plugin } from "vite";
import { fullsendDocsPlugin } from "./web/docs/build/vitePluginDocs";

const repoRoot = path.dirname(fileURLToPath(import.meta.url));
const webRoot = path.join(repoRoot, "web");
Expand All @@ -22,8 +21,6 @@ function spaFallbackPlugin(): Plugin {
req.url = "/index.html";
} else if (url.startsWith("/admin/") && !path.extname(url)) {
req.url = "/admin/index.html";
} else if (url.startsWith("/docs/") && !path.extname(url)) {
req.url = "/docs/index.html";
}
next();
});
Expand Down Expand Up @@ -94,11 +91,6 @@ export default defineConfig(({ command }) => ({
),
],
}),
svelte({
configFile: path.join(webRoot, "docs/svelte.config.js"),
include: normalizePath(path.join(webRoot, "docs/**/*.svelte")),
}),
fullsendDocsPlugin(repoRoot),
spaFallbackPlugin(),
adminDevEnvLogPlugin(),
adminRequestLogPlugin(),
Expand All @@ -107,7 +99,6 @@ export default defineConfig(({ command }) => ({
rollupOptions: {
input: {
admin: path.join(webRoot, "admin/index.html"),
docs: path.join(webRoot, "docs/index.html"),
},
},
},
Expand All @@ -118,11 +109,8 @@ export default defineConfig(({ command }) => ({
},
test: {
environment: "jsdom",
environmentMatchGlobs: [["docs/build/**/*.test.ts", "node"]],
include: [
"admin/src/**/*.test.ts",
"docs/build/**/*.test.ts",
"docs/src/**/*.test.ts",
],
passWithNoTests: true,
},
Expand Down
6 changes: 3 additions & 3 deletions website/.gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
node_modules/
build/
.docusaurus/
.playwright-cli/
dist/
.vitepress/cache/
.vitepress/.temp/
Loading
Loading