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
141 changes: 1 addition & 140 deletions .github/workflows/deploy-pages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,149 +25,10 @@ concurrency:

jobs:
docs-deploy:
name: Deploy documentation to GitHub Pages
if: github.event.workflow_run.conclusion == 'success'
uses: eclipse-score/cicd-workflows/.github/workflows/docs-publish.yml@dev
permissions:
actions: read
pages: write
id-token: write
contents: write
pull-requests: write
runs-on: ubuntu-latest
steps:
- name: Download build metadata
uses: actions/download-artifact@v8.0.1
with:
name: build-metadata
run-id: ${{ github.event.workflow_run.id }}
github-token: ${{ github.token }}

- name: Parse build metadata
id: metadata
run: |
EVENT_NAME=$(jq -r '.event_name' build-info.json)
PR_NUMBER=$(jq -r '.pr_number // empty' build-info.json)
REF_NAME=$(jq -r '.ref_name' build-info.json)

case "$EVENT_NAME" in
pull_request|push|merge_group|release) ;;
*)
echo "::error::Unexpected event_name: $EVENT_NAME"
exit 1
;;
esac

if [[ -n "$PR_NUMBER" && ! "$PR_NUMBER" =~ ^[0-9]+$ ]]; then
echo "::error::Invalid pr_number: $PR_NUMBER"
exit 1
fi

if [[ ! "$REF_NAME" =~ ^[a-zA-Z0-9._/-]+$ ]]; then
echo "::error::Invalid ref_name: $REF_NAME"
exit 1
fi

if [[ "$EVENT_NAME" == "merge_group" ]]; then
echo "should_deploy=false" >> "$GITHUB_OUTPUT"
else
echo "should_deploy=true" >> "$GITHUB_OUTPUT"
fi

echo "event_name=$EVENT_NAME" >> "$GITHUB_OUTPUT"
echo "pr_number=$PR_NUMBER" >> "$GITHUB_OUTPUT"
echo "ref_name=$REF_NAME" >> "$GITHUB_OUTPUT"

- name: Determine target folder
if: steps.metadata.outputs.should_deploy == 'true'
id: target
run: |
EVENT_NAME="${{ steps.metadata.outputs.event_name }}"
if [[ "$EVENT_NAME" == "pull_request" ]]; then
echo "folder=pr-${{ steps.metadata.outputs.pr_number }}" >> "$GITHUB_OUTPUT"
else
echo "folder=${{ steps.metadata.outputs.ref_name }}" >> "$GITHUB_OUTPUT"
fi

- name: Checkout gh-pages
if: steps.metadata.outputs.should_deploy == 'true'
uses: actions/checkout@v6
with:
ref: gh-pages
path: gh-pages-content

- name: Clean up old documentation
if: steps.metadata.outputs.should_deploy == 'true'
run: |
rm -rf "gh-pages-content/${{ steps.target.outputs.folder }}"

- name: Download documentation artifact
uses: actions/download-artifact@v8.0.1
with:
name: github-pages
run-id: ${{ github.event.workflow_run.id }}
github-token: ${{ github.token }}
path: gh-pages-content/${{ steps.target.outputs.folder }}

- name: Ensure .nojekyll exists
if: steps.metadata.outputs.should_deploy == 'true'
run: touch gh-pages-content/.nojekyll

- name: Extend versions.json
if: steps.metadata.outputs.should_deploy == 'true'
run: |
TARGET="${{ steps.target.outputs.folder }}"

# if versions.json does not exist, create it with an empty array as content
if [ ! -f gh-pages-content/versions.json ]; then
echo '[]' > gh-pages-content/versions.json
fi

# Add new version entry to versions.json if it doesn't already exist
if jq -e --arg v "$TARGET" 'map(select(.version == $v)) | length > 0' gh-pages-content/versions.json > /dev/null; then
echo "Version '$TARGET' already exists in versions.json"
else
REPO_NAME=$(basename "${{ github.repository }}")
OWNER_NAME="${{ github.repository_owner }}"
PAGES_URL="https://${OWNER_NAME}.github.io/${REPO_NAME}"
jq --arg v "$TARGET" --arg u "${PAGES_URL}/${TARGET}/" \
'. + [{"version": $v, "url": $u}]' gh-pages-content/versions.json > gh-pages-content/tmp.json && mv gh-pages-content/tmp.json gh-pages-content/versions.json
fi

- name: Commit and push changes to gh-pages
if: steps.metadata.outputs.should_deploy == 'true'
run: |
cd gh-pages-content
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add .
git commit -m "Update documentation for ${{ steps.target.outputs.folder }}" || echo "No changes to commit"
git push

- name: Create artifact from gh-pages
if: steps.metadata.outputs.should_deploy == 'true'
uses: actions/upload-pages-artifact@v3
with:
path: gh-pages-content

- name: Deploy artifact to GitHub Pages
if: steps.metadata.outputs.should_deploy == 'true'
id: deploy-pages
uses: actions/deploy-pages@v4

- name: Find existing PR comment
if: steps.metadata.outputs.should_deploy == 'true' && steps.metadata.outputs.event_name == 'pull_request' && steps.metadata.outputs.pr_number != ''
uses: peter-evans/find-comment@v3
id: fc
with:
issue-number: ${{ steps.metadata.outputs.pr_number }}
comment-author: 'github-actions[bot]'
body-includes: Documentation preview for this pull request

- name: Comment on PR with preview link
if: steps.metadata.outputs.should_deploy == 'true' && steps.metadata.outputs.event_name == 'pull_request' && steps.metadata.outputs.pr_number != '' && steps.fc.outputs.comment-id == ''
uses: peter-evans/create-or-update-comment@v4
with:
issue-number: ${{ steps.metadata.outputs.pr_number }}
body: |
Documentation preview for this pull request is available at:
**${{ steps.target.outputs.folder }}**: https://${{ github.repository_owner }}.github.io/${{ github.event.repository.name }}/${{ steps.target.outputs.folder }}/
45 changes: 5 additions & 40 deletions .github/workflows/pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,56 +13,21 @@

name: PR

permissions:
contents: read

on:
pull_request:
types: [opened, reopened, synchronize]
push:
branches:
- main # docs are built only on push to main branch, for feature branches there are PR builds
- main
merge_group:
types: [checks_requested]
release:
types: [created]

permissions:
contents: read

jobs:
docs-build:
name: Build documentation
runs-on: ubuntu-latest
steps:
- uses: eclipse-score/more-disk-space@v1

- name: Check out
uses: actions/checkout@v6

- name: Build documentation
run: |
bazel run //:docs -- --github_user=${{ github.repository_owner }} --github_repo=${{ github.event.repository.name }}

- name: Upload documentation artifact
uses: actions/upload-artifact@v7.0.1
with:
name: github-pages
path: _build
retention-days: 1
if-no-files-found: error

- name: Create build metadata
run: |
cat > build-info.json <<'EOF'
{
"event_name": "${{ github.event_name }}",
"pr_number": "${{ github.event.pull_request.number }}",
"ref_name": "${{ github.ref_name }}",
"head_sha": "${{ github.sha }}"
}
EOF

- name: Upload build metadata
uses: actions/upload-artifact@v7.0.1
with:
name: build-metadata
path: build-info.json
retention-days: 1
uses: eclipse-score/cicd-workflows/.github/workflows/docs.yml@dev
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ bazel-*
/_build*
docs/ubproject.toml

# Python
__pycache__/
.ruff_cache/

# AI
/.claude
/.codex
28 changes: 28 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
repos:
- repo: local
hooks:
- id: aggregate-status
name: Aggregate chapter statuses
entry: python3 scripts/aggregate_status.py
language: system
pass_filenames: false
files: ^(docs/explanation/.*\.md|scripts/aggregate_status\.py)$
exclude: ^docs/explanation/index\.md$
- id: generate-mindmap
name: Generate infrastructure chapter map
entry: python3 scripts/generate_mindmap.py
language: system
pass_filenames: false
files: ^(docs/explanation/[0-9][0-9]-.*\.md|docs/explanation/index\.md|scripts/generate_mindmap\.py)$
- id: ruff-check
name: ruff-check
entry: scripts/run_tool.sh ruff check --fix
language: system
require_serial: true
types: [python]
- id: ruff-format
name: ruff-format
entry: scripts/run_tool.sh ruff format
language: system
require_serial: true
types: [python]
101 changes: 101 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
@CONTRIBUTING.md

# Repository

S-CORE infrastructure documentation site. Published at <https://eclipse-score.github.io/infrastructure/>.

This is a documentation-only repository — no application code, no tests beyond the docs build.

# Documentation Structure

The site uses the [Divio documentation system](https://docs.divio.com/documentation-system/) with four quadrants:

| Directory | Quadrant | Content type |
|---|---|---|
| `docs/tutorials/` | Tutorials | Step-by-step learning guides for newcomers |
| `docs/how-to/` | How-to Guides | Task-oriented recipes for practitioners |
| `docs/reference/` | Reference | Factual lookup material (repos, config, versions) |
| `docs/explanation/` | Explanation | Architecture, design rationale, maturity assessment |

The explanation quadrant contains the numbered landscape chapters (`01-source-code-infrastructure.md` through `10-infrastructure-operations.md`) plus an index page with an interactive mindmap.

`docs/index.md` is the landing page with a Divio grid, quadrant link lists, and team quick links.

## When editing documentation

Before writing anything, answer: **What is the reader trying to do right now?**

| Reader intent | Quadrant |
|---|---|
| "I am learning — walk me through it" | Tutorial |
| "I know what I want — tell me how" | How-to |
| "I need to look up a value or option" | Reference |
| "I want to understand why this works the way it does" | Explanation |

If the reader intent does not match the quadrant you are editing, move the content — do not add it anyway.

### Hard rules per quadrant

**Tutorials** (`docs/tutorials/`)
- Sequential steps from zero to a working result. Never assume prior knowledge beyond the stated prerequisites.
- ❌ No lookup tables — move to Reference
- ❌ No architecture explanations — move to Explanation
- ❌ No "assumes you already have X set up" — that is a How-to

**How-to guides** (`docs/how-to/`)
- One goal, concrete steps, done. Assumes a working environment.
- ❌ No concept introductions or "why this works" paragraphs — move to Explanation or link to Tutorial
- ❌ No lookup tables (option lists, feature matrices, version tables) — move to Reference
- ❌ No content that duplicates a Tutorial — replace with a one-sentence description and a link

**Reference** (`docs/reference/`)
- Dry, factual, lookup-only. Tables, exact values, flag lists.
- ❌ No narrative prose explaining motivation — move to Explanation
- ❌ No procedural steps — move to How-to

**Explanation** (`docs/explanation/`)
- Architecture, design decisions, tradeoffs, maturity assessment. Prose-heavy.
- ❌ No step-by-step instructions — move to How-to
- ❌ No exact configuration values as the primary content — those belong in Reference

### When a topic spans quadrants

Each quadrant develops its own treatment fully — do not stub out a quadrant just because another quadrant covers the same topic from a different angle. A topic can have a complete tutorial, a complete how-to, and complete reference material at the same time.

What to avoid is writing the *same content type* in two places: if a how-to and a tutorial both contain the same step-by-step instructions, one of them is wrong. Remove the duplicate, not the quadrant.

## Cross-chapter rules in the explanation quadrant

The explanation chapters have specific ownership rules for cross-cutting topics. Before editing a chapter, check CONTRIBUTING.md for which chapter canonically owns which topic. Write the main narrative in the canonical chapter and use brief perspective-specific summaries with links elsewhere.

# Build & Validation

```bash
bazel run //:docs # build documentation
bazel run //:live_preview # local preview with live reload
bazel run //:docs_check # quick check during development
bazel run //:docs # full build — required before commit
bazel run //:ide_support # create .venv_docs for IDE integration
```

A change is not complete until `bazel run //:docs` passes cleanly.

# Pre-commit Hooks

Two hooks auto-update generated content in the explanation quadrant:

- `aggregate-status` — rolls up subsection maturity markers (🟢🟡🟠🔴⚪) to section and chapter headings
- `generate-mindmap` — regenerates the chapter map in `docs/explanation/index.md` from chapter headings

If not using pre-commit, run manually:

```bash
python3 scripts/aggregate_status.py
python3 scripts/generate_mindmap.py
```

# Navigation

Navigation is defined by `toctree` directives in the section index files (`docs/tutorials/index.md`, `docs/how-to/index.md`, `docs/reference/index.md`, `docs/explanation/index.md`). The top-level `docs/index.md` includes a hidden toctree pointing to these four section indices.

When adding a new page, add it to the appropriate section's toctree. Pages without a toctree entry will cause build warnings.
1 change: 1 addition & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
@AGENTS.md
Loading