A personal website.
This website is built with:
- Astro - Static site generation
- GitHub Actions - CI/CD
- Cloudflare Pages - Hosting and deployment
Blog posts are Astro content collections in src/content/blog/. Each post is a directory containing index.md and any co-located images.
Frontmatter:
---
title: "Post Title"
date: "YYYY-MM-DD"
path: "/blog/slug"
excerpt: "Short description for the listing page."
draft: true # optional, excluded from production
archived: true # optional, excluded from listing
---
Projects are defined in src/data/projects.json. Sorted by lastCommitDate (newest first).
This repo also hosts standalone microsites, each with its own domain, layout, and styles:
- useyourdamnhands.com — A public service announcement about unnecessary tools
- whatarewedoinghere.org — Coming soon
Microsites live under src/microsites/<name>/ (layouts, components, styles) and src/pages/<name>/ (routes). Domain routing is handled by Cloudflare Pages Functions middleware (functions/_middleware.ts).
The site supports multiple visual themes, toggled via a dropdown in the bottom-left corner:
- Default - Clean blue/coral palette
- Sharks - San Jose Sharks teal/orange palette with hockey easter eggs
- Canada - Canadian flag red/white palette with falling snow and maple leaves
- Underwater - Deep ocean gradient with animated waves, manta rays, and coral
Themes are defined in src/themes/ as TypeScript files satisfying the Theme interface. See CONTRIBUTING.md for the full theme API and conventions.
$ pnpm install
$ pnpm dev
| Command | Description |
|---|---|
pnpm dev |
Start dev server |
pnpm build |
Production build |
pnpm lint |
ESLint check |
pnpm lint:fix |
ESLint auto-fix |
pnpm format |
Prettier format all files |
pnpm format:check |
Prettier check |
pnpm typecheck |
TypeScript type check |
pnpm test |
Run unit tests (Vitest) |
pnpm test:e2e |
Run e2e tests (Playwright) |
ESLint and Prettier run automatically:
- On save — VS Code formats via Prettier
- On commit — Husky pre-commit hook runs
lint-staged - In CI — GitHub Actions checks lint and formatting before build
Deployed to Cloudflare Pages via GitHub Actions (.github/workflows/main.yml).
Production — on push to main:
- CI runs lint, format check, typecheck, tests, build, and Lighthouse
- Build output is deployed via
wrangler pages deploy --branch=main
Preview — on pull requests:
- CI runs the same checks, then deploys with
--branch=${{ github.head_ref }} - A preview URL (e.g.
feat-my-thing.tinney-dev.pages.dev) is posted as a PR comment - The comment is updated on subsequent pushes to the same PR
Custom domains (tinney.dev, useyourdamnhands.com, whatarewedoinghere.org) are configured in the Cloudflare Pages dashboard. Domain-based routing is handled by the middleware in functions/_middleware.ts.
See CONTRIBUTING.md for workflow, commit conventions, architecture, and code style guidelines.
MIT