diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000..29ae45f --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,15 @@ +# Code owners for goceleris/docs. +# +# GitHub requests a review from the matching owner(s) on every pull request +# and, when the branch protection / ruleset for `main` requires code-owner +# review, blocks the merge until one of them approves. Later rules override +# earlier ones, so the catch-all comes first and area delegations go below it. +# +# Syntax: https://docs.github.com/articles/about-code-owners + +# Default: the repository owner reviews everything. +* @FumingPower3925 + +# Area delegation example (uncomment and adjust when a co-maintainer takes an +# area; the more specific path wins over the catch-all above): +# /src/content/docs/ @FumingPower3925 @WdnLiu diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..7bf72dd --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,56 @@ +version: 2 +updates: + # ----- Bun (Astro site) ----- + # The site is installed and run with Bun (`bun install --frozen-lockfile`, + # engines.bun >= 1.3) and its only lockfile is the text `bun.lock`; there + # is no package-lock.json. That rules out the `npm` ecosystem: it is + # dependabot-core's npm_and_yarn, which reads package-lock.json, yarn.lock + # and pnpm-lock.yaml but never bun.lock. Pointed at this repo it would see + # a manifest-only project, propose nothing for the ^-ranged deps until a + # new major shipped, and any PR it did open would edit package.json without + # refreshing bun.lock, so the frozen-lockfile install in the `build` CI job + # would fail. `bun` is its own ecosystem (Bun >= 1.1.39, text lockfile) that + # parses and rewrites bun.lock, so bumps land as reviewable PRs that the + # `build` job then installs, compiles, checks and tests. + # + # Caveat: `bun` supports version updates only, not security updates. A + # Dependabot alert on a JS dependency will not auto-generate a PR here; it + # is closed by the next weekly version PR or by a hand-made bump. + # + # Weekly cadence: this is a static site with no runtime server, so a daily + # dependency PR stream buys nothing. + # + # `typescript` is pinned EXACTLY to 6.0.3 on purpose: @astrojs/check breaks + # on TypeScript 7, and drifting the pin would silently ship the site with + # no type-check gate. Only patch releases of the 6.0 line may be proposed; + # a major or minor bump must be a deliberate, hand-made change. + - package-ecosystem: bun + directory: / + schedule: + interval: weekly + ignore: + - dependency-name: typescript + update-types: + - version-update:semver-major + - version-update:semver-minor + groups: + all-js-deps: + patterns: + - "*" + commit-message: + prefix: "deps" + + # ----- GitHub Actions ----- + # Every workflow pins its actions to a full commit SHA with a `# vX.Y.Z` + # trailer; this entry is what keeps those SHAs current. Group all action + # bumps into ONE PR per scheduled run. + - package-ecosystem: github-actions + directory: / + schedule: + interval: weekly + groups: + all-actions: + patterns: + - "*" + commit-message: + prefix: "ci" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..c5b2b04 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,57 @@ +name: CI + +# Pull-request / push gate for the site. Cloudflare Workers Builds is what +# actually deploys (`bun run build` on every push to `main`), but until this +# workflow existed nothing checked a PR *before* it reached `main` — a broken +# build only surfaced as a failed deploy. This job runs the same install and +# build as the deploy, plus `astro check` (types + content schema) and the +# data-layer tests, so a required status check named `build` can gate `main`. +# +# It is deliberately read-only: no deploy, no token use, no writes. + +on: + pull_request: + push: + branches: [main] + +permissions: + contents: read + +concurrency: + group: ci-${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +jobs: + build: + name: build + runs-on: ubuntu-latest + timeout-minutes: 20 + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + # Nothing in this job pushes or calls the API; do not leave the + # GITHUB_TOKEN in .git/config for later steps to pick up. + persist-credentials: false + + # The site is a Bun project (bun.lock, engines.bun >= 1.3, scripts invoke + # `bun scripts/*.ts` directly) — there is no package-lock.json, so + # setup-node + `npm ci` would not work here. `latest` mirrors what + # Cloudflare Workers Builds installs; package.json only sets a floor. + - uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0 + with: + bun-version: latest + + - name: Install (frozen lockfile) + run: bun install --frozen-lockfile + + # `build` = build:data -> astro build -> pagefind. It must run before + # `check` because `astro check` type-checks imports of the gitignored + # src/data/generated/*.json that build:data emits. + - name: Build + run: bun run build + + - name: Check (astro check) + run: bun run check + + - name: Test (data layer) + run: bun test diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..76e3523 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,57 @@ +# Contributing + +Thanks for helping improve the Celeris documentation and benchmark dashboard. +This repository is the source of [goceleris.dev](https://goceleris.dev). + +## Running the site locally + +Requires [Bun](https://bun.sh) `>= 1.3.0` (see `engines` in `package.json`). + +```sh +bun install --frozen-lockfile +bun run dev # build:data, then astro dev at http://localhost:4321 +bun run demo # same, against a synthesized demo dataset +``` + +Before opening a pull request, run what CI runs: + +```sh +bun run build # build:data -> astro build -> pagefind +bun run check # astro check (types + content schema); needs build:data first +bun test # data-layer tests +``` + +`bun run validate` checks every committed `results/` cell without emitting +anything — it is the gate the benchmark publisher relies on. + +Documentation pages live in `src/content/docs/**/*.{md,mdx}` and are validated +against the frontmatter schema described in the [README](README.md#content-structure). + +## Pull-request flow + +1. Fork (or branch, if you have write access) from `main`. Branch names follow + `docs/`, `feat/`, `fix/`, `chore/`. +2. Keep one topic per pull request and use a conventional commit prefix + (`docs:`, `feat:`, `fix:`, `chore:`, `ci:`, `deps:`) with a body that + explains *why*. +3. Do not touch dependency versions in a content PR; Dependabot proposes those. + `typescript` is pinned exactly to `6.0.3` on purpose (`@astrojs/check` + breaks on TypeScript 7) — do not bump it by hand. +4. Do not edit `results/` by hand. Benchmark cells are committed by the + probatorium publisher, and `src/data/generated/` and `public/data/` are + gitignored build outputs. + +## Merge rule + +`main` is protected. A pull request merges only when: + +- the `build` CI job is green (install, build, `astro check`, tests), and +- a code owner (see `.github/CODEOWNERS`) has approved it. + +Every push to `main` is deployed automatically by Cloudflare Workers Builds, so +a merged PR is live within minutes — make sure the site builds and looks right +locally before merging. + +## Security + +Never report a vulnerability in a public issue; see [SECURITY.md](SECURITY.md). diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..ac8cef5 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,47 @@ +# Security Policy + +This repository builds the **goceleris.dev** static site: documentation and the +benchmark dashboard. It contains no server code and no runtime — every page is +rendered at build time and served as plain HTML from Cloudflare Workers static +assets. The security surface is therefore the build pipeline, the published +content, and the small client-side dashboard island. + +## Reporting a vulnerability + +**Do not open a public GitHub issue for security vulnerabilities.** + +Report privately through either channel: + +1. **Preferred:** this repository's **Security** tab → **"Report a + vulnerability"** (private vulnerability reporting is enabled): + +2. Email **security@goceleris.dev** + +Please include a description of the issue, steps to reproduce, the potential +impact, and a suggested fix if you have one. + +We will acknowledge your report within **72 hours** and keep you informed as we +triage and fix it. + +## Scope + +In scope for this repository: + +- The site build pipeline (`scripts/`, `src/lib/results/`) and the way it + ingests the committed `results/` benchmark cells +- Published content that could mislead users about Celeris's security posture +- The client-side dashboard island under `src/dashboard/` +- Static hosting configuration (`public/_headers`, `wrangler.jsonc`) + +## The engine itself + +Vulnerabilities in **Celeris** — the HTTP framework and its I/O engines that this +site documents — are handled by the celeris repository's policy, which also +lists the supported versions: + +(). + +Issues in the load generator or the benchmark harness belong to +[loadgen](https://github.com/goceleris/loadgen/security/policy) and +[probatorium](https://github.com/goceleris/probatorium/security/policy) +respectively.