From 3a46a98be34ba348716ae6dfe532f0f3b42eb9c6 Mon Sep 17 00:00:00 2001 From: "Billy D." Date: Mon, 9 Feb 2026 17:25:27 -0500 Subject: [PATCH] docs: add ADR index workflow, standardize all ADR formats - Add Gitea Action to auto-update README badges and ADR table on push - Standardize 8 ADRs from heading-style to inline metadata format - Add shields.io badges for ADR counts (total/accepted/proposed) - Replace static directory listing with linked ADR table in README - Accept ADR-0030 (MFA/YubiKey strategy) --- .gitea/workflows/update-adr-readme.yaml | 108 ++++++++++++++++++ README.md | 56 ++++++++- decisions/0014-docker-build-best-practices.md | 13 +-- ...i-notifications-and-semantic-versioning.md | 13 +-- decisions/0019-handler-deployment-strategy.md | 13 +-- decisions/0020-internal-registry-for-cicd.md | 13 +-- decisions/0021-notification-architecture.md | 9 +- decisions/0022-ntfy-discord-bridge.md | 9 +- decisions/0023-valkey-ml-caching.md | 9 +- decisions/0024-ray-repository-structure.md | 13 +-- decisions/0030-mfa-yubikey-strategy.md | 4 +- 11 files changed, 200 insertions(+), 60 deletions(-) create mode 100644 .gitea/workflows/update-adr-readme.yaml diff --git a/.gitea/workflows/update-adr-readme.yaml b/.gitea/workflows/update-adr-readme.yaml new file mode 100644 index 0000000..c928733 --- /dev/null +++ b/.gitea/workflows/update-adr-readme.yaml @@ -0,0 +1,108 @@ +name: Update README with ADR Index + +on: + push: + branches: + - main + paths: + - 'decisions/**.md' + - '.gitea/workflows/update-adr-readme.yaml' + workflow_dispatch: + +jobs: + update-readme: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 1 + + - name: Generate ADR table and update README + run: | + set -euo pipefail + + TABLE_HEADER="| # | Decision | Status | Date |" + TABLE_SEPARATOR="|---|----------|--------|------|" + TABLE_ROWS="" + TOTAL=0 + ACCEPTED=0 + PROPOSED=0 + SUPERSEDED=0 + DEPRECATED=0 + + for file in decisions/[0-9][0-9][0-9][0-9]-*.md; do + [ -f "$file" ] || continue + + # Extract ADR number from filename + num=$(basename "$file" | grep -oP '^\d+') + + # Skip the template + [ "$num" = "0000" ] && continue + + # Parse title from first heading line + title=$(head -1 "$file" | sed 's/^#\s*//') + + # Parse status: "* Status: accepted" + status=$(grep -m1 -iP '^\*\s*Status:\s*' "$file" \ + | sed 's/^\*\s*Status:\s*//i' | xargs) + + # Parse date: "* Date: 2026-02-04" + date=$(grep -m1 -iP '^\*\s*Date:\s*' "$file" \ + | sed 's/^\*\s*Date:\s*//i' | xargs) + + # Status emoji + case "$(echo "$status" | tr '[:upper:]' '[:lower:]')" in + accepted) badge="✅" ; ACCEPTED=$((ACCEPTED+1)) ;; + proposed) badge="📝" ; PROPOSED=$((PROPOSED+1)) ;; + superseded*) badge="♻️" ; SUPERSEDED=$((SUPERSEDED+1)) ;; + deprecated) badge="⛔" ; DEPRECATED=$((DEPRECATED+1)) ;; + *) badge="❓" ;; + esac + + TOTAL=$((TOTAL+1)) + TABLE_ROWS="${TABLE_ROWS}| ${num} | [${title}](${file}) | ${badge} ${status} | ${date} |\n" + done + + # Build the full table block + ADR_TABLE=$(printf '%s\n%s\n%s' "$TABLE_HEADER" "$TABLE_SEPARATOR" "$(echo -e "$TABLE_ROWS")") + + # Build badge line (shields.io static badge) + BADGE_LINE="![ADR Count](https://img.shields.io/badge/ADRs-${TOTAL}_total-blue?logo=bookstack) ![Accepted](https://img.shields.io/badge/accepted-${ACCEPTED}-brightgreen) ![Proposed](https://img.shields.io/badge/proposed-${PROPOSED}-yellow)" + + # Replace the ADR badges marker + if grep -q '' README.md; then + sed -i '//,//c\\n'"${BADGE_LINE}"'\n' README.md + else + echo "::warning::Missing marker in README.md" + fi + + # Replace the ADR table marker + if grep -q '' README.md; then + # Use awk to replace content between markers (handles multi-line) + awk -v table="$ADR_TABLE" ' + // { print; print table; skip=1; next } + // { skip=0 } + !skip { print } + ' README.md > README.md.tmp && mv README.md.tmp README.md + else + echo "::warning::Missing marker in README.md" + fi + + # Update the "Last updated" date + TODAY=$(date +%Y-%m-%d) + sed -i "s|^\*Last updated:.*\*$|*Last updated: ${TODAY}*|" README.md + + - name: Check for changes + id: changes + run: | + git diff --quiet README.md && echo "changed=false" >> "$GITHUB_OUTPUT" || echo "changed=true" >> "$GITHUB_OUTPUT" + + - name: Commit and push + if: steps.changes.outputs.changed == 'true' + run: | + git config user.name "Gitea Actions" + git config user.email "actions@daviestechlabs.io" + git add README.md + git commit -m "docs: auto-update ADR index in README [skip ci]" + git push diff --git a/README.md b/README.md index 35449c6..0611225 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,10 @@ [![Flux](https://img.shields.io/badge/GitOps-Flux-blue?logo=flux)](https://fluxcd.io) [![License](https://img.shields.io/badge/License-MIT-green)](LICENSE) + +![ADR Count](https://img.shields.io/badge/ADRs-37_total-blue?logo=bookstack) ![Accepted](https://img.shields.io/badge/accepted-35-brightgreen) ![Proposed](https://img.shields.io/badge/proposed-1-yellow) + + ## 📖 Quick Navigation | Document | Purpose | @@ -77,15 +81,55 @@ homelab-design/ ├── DOMAIN-MODEL.md # Core entities ├── CODING-CONVENTIONS.md # Patterns & practices ├── GLOSSARY.md # Terminology -├── decisions/ # ADRs -│ ├── 0000-template.md -│ ├── 0001-record-architecture-decisions.md -│ ├── 0002-use-talos-linux.md -│ └── ... +├── decisions/ # Architecture Decision Records ├── specs/ # Feature specifications └── diagrams/ # Additional diagrams ``` +### Architecture Decision Records + + +| # | Decision | Status | Date | +|---|----------|--------|------| +| 0001 | [Record Architecture Decisions](decisions/0001-record-architecture-decisions.md) | ✅ accepted | 2025-11-30 | +| 0002 | [Use Talos Linux for Kubernetes Nodes](decisions/0002-use-talos-linux.md) | ✅ accepted | 2025-11-30 | +| 0003 | [Use NATS for AI/ML Messaging](decisions/0003-use-nats-for-messaging.md) | ✅ accepted | 2025-12-01 | +| 0004 | [Use MessagePack for NATS Messages](decisions/0004-use-messagepack-for-nats.md) | ✅ accepted | 2025-12-01 | +| 0005 | [Multi-GPU Heterogeneous Strategy](decisions/0005-multi-gpu-strategy.md) | ✅ accepted | 2025-12-01 | +| 0006 | [GitOps with Flux CD](decisions/0006-gitops-with-flux.md) | ✅ accepted | 2025-11-30 | +| 0007 | [Use KServe for ML Model Serving](decisions/0007-use-kserve-for-inference.md) | ♻️ superseded by ADR-0011 | 2025-12-15 | +| 0008 | [Use Milvus for Vector Storage](decisions/0008-use-milvus-for-vectors.md) | ✅ accepted | 2025-12-15 | +| 0009 | [Dual Workflow Engine Strategy](decisions/0009-dual-workflow-engines.md) | ✅ accepted | 2026-01-15 | +| 0010 | [Use Envoy Gateway for Ingress](decisions/0010-use-envoy-gateway.md) | ✅ accepted | 2025-12-01 | +| 0011 | [Use KubeRay as Unified GPU Backend](decisions/0011-kuberay-unified-gpu-backend.md) | ✅ accepted | 2026-02-02 | +| 0012 | [Use uv for Python Development](decisions/0012-use-uv-for-python-development.md) | ✅ accepted | 2026-02-02 | +| 0013 | [Use Gitea Actions for CI/CD](decisions/0013-gitea-actions-for-ci.md) | ✅ accepted | 2026-02-02 | +| 0014 | [Docker Build Best Practices](decisions/0014-docker-build-best-practices.md) | ✅ accepted | 2026-02-02 | +| 0015 | [CI Notifications and Semantic Versioning](decisions/0015-ci-notifications-and-semantic-versioning.md) | ✅ accepted | 2026-02-02 | +| 0016 | [Affine Email Verification Strategy](decisions/0016-affine-email-verification-strategy.md) | 📝 proposed | 2026-02-04 | +| 0017 | [Secrets Management Strategy](decisions/0017-secrets-management-strategy.md) | ✅ accepted | 2026-02-04 | +| 0018 | [Security Policy Enforcement](decisions/0018-security-policy-enforcement.md) | ✅ accepted | 2026-02-04 | +| 0019 | [Python Module Deployment Strategy](decisions/0019-handler-deployment-strategy.md) | ✅ accepted | 2026-02-02 | +| 0020 | [Internal Registry URLs for CI/CD](decisions/0020-internal-registry-for-cicd.md) | ✅ accepted | 2026-02-02 | +| 0021 | [Notification Architecture](decisions/0021-notification-architecture.md) | ✅ accepted | 2026-02-04 | +| 0022 | [ntfy-Discord Bridge Service](decisions/0022-ntfy-discord-bridge.md) | ✅ accepted | 2026-02-04 | +| 0023 | [Valkey for ML Inference Caching](decisions/0023-valkey-ml-caching.md) | ✅ accepted | 2026-02-04 | +| 0024 | [Ray Repository Structure](decisions/0024-ray-repository-structure.md) | ✅ accepted | 2026-02-03 | +| 0025 | [Observability Stack Architecture](decisions/0025-observability-stack.md) | ✅ accepted | 2026-02-04 | +| 0026 | [Tiered Storage Strategy](decisions/0026-storage-strategy.md) | ✅ accepted | 2026-02-04 | +| 0027 | [Database Strategy with CloudNativePG](decisions/0027-database-strategy.md) | ✅ accepted | 2026-02-04 | +| 0028 | [Authentik Single Sign-On Strategy](decisions/0028-authentik-sso-strategy.md) | ✅ accepted | 2026-02-04 | +| 0029 | [Authentik User Registration Workflow](decisions/0029-authentik-user-registration-workflow.md) | ✅ accepted | 2026-02-04 | +| 0030 | [MFA and Yubikey Strategy](decisions/0030-mfa-yubikey-strategy.md) | ✅ accepted | 2026-02-04 | +| 0031 | [Gitea CI/CD Pipeline Strategy](decisions/0031-gitea-cicd-strategy.md) | ✅ accepted | 2026-02-04 | +| 0032 | [Velero Backup and Disaster Recovery](decisions/0032-velero-backup-strategy.md) | ✅ accepted | 2026-02-05 | +| 0033 | [Data Analytics Platform Architecture](decisions/0033-data-analytics-platform.md) | ✅ accepted | 2026-02-05 | +| 0034 | [Volcano Batch Scheduling Strategy](decisions/0034-volcano-batch-scheduling.md) | ✅ accepted | 2026-02-05 | +| 0035 | [ARM64 Raspberry Pi Worker Strategy](decisions/0035-arm64-worker-strategy.md) | ✅ accepted | 2026-02-05 | +| 0036 | [Automated Dependency Updates with Renovate](decisions/0036-renovate-dependency-updates.md) | ✅ accepted | 2026-02-05 | +| 0037 | [Node Naming Conventions](decisions/0037-node-naming-conventions.md) | ✅ accepted | 2026-02-05 | + + ## 🔗 Related Repositories | Repository | Purpose | @@ -102,4 +146,4 @@ homelab-design/ --- -*Last updated: 2026-02-01* +*Last updated: 2026-02-09* diff --git a/decisions/0014-docker-build-best-practices.md b/decisions/0014-docker-build-best-practices.md index b2cc324..f1f1046 100644 --- a/decisions/0014-docker-build-best-practices.md +++ b/decisions/0014-docker-build-best-practices.md @@ -1,12 +1,9 @@ -# ADR-0014: Docker Build Best Practices +# Docker Build Best Practices -## Status - -Accepted - -## Date - -2026-02-02 +* Status: accepted +* Date: 2026-02-02 +* Deciders: Billy +* Technical Story: Standardize container build practices for GPU-heavy ML images ## Context diff --git a/decisions/0015-ci-notifications-and-semantic-versioning.md b/decisions/0015-ci-notifications-and-semantic-versioning.md index 450a43d..e4809d6 100644 --- a/decisions/0015-ci-notifications-and-semantic-versioning.md +++ b/decisions/0015-ci-notifications-and-semantic-versioning.md @@ -1,12 +1,9 @@ -# ADR-0015: CI Notifications and Semantic Versioning +# CI Notifications and Semantic Versioning -## Status - -Accepted - -## Date - -2026-02-02 +* Status: accepted +* Date: 2026-02-02 +* Deciders: Billy +* Technical Story: Add pipeline notifications and automated versioning to Gitea Actions CI ## Context diff --git a/decisions/0019-handler-deployment-strategy.md b/decisions/0019-handler-deployment-strategy.md index e783b69..fbadd4a 100644 --- a/decisions/0019-handler-deployment-strategy.md +++ b/decisions/0019-handler-deployment-strategy.md @@ -1,12 +1,9 @@ -# ADR-0019: Python Module Deployment Strategy +# Python Module Deployment Strategy -## Status - -Accepted - -## Date - -2026-02-02 +* Status: accepted +* Date: 2026-02-02 +* Deciders: Billy +* Technical Story: Define how Python handler modules are packaged and deployed to Kubernetes ## Context diff --git a/decisions/0020-internal-registry-for-cicd.md b/decisions/0020-internal-registry-for-cicd.md index 9e14b39..0f5fa67 100644 --- a/decisions/0020-internal-registry-for-cicd.md +++ b/decisions/0020-internal-registry-for-cicd.md @@ -1,12 +1,9 @@ -# ADR-0020: Internal Registry URLs for CI/CD +# Internal Registry URLs for CI/CD -## Status - -Accepted - -## Date - -2026-02-02 +* Status: accepted +* Date: 2026-02-02 +* Deciders: Billy +* Technical Story: Bypass Cloudflare 100MB limit by using internal registry endpoints for CI pushes ## Context diff --git a/decisions/0021-notification-architecture.md b/decisions/0021-notification-architecture.md index 6c10783..12a31b8 100644 --- a/decisions/0021-notification-architecture.md +++ b/decisions/0021-notification-architecture.md @@ -1,8 +1,9 @@ -# ADR-0021: Notification Architecture +# Notification Architecture -## Status - -Accepted +* Status: accepted +* Date: 2026-02-04 +* Deciders: Billy +* Technical Story: Unify notification delivery across CI, alerting, and monitoring systems ## Context diff --git a/decisions/0022-ntfy-discord-bridge.md b/decisions/0022-ntfy-discord-bridge.md index 7f17afc..84ed688 100644 --- a/decisions/0022-ntfy-discord-bridge.md +++ b/decisions/0022-ntfy-discord-bridge.md @@ -1,8 +1,9 @@ -# ADR-0022: ntfy-Discord Bridge Service +# ntfy-Discord Bridge Service -## Status - -Accepted +* Status: accepted +* Date: 2026-02-04 +* Deciders: Billy +* Technical Story: Forward ntfy notifications to Discord webhooks with proper embed formatting ## Context diff --git a/decisions/0023-valkey-ml-caching.md b/decisions/0023-valkey-ml-caching.md index a7e5bb0..e3c0ba1 100644 --- a/decisions/0023-valkey-ml-caching.md +++ b/decisions/0023-valkey-ml-caching.md @@ -1,8 +1,9 @@ -# ADR-0023: Valkey for ML Inference Caching +# Valkey for ML Inference Caching -## Status - -Accepted +* Status: accepted +* Date: 2026-02-04 +* Deciders: Billy +* Technical Story: Consolidate and configure Valkey for ML caching use cases ## Context diff --git a/decisions/0024-ray-repository-structure.md b/decisions/0024-ray-repository-structure.md index 918277d..0d8a014 100644 --- a/decisions/0024-ray-repository-structure.md +++ b/decisions/0024-ray-repository-structure.md @@ -1,12 +1,9 @@ -# ADR-0024: Ray Repository Structure +# Ray Repository Structure -## Status - -Accepted - -## Date - -2026-02-03 +* Status: accepted +* Date: 2026-02-03 +* Deciders: Billy +* Technical Story: Document repository layout for Ray Serve and KubeRay image components ## Context diff --git a/decisions/0030-mfa-yubikey-strategy.md b/decisions/0030-mfa-yubikey-strategy.md index f14fd08..e864479 100644 --- a/decisions/0030-mfa-yubikey-strategy.md +++ b/decisions/0030-mfa-yubikey-strategy.md @@ -1,6 +1,6 @@ # MFA and Yubikey Strategy -* Status: proposed +* Status: accepted * Date: 2026-02-04 * Deciders: Billy * Technical Story: Enable hardware security key (Yubikey) authentication across homelab applications @@ -52,7 +52,7 @@ WebAuthn provides the best security (phishing-resistant) and user experience (to | Application | WebAuthn Support | Current Status | Action Required | |-------------|------------------|----------------|-----------------| -| Authentik | ✅ Native | ⚠️ In Progress | Configure enforcement policies | +| Authentik | ✅ Native | ✅ Implemented | Blueprint deployed via ConfigMap | | Vaultwarden | ✅ Native | ✅ Implemented | None - WebAuthn enrolled | ## Authentik Configuration