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
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 1 addition & 1 deletion .bun-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.3.14
1.4.0
29 changes: 27 additions & 2 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,21 @@
version: 2

updates:
# JavaScript dependencies — managed with Bun (bun.lock is the source of truth;
# the deploy/CI workflows run `bun install`). Requires Bun >= 1.1.39.
# Astro site — managed with Bun (bun.lock is the source of truth; CI and the
# deploy workflow both run `bun install --frozen-lockfile`).
- package-ecosystem: 'bun'
directory: '/'
schedule:
interval: 'weekly'
open-pull-requests-limit: 5
commit-message:
prefix: 'chore(deps)'
ignore:
# astro check and next build both load TypeScript's programmatic API, which
# the 7.x native compiler does not ship yet. Unpin only once both support it.
# https://github.com/withastro/roadmap/discussions/1321
- dependency-name: 'typescript'
versions: ['>=7']
groups:
# Batch all non-major updates into a single PR to cut review noise.
# Major bumps still arrive as individual PRs (they need manual review).
Expand All @@ -20,6 +26,25 @@ updates:
- 'minor'
- 'patch'

# Outstatic dashboard — a separate app with its own package.json / bun.lock.
- package-ecosystem: 'bun'
directory: '/cms'
schedule:
interval: 'weekly'
open-pull-requests-limit: 3
commit-message:
prefix: 'chore(cms-deps)'
ignore:
- dependency-name: 'typescript'
versions: ['>=7']
# outstatic pins this exact version as a peer dependency.
- dependency-name: 'tailwindcss'
groups:
minor-and-patch:
update-types:
- 'minor'
- 'patch'

# GitHub Actions — keeps the SHA pins (and their `# vX.Y.Z` comments) current.
- package-ecosystem: 'github-actions'
directory: '/'
Expand Down
36 changes: 32 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,18 +36,18 @@ jobs:
- name: Install dependencies
run: bun install --frozen-lockfile

- name: Gate (typecheck, format, lint, dead-code, tests)
- name: Gate (typecheck, format, lint, dead-code, build, tests)
run: bun run gate

- name: Accessibility (Lighthouse >= 95)
run: bun run a11y

- name: Secret scan
run: bun run secrets

- name: Dependency audit (advisory, non-blocking)
run: bun run audit || echo "::notice::bun audit reported advisories (non-blocking; Dependabot tracks upstream fixes)"

- name: Build website
run: bun run build

- name: Job summary
if: always()
run: |
Expand All @@ -67,3 +67,31 @@ jobs:
echo "| Pages built | $pages_built |"
echo "| Commit | \`${GITHUB_SHA::7}\` |"
} >> "$GITHUB_STEP_SUMMARY"

cms:
name: CMS build (Outstatic dashboard)
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

- name: Setup Node.js
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: 24

- name: Setup Bun
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0
with:
bun-version-file: .bun-version

- name: Install dependencies
run: bun install --frozen-lockfile
working-directory: cms

# The dashboard is never deployed — it runs locally and commits Markdown
# into this repo. Building it here only proves a dependency bump has not
# broken the tool the blog is authored with.
- name: Build
run: bun run build
working-directory: cms
120 changes: 120 additions & 0 deletions .github/workflows/deploy-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
name: Deploy test site (Netlify)

# The TEST environment. Every push to main lands on Netlify so a change can be
# looked at on a real host before it is released.
#
# Production is a different workflow with a different trigger: deploy.yml puts
# the same dist/ on GitHub Pages at libredb.org, and only when a release is
# published. Nothing here touches production, and merging to main never
# publishes — that separation is the point of having two workflows.
#
# This job builds and deploys, and deliberately does NOT run the gate: ci.yml
# already runs typecheck, format, lint, knip, tests, Lighthouse and the secret
# scan on the same push, in parallel. Repeating it here would double the work to
# protect a test host from a state its own build step already fails on — the
# only thing that can break this deploy is `bun run build`, and that is the step
# that is here.
on:
push:
branches: [main]
workflow_dispatch:

permissions:
contents: read

# A newer push wins. On a test host the freshest commit is the only one anyone
# wants to look at, so an in-flight deploy of an older commit is cancelled
# rather than raced. (deploy.yml does the opposite for production, where a
# half-finished deploy must never be interrupted.)
concurrency:
group: netlify-test
cancel-in-progress: true

jobs:
deploy:
name: Build and deploy to Netlify
runs-on: ubuntu-latest
environment:
name: netlify-test
url: ${{ steps.deploy.outputs.url }}
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

- name: Setup Node.js
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: 24

- name: Setup Bun
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0
with:
bun-version-file: .bun-version

# Fail here with a sentence, rather than fifty lines into the CLI with
# "site not found". A missing secret is the likeliest way this breaks, and
# it breaks identically for someone who forked the repo.
- name: Check credentials are configured
env:
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }}
run: |
missing=""
[ -n "$NETLIFY_AUTH_TOKEN" ] || missing="$missing NETLIFY_AUTH_TOKEN"
[ -n "$NETLIFY_SITE_ID" ] || missing="$missing NETLIFY_SITE_ID"
if [ -n "$missing" ]; then
echo "::error::Missing repository secret(s):$missing — set them under Settings → Secrets and variables → Actions."
exit 1
fi

- name: Install dependencies
run: bun install --frozen-lockfile

- name: Build website
run: bun run build

# The token goes through the environment, never through argv: a command
# line is readable from the process list on the runner, and the CLI reads
# both of these from the environment anyway.
#
# netlify-cli is pinned exactly, like every action above. Dependabot does
# not see a version inside a `bunx` call, so this is a manual bump — the
# alternative, a devDependency, would add the CLI's very large install to
# every CI run for the sake of one job.
- name: Deploy to Netlify
id: deploy
env:
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }}
run: |
set -o pipefail
bunx netlify-cli@26.1.0 deploy \
--dir=dist \
--no-build \
--prod \
--json \
--message "main@${GITHUB_SHA::7} — ${GITHUB_WORKFLOW}" \
| tee deploy.json
# The summary must never be the reason a good deploy reports failure,
# so the URL is best-effort and the step's exit status stays the CLI's.
url=$(node -e "try{process.stdout.write(require('./deploy.json').url||'')}catch{}")
echo "url=${url:-https://libredb-website.netlify.app}" >> "$GITHUB_OUTPUT"

- name: Deploy summary
if: always()
env:
URL: ${{ steps.deploy.outputs.url }}
run: |
pages_built=0
[ -d dist ] && pages_built=$(find dist -name '*.html' | wc -l | tr -d ' ')
{
echo "## 🧪 Test deploy — \`${{ job.status }}\`"
echo ""
echo "| Item | Value |"
echo "| --- | --- |"
echo "| Site | ${URL:-n/a} |"
echo "| Pages built | $pages_built |"
echo "| Commit | \`${GITHUB_SHA::7}\` |"
echo ""
echo "Production is unaffected: libredb.org publishes from \`deploy.yml\` on a released tag."
} >> "$GITHUB_STEP_SUMMARY"
7 changes: 5 additions & 2 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ name: Deploy to GitHub Pages

# Production deploy is gated on publishing a GitHub release.
# Build verification on PRs / main pushes lives in ci.yml.
#
# NOTE for CMS authors: saving a post in the Outstatic dashboard commits Markdown
# to main, which runs ci.yml but does NOT publish. Cut a release (or run this
# workflow from the Actions tab) to put new posts live.
on:
release:
types: [published]
Expand Down Expand Up @@ -64,8 +68,7 @@ jobs:
with:
path: ./dist
# Without this the action tars ./dist with --exclude=.[^/]*, which drops
# public/.well-known/ - the domain verification files served from there
# (Flathub, security.txt) would 404 in production.
# public/.well-known/ — anything served from there would 404 in production.
include-hidden-files: true

deploy:
Expand Down
47 changes: 20 additions & 27 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,40 +1,33 @@
# build output
node_modules/
dist/
# generated types
.astro/
.DS_Store
*.log

# dependencies
node_modules/

# logs
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*

# Outstatic companion app
cms/node_modules/
cms/.next/
cms/.env.local
cms/next-env.d.ts

# environment variables
# local env
.env
.env.production
.env.local

# macOS-specific files
.DS_Store
# scratch — session memory (remember plugin), local tooling state
.remember/

# jetbrains setting folder
# JetBrains
.idea/

# Brainstorm visual companion
.superpowers/

# Session memory (remember plugin) — local tooling state, not project source
.remember/

# Playwright MCP output
.playwright-mcp/
# Local Netlify folder
.netlify

docs/designs/_ref
.playwright-mcp

# Local-only working material, carried over from this repo's previous .gitignore
.superpowers/
.qoder/
docs/superpowers/


docs/designs/_ref
libredb-org-redesign.md
10 changes: 9 additions & 1 deletion .oxlintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,13 @@
"rules": {
"no-underscore-dangle": "off"
},
"ignorePatterns": ["dist/**", ".astro/**", "node_modules/**", "public/**"]
"ignorePatterns": [
"dist/**",
".astro/**",
"node_modules/**",
"public/**",
"cms/.next/**",
"design/**",
"design-system/**"
]
}
25 changes: 19 additions & 6 deletions .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,27 @@ dist
.astro
node_modules
bun.lock

# Internal design/plan artifacts (HTML mockups + agent plan files whose fenced
# code blocks aren't valid JS). Not shipped source — don't format.
docs
cms/.next

# Served verbatim — Prettier must not reflow static assets
public

# Verbatim copy synced from libredb-studio by scripts/sync-docker-compose.mjs.
# Formatting it here would fight the sync step on every build.
# Design handoff artifacts (HTML mockups and reference material, not shipped
# source). Reformatting them would fight the handoff they were exported from.
design
design-system

# CMS-authored content. Outstatic writes this Markdown; formatting it here would
# produce a diff on the next save from the dashboard.
outstatic/content

# Vendored verbatim from design-system/ so Vite can resolve the relative url()
# references inside tokens/theme.css. tests/ds-integrity.test.ts asserts every
# file is byte-identical to its source — reformatting here would break that.
src/styles/ds

# Verbatim copy of libredb-studio's docker-compose.example.yml. It is served at
# /docker-compose.example.yml and shown byte-for-byte on /docker-compose, so it
# must stay identical to the upstream file — reformatting it would silently make
# the mirror a paraphrase.
src/data/docker-compose.example.yml
3 changes: 1 addition & 2 deletions .prettierrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
"$schema": "https://json.schemastore.org/prettierrc",
"singleQuote": true,
"printWidth": 120,
"plugins": ["prettier-plugin-astro", "prettier-plugin-tailwindcss"],
"tailwindStylesheet": "./src/styles/global.css",
"plugins": ["prettier-plugin-astro"],
"overrides": [{ "files": "*.astro", "options": { "parser": "astro" } }]
}
7 changes: 4 additions & 3 deletions .secretlintignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ dist
.astro
node_modules
bun.lock
cms/.next

# Synced docker-compose example (from libredb-studio). The "connection string"
# is a commented-out template default (postgres:postgres@...), not a secret.
**/docker-compose.example.yml
# Example env file for the local Outstatic dashboard. The values are documented
# placeholders (`your-github-oauth-...`), not real credentials.
cms/.env.local.example
Loading
Loading