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
193 changes: 193 additions & 0 deletions .github/workflows/docs-deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
name: Deploy Docs

on:
push:
branches: [main]
paths:
- "docs/**"
- "src/**/*.cs"
- "src/**/*.csproj"
- "Directory.Build.props"
- "Directory.Packages.props"
- "*.md"
- ".github/workflows/docs-deploy.yml"
release:
types: [published]
workflow_dispatch:

permissions:
contents: write

concurrency:
group: docs-deploy
cancel-in-progress: false

jobs:
build:
runs-on: ubuntu-latest
timeout-minutes: 20
outputs:
version_path: ${{ steps.version.outputs.path }}
is_release: ${{ steps.version.outputs.is_release }}
version_tag: ${{ steps.version.outputs.tag }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0

- uses: actions/setup-dotnet@v4
with:
dotnet-version: "9.0.x"

- name: Cache NuGet packages
uses: actions/cache@v4
with:
path: ~/.nuget/packages
key: nuget-${{ runner.os }}-${{ hashFiles('**/*.csproj', '**/Directory.Packages.props') }}
restore-keys: nuget-${{ runner.os }}-

- name: Restore solution
run: dotnet restore Compendium.sln

- name: Install DocFX
run: dotnet tool install -g docfx
Copy link

Copilot AI Apr 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The workflow installs DocFX without pinning a version. Since the PR was validated against DocFX 2.78.5, using whatever the current latest tool is can introduce unexpected build breaks or output changes. Pin the tool version (e.g., dotnet tool install -g docfx --version <tested-version>) to make deployments reproducible.

Suggested change
run: dotnet tool install -g docfx
run: dotnet tool install -g docfx --version 2.78.5

Copilot uses AI. Check for mistakes.

- name: Determine target version path
id: version
run: |
if [ "${{ github.event_name }}" = "release" ]; then
TAG="${{ github.event.release.tag_name }}"
VERSION_NUM="${TAG#v}"
MAJOR_MINOR=$(echo "$VERSION_NUM" | cut -d. -f1-2)
echo "path=v$MAJOR_MINOR" >> "$GITHUB_OUTPUT"
echo "is_release=true" >> "$GITHUB_OUTPUT"
echo "tag=$TAG" >> "$GITHUB_OUTPUT"
else
echo "path=main" >> "$GITHUB_OUTPUT"
echo "is_release=false" >> "$GITHUB_OUTPUT"
echo "tag=" >> "$GITHUB_OUTPUT"
fi

- name: Sync ROADMAP into docs (if present)
run: |
if [ -f ROADMAP.md ]; then
{
echo '---'
echo 'uid: roadmap'
echo 'title: Roadmap'
echo '---'
echo
cat ROADMAP.md
} > docs/roadmap.md
echo "ROADMAP.md inlined into docs/roadmap.md"
else
echo "ROADMAP.md not found — keeping docs/roadmap.md placeholder"
fi

- name: Generate API metadata
run: docfx metadata docs/docfx.json

- name: Build documentation site
run: docfx build docs/docfx.json

- name: Upload site artifact
uses: actions/upload-artifact@v4
with:
name: docs-site
path: docs/_site/
retention-days: 7

deploy:
needs: build
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: Download site artifact
uses: actions/download-artifact@v4
with:
name: docs-site
path: site/

- name: Checkout or initialize gh-pages
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
set -euo pipefail
mkdir -p gh-pages
cd gh-pages
git init -q -b gh-pages
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git remote add origin "https://x-access-token:${GITHUB_TOKEN}@github.com/${GITHUB_REPOSITORY}.git"
if git fetch origin gh-pages --depth=1 2>/dev/null; then
git reset --hard origin/gh-pages
echo "Existing gh-pages checked out."
else
echo "No gh-pages branch yet — bootstrapping."
fi

- name: Deploy site to versioned path
env:
TARGET: ${{ needs.build.outputs.version_path }}
IS_RELEASE: ${{ needs.build.outputs.is_release }}
TAG: ${{ needs.build.outputs.version_tag }}
run: |
set -euo pipefail
cd gh-pages

# 1. Replace target subdir
rm -rf "$TARGET"
mkdir -p "$TARGET"
cp -r ../site/. "$TARGET/"

# 2. On release: also refresh latest/ and append to versions.json
if [ "$IS_RELEASE" = "true" ]; then
rm -rf latest
mkdir -p latest
cp -r ../site/. latest/

if [ ! -f versions.json ]; then
echo "[]" > versions.json
fi
jq --arg target "$TARGET" --arg tag "$TAG" \
'map(select(.version != $target)) | [{"version": $target, "title": $tag, "aliases": []}] + .' \
versions.json > versions.json.new
mv versions.json.new versions.json
fi

# 3. Ensure root redirect (latest > main)
if [ -d "latest" ]; then
REDIRECT_TARGET="latest/"
else
REDIRECT_TARGET="main/"
fi
cat > index.html <<HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Compendium documentation</title>
<meta http-equiv="refresh" content="0; url=./${REDIRECT_TARGET}" />
<link rel="canonical" href="https://sassy-solutions.github.io/compendium/${REDIRECT_TARGET}" />
</head>
<body>
<p>Redirecting to <a href="./${REDIRECT_TARGET}">./${REDIRECT_TARGET}</a>…</p>
</body>
</html>
HTML

# 4. Initial files
[ -f versions.json ] || echo "[]" > versions.json
touch .nojekyll

- name: Commit and push gh-pages
run: |
set -euo pipefail
cd gh-pages
git add -A
if git diff --cached --quiet; then
echo "No changes to publish."
exit 0
fi
git commit -m "docs: deploy ${{ needs.build.outputs.version_path }} from ${{ github.sha }}"
git push origin gh-pages
4 changes: 4 additions & 0 deletions docs/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
_site/
api/
obj/
.docfx/
5 changes: 5 additions & 0 deletions docs/adapters/aspnetcore.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Compendium.Adapters.AspNetCore

> Coming soon — tracked in [POM-184](https://github.com/sassy-solutions/compendium/issues?q=is%3Aissue+POM-184).

ASP.NET Core integration: tenant validation middleware, problem details, auth helpers.
5 changes: 5 additions & 0 deletions docs/adapters/lemonsqueezy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Compendium.Adapters.LemonSqueezy

> Coming soon — tracked in [POM-184](https://github.com/sassy-solutions/compendium/issues?q=is%3Aissue+POM-184).

LemonSqueezy billing adapter.
5 changes: 5 additions & 0 deletions docs/adapters/listmonk.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Compendium.Adapters.Listmonk

> Coming soon — tracked in [POM-184](https://github.com/sassy-solutions/compendium/issues?q=is%3Aissue+POM-184).

Listmonk newsletter adapter.
5 changes: 5 additions & 0 deletions docs/adapters/openrouter.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Compendium.Adapters.OpenRouter

> Coming soon — tracked in [POM-184](https://github.com/sassy-solutions/compendium/issues?q=is%3Aissue+POM-184).

OpenRouter AI provider adapter.
5 changes: 5 additions & 0 deletions docs/adapters/postgresql.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Compendium.Adapters.PostgreSQL

> Coming soon — tracked in [POM-184](https://github.com/sassy-solutions/compendium/issues?q=is%3Aissue+POM-184).

PostgreSQL event store and projection store.
5 changes: 5 additions & 0 deletions docs/adapters/redis.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Compendium.Adapters.Redis

> Coming soon — tracked in [POM-184](https://github.com/sassy-solutions/compendium/issues?q=is%3Aissue+POM-184).

Redis cache adapter.
5 changes: 5 additions & 0 deletions docs/adapters/stripe.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Compendium.Adapters.Stripe

> Coming soon — tracked in [POM-184](https://github.com/sassy-solutions/compendium/issues?q=is%3Aissue+POM-184).

Stripe billing adapter.
16 changes: 16 additions & 0 deletions docs/adapters/toc.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
- name: ASP.NET Core
href: aspnetcore.md
- name: PostgreSQL
href: postgresql.md
- name: Redis
href: redis.md
- name: Zitadel
href: zitadel.md
- name: Stripe
href: stripe.md
- name: LemonSqueezy
href: lemonsqueezy.md
- name: Listmonk
href: listmonk.md
- name: OpenRouter
href: openrouter.md
5 changes: 5 additions & 0 deletions docs/adapters/zitadel.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Compendium.Adapters.Zitadel

> Coming soon — tracked in [POM-184](https://github.com/sassy-solutions/compendium/issues?q=is%3Aissue+POM-184).

Zitadel OIDC identity adapter.
14 changes: 14 additions & 0 deletions docs/adr/toc.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
- name: Index
href: README.md
- name: 0001 — Result pattern
href: 0001-result-pattern.md
- name: 0002 — Hexagonal architecture
href: 0002-hexagonal-architecture.md
- name: 0003 — Zero-dependency Core
href: 0003-zero-dep-core.md
- name: 0004 — Multi-tenancy strategy
href: 0004-multi-tenancy-strategy.md
- name: 0005 — Event sourcing
href: 0005-event-sourcing-vs-state.md
- name: Template
href: 0000-template.md
5 changes: 5 additions & 0 deletions docs/concepts/event-sourcing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Event Sourcing

> Coming soon — tracked in [POM-183](https://github.com/sassy-solutions/compendium/issues?q=is%3Aissue+POM-183).

Why event sourcing, append-only stores, aggregates vs projections, and snapshots in Compendium. See also [ADR 0005](../adr/0005-event-sourcing-vs-state.md).
5 changes: 5 additions & 0 deletions docs/concepts/hexagonal-architecture.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Hexagonal Architecture

> Coming soon — tracked in [POM-183](https://github.com/sassy-solutions/compendium/issues?q=is%3Aissue+POM-183).

Core / Application / Adapters, ports vs adapters, why Compendium keeps Core dependency-free. See also [ADR 0002](../adr/0002-hexagonal-architecture.md) and [ADR 0003](../adr/0003-zero-dep-core.md).
5 changes: 5 additions & 0 deletions docs/concepts/multi-tenancy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Multi-tenancy

> Coming soon — tracked in [POM-183](https://github.com/sassy-solutions/compendium/issues?q=is%3Aissue+POM-183).

`TenantContext`, multi-source resolution (header / subdomain / JWT), and consistency validation. See also [ADR 0004](../adr/0004-multi-tenancy-strategy.md).
5 changes: 5 additions & 0 deletions docs/concepts/result-pattern.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Result Pattern

> Coming soon — tracked in [POM-183](https://github.com/sassy-solutions/compendium/issues?q=is%3Aissue+POM-183).

`Result<T>`, `Error`, and why Compendium does not use exceptions for control flow. See also [ADR 0001](../adr/0001-result-pattern.md).
8 changes: 8 additions & 0 deletions docs/concepts/toc.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
- name: Event Sourcing
href: event-sourcing.md
- name: Hexagonal Architecture
href: hexagonal-architecture.md
- name: Result Pattern
href: result-pattern.md
- name: Multi-tenancy
href: multi-tenancy.md
59 changes: 59 additions & 0 deletions docs/docfx.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
{
"$schema": "https://raw.githubusercontent.com/dotnet/docfx/main/schemas/docfx.schema.json",
"metadata": [
{
"src": [
{
"files": ["**/*.csproj"],
"src": "../src",
"exclude": ["**/Compendium.Adapters.Shared.csproj"]
Comment on lines +8 to +9
Copy link

Copilot AI Apr 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

exclude removes Compendium.Adapters.Shared.csproj from API metadata generation, but that project currently does not opt out of packing (no <IsPackable>false</IsPackable>), so it looks like a public package that will end up undocumented. Either include it in DocFX metadata, or explicitly mark the project as non-packable/internal so the exclusion matches the project intent.

Suggested change
"src": "../src",
"exclude": ["**/Compendium.Adapters.Shared.csproj"]
"src": "../src"

Copilot uses AI. Check for mistakes.
}
],
"dest": "api",
"includePrivateMembers": false,
"disableGitFeatures": false,
"disableDefaultFilter": false,
"noRestore": false,
"namespaceLayout": "flattened",
"memberLayout": "samePage",
"EnumSortOrder": "alphabetic",
"allowCompilationErrors": false
}
],
"build": {
"content": [
{
"files": ["**/*.{md,yml}"],
"exclude": ["_site/**", "obj/**"]
}
],
"resource": [
{
"files": ["images/**"]
}
],
"output": "_site",
"globalMetadata": {
"_appName": "Compendium",
"_appTitle": "Compendium — .NET event-sourcing framework",
"_enableSearch": true,
"_appFooter": "Copyright © 2026 Sassy Solutions. Released under the MIT License. <a href=\"https://github.com/sassy-solutions/compendium\">View on GitHub</a>.",
"_appLogoPath": "images/logo.svg",
"_appFaviconPath": "images/favicon.ico",
Comment on lines +41 to +42
Copy link

Copilot AI Apr 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

_appLogoPath/_appFaviconPath point to images/logo.svg and images/favicon.ico, but docs/images/ currently only contains .gitkeep. This will produce broken assets in the generated site (and may cause template warnings). Add the referenced files (even placeholders) or remove/adjust these metadata values.

Suggested change
"_appLogoPath": "images/logo.svg",
"_appFaviconPath": "images/favicon.ico",

Copilot uses AI. Check for mistakes.
"_gitContribute": {
"repo": "https://github.com/sassy-solutions/compendium",
"branch": "main"
},
"_disableContribution": false
},
"template": ["default", "modern"],
"postProcessors": ["ExtractSearchIndex"],
"keepFileLink": false,
"disableGitFeatures": false,
"sitemap": {
"baseUrl": "https://sassy-solutions.github.io/compendium/",
"priority": 0.5,
"changefreq": "weekly"
}
Comment on lines +52 to +57
Copy link

Copilot AI Apr 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DocFX sitemap baseUrl is set to https://sassy-solutions.github.io/compendium/, but this workflow deploys the site under versioned subpaths like /main/ and /vX.Y/. As a result, generated sitemap URLs will not match the actual published URLs. Consider setting baseUrl dynamically per deploy target (e.g., replace during workflow) or disabling sitemap generation until a per-version base URL is supported.

Suggested change
"disableGitFeatures": false,
"sitemap": {
"baseUrl": "https://sassy-solutions.github.io/compendium/",
"priority": 0.5,
"changefreq": "weekly"
}
"disableGitFeatures": false

Copilot uses AI. Check for mistakes.
}
}
13 changes: 13 additions & 0 deletions docs/getting-started.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Getting Started

> Coming soon — tracked in [POM-182](https://github.com/sassy-solutions/compendium/issues?q=is%3Aissue+POM-182).

This page will walk you through:

1. Installing the Compendium NuGet packages
2. Defining your first event-sourced aggregate
3. Wiring CQRS dispatchers in `Program.cs`
4. Dispatching a command and reading a projection
5. Running one of the [samples](https://github.com/sassy-solutions/compendium/tree/main/samples)

In the meantime, the [README](https://github.com/sassy-solutions/compendium/blob/main/README.md) has a Quick Start snippet.
Empty file added docs/images/.gitkeep
Empty file.
Loading
Loading