Skip to content
Closed
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
5 changes: 5 additions & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
* @metalagman

/.github/ @metalagman
/docs/.vitepress/ @metalagman
/scripts/ @metalagman
23 changes: 23 additions & 0 deletions .github/ISSUE_TEMPLATE/bug.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
name: Documentation or site bug
description: Report incorrect documentation, broken links, or site behavior
title: "docs: "
labels: [bug]
body:
- type: input
id: page
attributes:
label: Page URL
validations:
required: true
- type: textarea
id: problem
attributes:
label: Problem
validations:
required: true
- type: textarea
id: expected
attributes:
label: Expected content or behavior
validations:
required: true
5 changes: 5 additions & 0 deletions .github/ISSUE_TEMPLATE/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
blank_issues_enabled: true
contact_links:
- name: Security or privacy report
url: https://github.com/diffpal/diffpal.github.io/security/advisories/new
about: Report sensitive issues privately.
9 changes: 9 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
## Summary

<!-- What changes, why, and which dp- issue tracks it? -->

## Validation

- [ ] Documentation synchronization and production build pass.
- [ ] Privacy checks pass and analytics consent behavior is unchanged or documented.
- [ ] Links and user-facing version references are current.
19 changes: 16 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,23 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v5
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6

- name: Resolve canonical docs source
id: docs-source
run: |
ref=$(node -p "require('./docs-source.json').ref")
echo "ref=$ref" >> "$GITHUB_OUTPUT"

- name: Checkout canonical DiffPal docs
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
with:
repository: diffpal/diffpal
ref: ${{ steps.docs-source.outputs.ref }}
path: .source/diffpal

- name: Setup Node
uses: actions/setup-node@v6
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
with:
node-version: 22
cache: npm
Expand All @@ -26,4 +39,4 @@ jobs:
run: npm ci

- name: Build
run: npm run docs:build
run: npm run check
23 changes: 18 additions & 5 deletions .github/workflows/pages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,29 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v5
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6

- name: Resolve canonical docs source
id: docs-source
run: |
ref=$(node -p "require('./docs-source.json').ref")
echo "ref=$ref" >> "$GITHUB_OUTPUT"

- name: Checkout canonical DiffPal docs
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
with:
repository: diffpal/diffpal
ref: ${{ steps.docs-source.outputs.ref }}
path: .source/diffpal

- name: Setup Node
uses: actions/setup-node@v6
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
with:
node-version: 22
cache: npm

- name: Configure Pages
uses: actions/configure-pages@v4
uses: actions/configure-pages@1f0c5cde4bc74cd7e1254d0cb4de8d49e9068c7d # v4

- name: Install dependencies
run: npm ci
Expand All @@ -38,7 +51,7 @@ jobs:
run: npm run docs:build

- name: Upload artifact
uses: actions/upload-pages-artifact@v3
uses: actions/upload-pages-artifact@56afc609e74202658d3ffba0e8f6dda462b719fa # v3
with:
path: .vitepress/dist

Expand All @@ -51,4 +64,4 @@ jobs:
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
uses: actions/deploy-pages@d6db90164ac5ed86f2b6aed7e0febac5b3c0c03e # v4
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
node_modules/
.generated/
.generated-rewrites.json
.source/
.vitepress/cache/
.vitepress/dist/
.DS_Store
Expand Down
26 changes: 8 additions & 18 deletions .vitepress/config.mts
Original file line number Diff line number Diff line change
@@ -1,40 +1,28 @@
import { defineConfig } from 'vitepress'
import fs from 'node:fs'

const siteTitle = 'DiffPal'
const siteDescription = 'Open-source AI PR review you control.'
const mainRepo = 'https://github.com/diffpal/diffpal'
const examplesBase = `${mainRepo}/tree/main/examples`
const changelog = `${mainRepo}/blob/main/CHANGELOG.md`
const googleAnalyticsId = 'G-B8G6D7K9SQ'
const docsSource = JSON.parse(fs.readFileSync('docs-source.json', 'utf8'))
const rewrites = JSON.parse(fs.readFileSync('.generated-rewrites.json', 'utf8'))

export default defineConfig({
lang: 'en-US',
title: siteTitle,
description: siteDescription,
base: '/',
srcDir: '.generated',
rewrites,
cleanUrls: true,
lastUpdated: true,
srcExclude: ['README.md', 'AGENTS.md'],
sitemap: {
hostname: 'https://diffpal.github.io'
},
head: [
['link', { rel: 'icon', type: 'image/png', href: '/logo-mark.png' }],
[
'script',
{
async: '',
src: `https://www.googletagmanager.com/gtag/js?id=${googleAnalyticsId}`
}
],
[
'script',
{},
`window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', '${googleAnalyticsId}');`
],
['meta', { name: 'theme-color', content: '#2563eb' }],
['meta', { property: 'og:type', content: 'website' }],
['meta', { property: 'og:title', content: siteTitle }],
Expand All @@ -50,7 +38,7 @@ gtag('config', '${googleAnalyticsId}');`
provider: 'local'
},
editLink: {
pattern: 'https://github.com/diffpal/diffpal.github.io/edit/main/:path',
pattern: `${mainRepo}/edit/${docsSource.ref}/docs/:path`,
text: 'Edit this page on GitHub'
},
socialLinks: [
Expand All @@ -61,6 +49,7 @@ gtag('config', '${googleAnalyticsId}');`
{ text: 'Docs', link: '/docs' },
{ text: 'Examples', link: examplesBase },
{ text: 'Security', link: '/security' },
{ text: 'Privacy', link: '/privacy' },
{ text: 'Changelog', link: changelog },
{ text: 'GitHub', link: mainRepo }
],
Expand Down Expand Up @@ -113,6 +102,7 @@ gtag('config', '${googleAnalyticsId}');`
{ text: 'Verify first review', link: '/verify-first-review' },
{ text: 'Next steps', link: '/next-steps' },
{ text: 'Secrets and fork PRs', link: '/secrets-and-fork-prs' },
{ text: 'Migrate to v1', link: '/migrate-to-v1' },
{ text: 'Examples gallery', link: examplesBase }
]
},
Expand Down
63 changes: 63 additions & 0 deletions .vitepress/theme/ConsentAnalytics.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<script setup lang="ts">
import { onMounted, ref } from 'vue'

const storageKey = 'diffpal-analytics-consent'
const analyticsID = 'G-B8G6D7K9SQ'
const showChoices = ref(false)
const hasChoice = ref(false)

function loadAnalytics() {
if (document.querySelector(`script[data-diffpal-analytics="${analyticsID}"]`)) return
window.dataLayer = window.dataLayer || []
window.gtag = function gtag(...args: unknown[]) {
window.dataLayer.push(args)
}
window.gtag('js', new Date())
window.gtag('config', analyticsID, { anonymize_ip: true })

const script = document.createElement('script')
script.async = true
script.dataset.diffpalAnalytics = analyticsID
script.src = `https://www.googletagmanager.com/gtag/js?id=${analyticsID}`
document.head.appendChild(script)
}

function choose(value: 'accepted' | 'declined') {
localStorage.setItem(storageKey, value)
hasChoice.value = true
showChoices.value = false
if (value === 'accepted') loadAnalytics()
}

onMounted(() => {
const choice = localStorage.getItem(storageKey)
hasChoice.value = choice === 'accepted' || choice === 'declined'
showChoices.value = !hasChoice.value
if (choice === 'accepted') loadAnalytics()
})
</script>

<template>
<button v-if="hasChoice && !showChoices" class="privacy-choice-button" type="button" @click="showChoices = true">
Privacy choices
</button>
<aside v-if="showChoices" class="privacy-consent" aria-label="Analytics privacy choices">
<p>
DiffPal uses optional Google Analytics to understand documentation usage.
Nothing is loaded unless you accept. <a href="/privacy">Privacy details</a>
</p>
<div>
<button type="button" class="decline" @click="choose('declined')">Decline</button>
<button type="button" class="accept" @click="choose('accepted')">Accept analytics</button>
</div>
</aside>
</template>

<script lang="ts">
declare global {
interface Window {
dataLayer: unknown[]
gtag: (...args: unknown[]) => void
}
}
</script>
12 changes: 12 additions & 0 deletions .vitepress/theme/Layout.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<script setup lang="ts">
import DefaultTheme from 'vitepress/theme'
import ConsentAnalytics from './ConsentAnalytics.vue'
</script>

<template>
<DefaultTheme.Layout>
<template #layout-bottom>
<ConsentAnalytics />
</template>
</DefaultTheme.Layout>
</template>
51 changes: 51 additions & 0 deletions .vitepress/theme/custom.css
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,57 @@
max-width: 680px;
}

.privacy-consent {
position: fixed;
z-index: 100;
right: 1rem;
bottom: 1rem;
max-width: 34rem;
padding: 1rem;
border: 1px solid var(--vp-c-divider);
border-radius: 0.75rem;
background: var(--vp-c-bg-soft);
box-shadow: var(--vp-shadow-3);
}

.privacy-consent p {
margin: 0 0 0.75rem;
}

.privacy-consent div {
display: flex;
justify-content: flex-end;
gap: 0.5rem;
}

.privacy-consent button,
.privacy-choice-button {
padding: 0.45rem 0.75rem;
border: 1px solid var(--vp-c-divider);
border-radius: 0.5rem;
cursor: pointer;
}

.privacy-consent .accept {
color: white;
border-color: var(--vp-c-brand-1);
background: var(--vp-c-brand-1);
}

.privacy-consent .decline,
.privacy-choice-button {
color: var(--vp-c-text-1);
background: var(--vp-c-bg);
}

.privacy-choice-button {
position: fixed;
z-index: 90;
right: 1rem;
bottom: 1rem;
font-size: 0.8rem;
}

@media (max-width: 640px) {
.vp-doc table {
display: block;
Expand Down
6 changes: 5 additions & 1 deletion .vitepress/theme/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import DefaultTheme from 'vitepress/theme'
import Layout from './Layout.vue'
import './custom.css'

export default DefaultTheme
export default {
extends: DefaultTheme,
Layout
}
19 changes: 18 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@ This repository contains the public documentation website for DiffPal.

Production site: https://diffpal.github.io/

Public documentation Markdown lives at the repository root so the organization-level GitHub Pages site publishes at `/`, not under a project path.
Canonical public documentation lives in the main
[`diffpal/diffpal`](https://github.com/diffpal/diffpal/tree/main/docs)
repository. This site records an immutable source commit in `docs-source.json`
and generates its documentation pages into `.generated/` before each build.
Only the homepage, theme, privacy policy, and site metadata are maintained here.

## Local Development

Expand All @@ -14,6 +18,13 @@ Install dependencies:
npm ci
```

Check out the locked canonical documentation source:

```bash
git clone https://github.com/diffpal/diffpal.git .source/diffpal
git -C .source/diffpal checkout "$(node -p "require('./docs-source.json').ref")"
```

Start the local VitePress server:

```bash
Expand All @@ -28,6 +39,12 @@ Build the static site:
npm run docs:build
```

Run the complete build, privacy, and synchronization checks with:

```bash
npm run check
```

Preview the generated site:

```bash
Expand Down
Loading