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
84 changes: 84 additions & 0 deletions .github/BRANCH_PROTECTION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
# Branch Protection Configuration

This document outlines the recommended branch protection settings for the `main` branch.

## Setting Up Branch Protection

Navigate to: Settings → Branches → Add rule

### Branch name pattern
- `main`

### Protect matching branches

#### ✅ Required Settings

1. **Require a pull request before merging**
- ✅ Require approvals: 1
- ✅ Dismiss stale pull request approvals when new commits are pushed
- ✅ Require review from CODEOWNERS (if applicable)

2. **Require status checks to pass before merging**
- ✅ Require branches to be up to date before merging
- **Required status checks:**
- `validate` (from PR Validation workflow)

3. **Require conversation resolution before merging**
- ✅ Enable this to ensure all PR comments are addressed

4. **Additional restrictions**
- ✅ Do not allow bypassing the above settings
- ✅ Restrict who can push to matching branches (optional, but recommended)

#### ⚠️ Optional but Recommended

1. **Require signed commits**
- Ensures commits are verified

2. **Include administrators**
- Apply rules to admin users as well

3. **Restrict who can dismiss pull request reviews**
- Limit to repository administrators

## Automated Setup via GitHub CLI

You can also configure branch protection using the GitHub CLI:

```bash
# Install GitHub CLI if not already installed
# brew install gh (macOS)
# or see: https://cli.github.com/

# Authenticate
gh auth login

# Set up branch protection
gh api repos/:owner/:repo/branches/main/protection \
--method PUT \
--field required_status_checks='{"strict":true,"contexts":["validate"]}' \
--field enforce_admins=true \
--field required_pull_request_reviews='{"dismiss_stale_reviews":true,"require_code_owner_reviews":false,"required_approving_review_count":1}' \
--field restrictions=null
```

## Verifying Protection

After setup, the main branch should show a 🔒 icon in the GitHub UI, indicating it's protected.

Test the protection by:
1. Attempting to push directly to main (should fail)
2. Creating a PR and verifying checks run
3. Ensuring merge is blocked until checks pass

## Status Checks

The following GitHub Actions workflows provide status checks:

### Currently Implemented
- **PR Validation** (`validate`): Runs linting, type checking, and build verification

### Planned Additions
- **Link Checker**: Validates internal and external links
- **Accessibility Tests**: Automated a11y testing
- **Performance Budget**: Lighthouse CI checks
154 changes: 154 additions & 0 deletions .github/CI_CD_DOCUMENTATION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
# CI/CD and Branch Protection Documentation

## Overview

This repository implements comprehensive quality gates to ensure code quality and prevent broken deployments to GitHub Pages.

## 🛡️ Protection Mechanisms

### 1. Pull Request Validation

**File:** `.github/workflows/pr-validation.yml`

All pull requests to `main` undergo automated validation:

- **Linting** - Code style and quality checks via ESLint
- **Type Checking** - TypeScript validation via `astro check`
- **Build Verification** - Ensures the site builds successfully
- **Link Validation** - Checks all internal links are valid

The workflow provides automatic PR comments with validation results.

### 2. Link Validation

**File:** `scripts/validate-links.js`

Custom Node.js script that:
- Parses all generated HTML files in `dist/`
- Extracts internal links (href and src attributes)
- Validates each link resolves to an actual file or route
- Reports broken links with their source locations

**Usage:**
```bash
npm run validate:links # Run link validation
npm run validate:all # Run all validation (lint, build, links)
```

### 3. Deployment Workflow

**File:** `.github/workflows/deploy.yml`

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)

## 🔐 Branch Protection Setup

### Required Configuration

Follow the instructions in `.github/BRANCH_PROTECTION.md` to enable branch protection.

**Key Settings:**
- Require pull request reviews before merging
- Require status checks to pass (specifically the `validate` check)
- Dismiss stale reviews when new commits are pushed
- Require branches to be up to date before merging

### Setting Up Protection

#### Via GitHub UI:
1. Go to Settings → Branches
2. Add rule for `main` branch
3. Configure settings per `BRANCH_PROTECTION.md`

#### Via GitHub CLI:
```bash
gh api repos/:owner/:repo/branches/main/protection \
--method PUT \
--field required_status_checks='{"strict":true,"contexts":["validate"]}' \
--field enforce_admins=true \
--field required_pull_request_reviews='{"dismiss_stale_reviews":true,"required_approving_review_count":1}'
```

## 📋 Development Workflow

### 1. Create Feature Branch
```bash
git checkout -b feature/my-feature
```

### 2. Make Changes
Edit files, add content, modify styles, etc.

### 3. Test Locally
```bash
npm run validate:all # Run all checks locally
```

### 4. Create Pull Request
```bash
git push origin feature/my-feature
# Create PR via GitHub UI or CLI
```

### 5. Automated Validation
PR validation workflow automatically runs and reports results.

### 6. Merge
Once checks pass and PR is approved, merge to main.

### 7. Automatic Deployment
Changes are automatically deployed to GitHub Pages.

## 🚀 Future Enhancements

### Phase 2: Enhanced Link Validation
- [ ] External link checking with smart caching
- [ ] Anchor link validation (#fragments)
- [ ] Asset optimization checks

### Phase 3: Quality Improvements
- [ ] Accessibility testing (axe-core)
- [ ] SEO validation
- [ ] Performance budgets (Lighthouse CI)
- [ ] Content validation (frontmatter requirements)

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

## 🛠️ Troubleshooting

### PR Checks Failing

1. **Linting Errors:**
```bash
npm run lint:fix # Auto-fix linting issues
```

2. **Build Errors:**
```bash
npm run build # Test build locally
```

3. **Link Validation Errors:**
```bash
npm run validate:links # Check which links are broken
```

### Branch Protection Not Working

- Ensure you have admin access to the repository
- Verify the `validate` status check name matches the workflow job name
- Check that branch protection rules are enabled in Settings → Branches

## 📚 Related Documentation

- [Branch Protection Setup](./BRANCH_PROTECTION.md)
- [PR Validation Workflow](./workflows/pr-validation.yml)
- [Deployment Workflow](./workflows/deploy.yml)
- [Link Validation Script](../scripts/validate-links.js)
67 changes: 67 additions & 0 deletions .github/workflows/pr-validation.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
name: PR Validation

on:
pull_request:
branches: [main]
types: [opened, synchronize, reopened]

permissions:
contents: read
pull-requests: write

jobs:
validate:
name: Validate PR
runs-on: ubuntu-latest

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 20
cache: 'npm'

- name: Install Dependencies
run: npm ci

- name: Run Linting
run: npm run lint
continue-on-error: false

- name: Type Check and Build
run: npm run build
continue-on-error: false

- name: Check Build Output
run: |
if [ ! -d "dist" ]; then
echo "Error: Build output directory 'dist' not found"
exit 1
fi
echo "Build successful - dist directory created"
echo "Files generated: $(find dist -type f | wc -l)"

- name: Validate Internal Links
run: npm run validate:links
continue-on-error: false

- name: Report Status
if: always()
uses: actions/github-script@v7
with:
script: |
const status = '${{ job.status }}';
const icon = status === 'success' ? '✅' : '❌';
const message = status === 'success'
? 'All checks passed! Ready for review.'
: 'Some checks failed. Please review the errors above.';

github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: `## PR Validation ${icon}\n\n${message}\n\n### Checks Performed:\n- ✓ Linting\n- ✓ Type checking\n- ✓ Build verification\n- ✓ Internal link validation`
});
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@
"preview:network": "astro preview --host",
"astro": "astro",
"lint": "eslint .",
"lint:fix": "eslint . --fix"
"lint:fix": "eslint . --fix",
"validate:links": "node scripts/validate-links.js",
"validate:all": "npm run lint && npm run build && npm run validate:links"
},
"dependencies": {
"@astrojs/check": "^0.9.4",
Expand Down
Loading