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
3 changes: 3 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# A historical cache-key delimiter embedded a NUL in this TypeScript file.
# Keep source diffs reviewable while the textual replacement lands.
src/lib/category.ts text diff
8 changes: 4 additions & 4 deletions .github/BRANCH_PROTECTION.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,9 @@ Test the protection by:
The following GitHub Actions workflows provide status checks:

### Currently Implemented
- **PR Validation** (`validate`): Runs linting, type checking, and build verification
- **PR Validation** (`validate`): Runs linting, type and unit checks, production build,
content/feed validation, and Chromium accessibility/browser QA

### Planned Additions
- **Link Checker**: Validates internal and external links
- **Accessibility Tests**: Automated a11y testing
- **Performance Budget**: Lighthouse CI checks
- **External Link Checker**: Extends the existing internal link and fragment validation
- **Performance Budget**: Lighthouse CI checks
28 changes: 21 additions & 7 deletions .github/CI_CD_DOCUMENTATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,18 @@ This repository implements comprehensive quality gates to ensure code quality an
All pull requests to `main` undergo automated validation:

- **Linting** - Code style and quality checks via ESLint
- **Markdown Linting** - Structural checks for Markdown and MDX content
- **Unit Tests** - Vitest coverage for TypeScript utilities
- **Spell Checking** - Source and generated HTML spelling checks via CSpell
- **Prose Linting** - Article terminology and style checks via Vale
- **Vale Fixture Tests** - Terminology rule fixtures that assert expected pass/fail behavior
- **Type Checking** - TypeScript validation via `astro check`
- **Type Checking** - Native TypeScript checks plus `astro check`
- **Build Verification** - Ensures the site builds successfully
- **Link Validation** - Checks all internal links are valid
- **Feed Validation** - Checks RSS XML and namespace correctness
- **Browser QA** - Runs Chromium behavior, responsive, and accessibility checks

The workflow provides automatic PR comments with validation results.
Results appear in GitHub's native `Validate PR` required check.

### 2. Link Validation

Expand All @@ -38,7 +41,7 @@ Custom Node.js script that:
npm run validate:links # Run link validation
npm run lint:prose # Run Vale prose linting
npm run test:vale # Run Vale terminology fixture tests
npm run validate:all # Run validation (lint, prose, Vale fixtures, build, links)
npm run validate:all # Run static validation plus Chromium browser QA
```

### 3. Deployment Workflow
Expand All @@ -49,6 +52,16 @@ Automatically deploys to GitHub Pages when changes are pushed to `main`:
- Builds the site with `npm run build`
- Uploads artifacts to GitHub Pages
- Only runs after all PR checks have passed (when branch protection is enabled)
- Grants Pages and OIDC write permissions only to the deploy job

### 4. Dependency Maintenance

**File:** `.github/dependabot.yml`

Dependabot checks npm and GitHub Actions weekly. It groups compatible npm
minor/patch updates and all GitHub Actions updates while leaving npm majors as
focused migration PRs. Workflow actions remain pinned to full commit SHAs;
Dependabot updates those pins as new releases are selected.

## 🔐 Branch Protection Setup

Expand Down Expand Up @@ -100,7 +113,7 @@ git push origin feature/my-feature
```

### 5. Automated Validation
PR validation workflow automatically runs and reports results.
The PR validation workflow automatically runs and reports a native required check.

### 6. Merge
Once checks pass and PR is approved, merge to main.
Expand All @@ -116,15 +129,16 @@ Changes are automatically deployed to GitHub Pages.
- [ ] Asset optimization checks

### Phase 3: Quality Improvements
- [ ] Accessibility testing (axe-core)
- [x] Accessibility testing (axe-core + Playwright)
- [ ] SEO validation
- [ ] Performance budgets (Lighthouse CI)
- [ ] Content validation (frontmatter requirements)
- [x] Content validation (Astro/Zod frontmatter schemas)

### Phase 4: Advanced Features
- [ ] Preview deployments for PRs
- [ ] Visual regression testing
- [ ] Spell checking
- [x] Spell checking
- [x] Automated dependency updates
- [ ] Security scanning

## 🛠️ Troubleshooting
Expand Down
41 changes: 26 additions & 15 deletions .github/WORKFLOW_ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,19 @@ This repository uses a modular GitHub Actions workflow architecture to ensure co
- Accepts optional `checkout-ref` input for specific git references
- Performs all validation steps:
- Linting (ESLint)
- Markdown linting
- TypeScript checking
- Unit tests
- Spell checking (source files)
- Prose linting (Vale)
- Vale fixture tests
- TypeScript checking and Astro build
- Astro check and production build
- Spell checking (generated HTML)
- Internal link validation
- RSS feed validation
- Chromium browser and accessibility QA
- Upload pages artifact for deployment

**Outputs**:
- `artifact-uploaded`: Boolean indicating if the build artifact was successfully created

### 2. `.github/workflows/deploy.yml`
**Purpose**: Deploy the site to GitHub Pages

Expand All @@ -48,9 +49,8 @@ This repository uses a modular GitHub Actions workflow architecture to ensure co

**Features**:
- Uses the same build workflow as deployment (ensures parity)
- Provides detailed status comments on PRs
- Acts as a complete dry-run of the deployment process
- Reports all validation results clearly
- Reports results through GitHub's native required check

## Key Design Decisions

Expand All @@ -65,12 +65,15 @@ Multiple safeguards prevent accidental deployment:

### 3. Complete PR Validation
PRs undergo the exact same validation as deployment, including:
- All linting and type checking
- ESLint, Markdown linting, and type checking
- Unit tests
- Spell checking (both source and generated HTML)
- Prose linting
- Vale fixture tests
- Full site build
- Link validation
- RSS feed validation
- Chromium browser and accessibility QA

This prevents the "passes CI but fails deployment" scenario.

Expand Down Expand Up @@ -98,6 +101,14 @@ This prevents the "passes CI but fails deployment" scenario.
### Adding New Validation Steps
Add new validation steps to `build.yml` only. They will automatically be included in both PR validation and deployment.

### Dependency Updates

Dependabot checks npm and GitHub Actions weekly via `.github/dependabot.yml`. Compatible
npm minor/patch updates and GitHub Actions updates are grouped to reduce PR
noise; npm major upgrades remain separate so their migration risk is explicit.
Action references stay pinned to full commit SHAs, with release-version comments
for reviewability.

### Modifying Deployment Conditions
Edit the `if` condition in the `deploy` job of `deploy.yml`. Current logic:
```yaml
Expand All @@ -109,20 +120,20 @@ if: |
### Debugging Workflow Issues
1. Check the workflow run logs in GitHub Actions tab
2. Use `workflow_dispatch` to manually test workflows
3. The PR validation comment provides a summary of what checks ran
3. Inspect the `Validate PR` required check for the failing validation step

## Security Considerations

- Deployment requires `pages: write` and `id-token: write` permissions (only in deploy.yml)
- PR validation has minimal permissions:
- `contents: read` for checking out code
- `pull-requests: write` for posting status comments
- No write access to Pages (follows principle of least privilege)
- Deployment grants `pages: write` and `id-token: write` only to the deploy job
- Build and PR validation have only `contents: read`
- Checkout credentials are not persisted after source retrieval
- Third-party and GitHub-authored actions are pinned to audited commit SHAs
- The `configure-pages` action was removed as it's not needed (we don't use its outputs)
- Concurrency groups prevent race conditions during deployment
- Branch protection rules should be configured to require PR validation before merge

### Permission Model
- **PR Validation**: Read-only access (can't modify repository or deploy)
- **Deployment**: Write access only when pushing to main branch
- **PR Validation**: Read-only access (cannot modify the repository or deploy)
- **Build**: Read-only access, including when called by the deployment workflow
- **Deployment**: Pages/OIDC write access only in the conditional deploy job
- **Manual Workflow**: Deployment only allowed from main branch with explicit flag
29 changes: 29 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
version: 2

updates:
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "weekly"
day: "monday"
time: "09:00"
timezone: "America/Chicago"
groups:
npm-minor-and-patch:
patterns:
- "*"
update-types:
- "minor"
- "patch"

- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
day: "monday"
time: "09:00"
timezone: "America/Chicago"
groups:
github-actions:
patterns:
- "*"
51 changes: 20 additions & 31 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,44 +8,40 @@ on:
type: string
required: false
default: ''
outputs:
artifact-uploaded:
description: 'Whether the pages artifact was uploaded successfully'
value: ${{ jobs.build.outputs.artifact-uploaded }}

permissions:
contents: read

jobs:
build:
name: Build and validate
runs-on: ubuntu-latest
outputs:
artifact-uploaded: ${{ steps.upload.outputs.artifact-uploaded }}


steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
ref: ${{ inputs.checkout-ref }}

persist-credentials: false

- name: Setup Node
uses: actions/setup-node@v4
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version-file: '.nvmrc'
cache: 'npm'

- name: Setup Rust
uses: actions-rust-lang/setup-rust-toolchain@v1
with:
toolchain: stable
cache: true

- name: Install trop
run: cargo install trop-cli --locked

- name: Install Dependencies
run: npm ci


- name: Install Chromium
run: npx playwright install --with-deps chromium

- name: Run Linting
run: npm run lint

- name: Run Markdown Linting
run: npm run lint:markdown

- name: Type Check (TypeScript 7)
run: npm run typecheck

Expand Down Expand Up @@ -95,17 +91,10 @@ jobs:
- name: Validate RSS Feed
run: npm run validate:feed

- name: Run Browser QA
run: npm run qa:ci

- name: Upload Pages Artifact
id: upload
uses: actions/upload-pages-artifact@v3
uses: actions/upload-pages-artifact@fc324d3547104276b827a68afc52ff2a11cc49c9 # v5.0.0
with:
path: './dist'

- name: Set Output
if: always()
run: |
if [ "${{ steps.upload.outcome }}" == "success" ]; then
echo "artifact-uploaded=true" >> $GITHUB_OUTPUT
else
echo "artifact-uploaded=false" >> $GITHUB_OUTPUT
fi
21 changes: 14 additions & 7 deletions .github/workflows/claude-code-review.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,15 @@ on:
# - "src/**/*.js"
# - "src/**/*.jsx"

permissions: {}

concurrency:
group: claude-review-${{ github.event.pull_request.number }}
cancel-in-progress: true

jobs:
claude-review:
name: Review with Claude
# Optional: Filter by PR author
# if: |
# github.event.pull_request.user.login == 'external-contributor' ||
Expand All @@ -20,20 +27,21 @@ jobs:

runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: read
issues: read
id-token: write
contents: read # Read the repository under review.
pull-requests: read # Read PR context; comments use the Claude GitHub App token.
issues: read # Read issue-style PR comments through the GitHub API.
id-token: write # Authenticate the Claude GitHub App through OIDC.

steps:
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 1
persist-credentials: false

- name: Run Claude Code Review
id: claude-review
uses: anthropics/claude-code-action@v1
uses: anthropics/claude-code-action@a874e9ecd7bb36efdad65429c6b35815f5a08f10 # v1.0.210
with:
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
prompt: |
Expand All @@ -54,4 +62,3 @@ jobs:
# See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md
# or https://docs.claude.com/en/docs/claude-code/cli-reference for available options
claude_args: '--allowed-tools "Bash(gh issue view:*),Bash(gh search:*),Bash(gh issue list:*),Bash(gh pr comment:*),Bash(gh pr diff:*),Bash(gh pr view:*),Bash(gh pr list:*)"'

Loading
Loading