Skip to content

Commit 5b89d66

Browse files
committed
Website: add documentation guidelines + code ref in doc
1 parent 4fd97df commit 5b89d66

File tree

7 files changed

+297
-0
lines changed

7 files changed

+297
-0
lines changed
Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
#!/usr/bin/env bash
2+
# Verify that code references in documentation match actual source code
3+
# This script extracts CODE_REFERENCE comments from markdown files and validates
4+
# that the referenced code still exists at the specified line numbers
5+
6+
set -euo pipefail
7+
8+
# Colors for output
9+
RED='\033[0;31m'
10+
GREEN='\033[0;32m'
11+
YELLOW='\033[1;33m'
12+
NC='\033[0m' # No Color
13+
14+
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
15+
DOCS_DIR="${REPO_ROOT}/website/docs"
16+
EXIT_CODE=0
17+
TOTAL_REFS=0
18+
VALID_REFS=0
19+
INVALID_REFS=0
20+
21+
echo "Verifying code references in documentation..."
22+
echo "Repository root: ${REPO_ROOT}"
23+
echo ""
24+
25+
# Find all markdown files with CODE_REFERENCE comments
26+
while IFS= read -r doc_file; do
27+
# Extract CODE_REFERENCE comments from this file
28+
while IFS= read -r line_num; do
29+
# Get the actual line content
30+
comment_line=$(sed -n "${line_num}p" "$doc_file")
31+
32+
# Extract file path and line range from comment
33+
# Format: <!-- CODE_REFERENCE: path/to/file.rs#L123-L456 -->
34+
if [[ $comment_line =~ CODE_REFERENCE:\ *([^#]+)#L([0-9]+)-L([0-9]+) ]]; then
35+
file_path="${BASH_REMATCH[1]}"
36+
start_line="${BASH_REMATCH[2]}"
37+
end_line="${BASH_REMATCH[3]}"
38+
39+
# Trim whitespace from file_path
40+
file_path=$(echo "$file_path" | xargs)
41+
42+
TOTAL_REFS=$((TOTAL_REFS + 1))
43+
44+
# Check if the source file exists
45+
source_file="${REPO_ROOT}/${file_path}"
46+
if [[ ! -f "$source_file" ]]; then
47+
echo -e "${RED}${NC} Invalid reference in ${doc_file}:${line_num}"
48+
echo " File not found: ${file_path}"
49+
INVALID_REFS=$((INVALID_REFS + 1))
50+
EXIT_CODE=1
51+
continue
52+
fi
53+
54+
# Check if the line range is valid
55+
total_lines=$(wc -l < "$source_file")
56+
if [[ $end_line -gt $total_lines ]]; then
57+
echo -e "${RED}${NC} Invalid reference in ${doc_file}:${line_num}"
58+
echo " Line range L${start_line}-L${end_line} exceeds file length (${total_lines} lines)"
59+
echo " File: ${file_path}"
60+
INVALID_REFS=$((INVALID_REFS + 1))
61+
EXIT_CODE=1
62+
continue
63+
fi
64+
65+
# Extract the actual code from source file
66+
actual_code=$(sed -n "${start_line},${end_line}p" "$source_file")
67+
68+
# Find the corresponding code block in the markdown (should be right after the comment)
69+
# Look for ```rust reference block within next 5 lines
70+
code_block_start=$((line_num + 1))
71+
code_block_end=$((line_num + 10))
72+
73+
# Extract GitHub URL from the reference block
74+
github_url=$(sed -n "${code_block_start},${code_block_end}p" "$doc_file" | grep "github.com" | head -1)
75+
76+
if [[ -n "${github_url}" ]]; then
77+
# Verify the GitHub URL contains correct line range
78+
line_range_pattern="#L${start_line}-L${end_line}"
79+
if [[ "${github_url}" =~ ${line_range_pattern} ]]; then
80+
# Extract GitHub raw URL from the reference
81+
# Convert: https://github.com/o1-labs/mina-rust/blob/develop/path/to/file.rs#L10-L20
82+
# To: https://raw.githubusercontent.com/o1-labs/mina-rust/develop/path/to/file.rs
83+
if [[ "${github_url}" =~ github\.com/([^/]+)/([^/]+)/blob/([^/]+)/([^#]+) ]]; then
84+
org="${BASH_REMATCH[1]}"
85+
repo="${BASH_REMATCH[2]}"
86+
branch="${BASH_REMATCH[3]}"
87+
gh_file_path="${BASH_REMATCH[4]}"
88+
89+
raw_url="https://raw.githubusercontent.com/${org}/${repo}/${branch}/${gh_file_path}"
90+
91+
# Fetch the code from GitHub
92+
github_code=$(curl -s "${raw_url}" | sed -n "${start_line},${end_line}p")
93+
94+
# Compare local code with GitHub code
95+
if [[ "${actual_code}" == "${github_code}" ]]; then
96+
echo -e "${GREEN}${NC} Valid reference in ${doc_file}:${line_num}"
97+
echo " ${file_path}#L${start_line}-L${end_line}"
98+
echo " Local code matches GitHub (${branch})"
99+
VALID_REFS=$((VALID_REFS + 1))
100+
else
101+
echo -e "${RED}${NC} Code mismatch in ${doc_file}:${line_num}"
102+
echo " ${file_path}#L${start_line}-L${end_line}"
103+
echo " Local code differs from GitHub (${branch})"
104+
echo " This may indicate uncommitted changes or branch divergence"
105+
INVALID_REFS=$((INVALID_REFS + 1))
106+
EXIT_CODE=1
107+
fi
108+
else
109+
echo -e "${YELLOW}${NC} Could not parse GitHub URL in ${doc_file}:${line_num}"
110+
echo " URL: ${github_url}"
111+
INVALID_REFS=$((INVALID_REFS + 1))
112+
EXIT_CODE=1
113+
fi
114+
else
115+
echo -e "${YELLOW}${NC} Mismatched line range in ${doc_file}:${line_num}"
116+
echo " CODE_REFERENCE comment specifies: L${start_line}-L${end_line}"
117+
echo " But GitHub URL has different line range"
118+
INVALID_REFS=$((INVALID_REFS + 1))
119+
EXIT_CODE=1
120+
fi
121+
else
122+
echo -e "${YELLOW}${NC} No GitHub URL found for reference in ${doc_file}:${line_num}"
123+
echo " Expected rust reference block with GitHub URL"
124+
INVALID_REFS=$((INVALID_REFS + 1))
125+
EXIT_CODE=1
126+
fi
127+
fi
128+
done < <(grep -n "CODE_REFERENCE:" "$doc_file" | cut -d: -f1)
129+
done < <(find "$DOCS_DIR" -name "*.md" -o -name "*.mdx")
130+
131+
echo ""
132+
echo "================================"
133+
echo "Code Reference Verification Summary"
134+
echo "================================"
135+
echo -e "Total references checked: ${TOTAL_REFS}"
136+
echo -e "${GREEN}Valid references: ${VALID_REFS}${NC}"
137+
if [[ $INVALID_REFS -gt 0 ]]; then
138+
echo -e "${RED}Invalid references: ${INVALID_REFS}${NC}"
139+
else
140+
echo -e "${GREEN}Invalid references: ${INVALID_REFS}${NC}"
141+
fi
142+
echo ""
143+
144+
if [[ $EXIT_CODE -eq 0 ]]; then
145+
echo -e "${GREEN}✓ All code references are valid!${NC}"
146+
else
147+
echo -e "${RED}✗ Some code references are invalid. Please update the documentation.${NC}"
148+
fi
149+
150+
exit $EXIT_CODE

.github/workflows/docs.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@ jobs:
5151
# - ./github/workflows/lint.yaml
5252
toolchain: nightly
5353

54+
- name: Verify code references in documentation
55+
run: bash .github/scripts/verify-code-references.sh
56+
5457
- name: Build documentation
5558
run: make docs-build
5659

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
---
2+
sidebar_position: 10
3+
title: Documentation Guidelines
4+
description: Best practices for writing and maintaining documentation
5+
slug: /developers/documentation-guidelines
6+
---
7+
8+
# Documentation Guidelines
9+
10+
This guide explains how to write and maintain documentation for the Mina Rust
11+
project, including how to reference code from the codebase. Referencing code
12+
from codebases can be useful to check compatibility between implementations. For
13+
instance, we can have pages where the Rust code is compared to the OCaml code to
14+
discuss the differences or similarities.
15+
16+
## Referencing Code in Documentation
17+
18+
To keep documentation synchronized with the actual codebase, we use the
19+
[`docusaurus-theme-github-codeblock`](https://github.com/christian-bromann/docusaurus-theme-github-codeblock)
20+
plugin that automatically fetches code from GitHub.
21+
22+
### How to add code references
23+
24+
Use this pattern to reference code snippets:
25+
26+
````
27+
<!-- CODE_REFERENCE: path/to/file.rs#LStartLine-LEndLine -->
28+
29+
```rust reference title="path/to/file.rs"
30+
https://github.com/o1-labs/mina-rust/blob/develop/path/to/file.rs#LStartLine-LEndLine
31+
```
32+
````
33+
34+
### Example
35+
36+
Here's a real example from the zkApps documentation:
37+
38+
<!-- CODE_REFERENCE: ledger/src/scan_state/transaction_logic.rs#L3588-L3592 -->
39+
40+
```rust reference title="ledger/src/scan_state/transaction_logic.rs"
41+
https://github.com/o1-labs/mina-rust/blob/develop/ledger/src/scan_state/transaction_logic.rs#L3588-L3592
42+
```
43+
44+
### Components explained
45+
46+
1. **CODE_REFERENCE comment**: Acts as the source of truth for verification
47+
48+
```markdown
49+
<!-- CODE_REFERENCE: path/to/file.rs#LStartLine-LEndLine -->
50+
```
51+
52+
- Must match the GitHub URL line range exactly
53+
- Used by CI to verify references are valid
54+
- Path is relative to repository root
55+
56+
2. **Code block with reference**: Displays the actual code
57+
58+
```markdown
59+
(triple backticks)rust reference title="path/to/file.rs"
60+
https://github.com/o1-labs/mina-rust/blob/develop/path/to/file.rs#LStartLine-LEndLine
61+
(triple backticks)
62+
```
63+
64+
- Language: Use appropriate language identifier (`rust`, `toml`, `bash`,
65+
etc.)
66+
- `reference` keyword: Tells the plugin to fetch code from GitHub
67+
- `title`: Optional, shows the file path above the code block
68+
- URL: Full GitHub URL with line range (`#L10-L20`)
69+
70+
### Verification
71+
72+
A verification script runs in CI to ensure all code references are valid:
73+
74+
```bash
75+
bash .github/scripts/verify-code-references.sh
76+
```
77+
78+
The script checks:
79+
80+
- ✓ Referenced files exist
81+
- ✓ Line ranges are valid
82+
- ✓ GitHub URLs match CODE_REFERENCE comments
83+
- ✓ Code blocks have corresponding references
84+
- ✓ Local code matches what's deployed on GitHub
85+
86+
### When code changes
87+
88+
If code is added or removed and line numbers shift:
89+
90+
1. The verification script will detect the mismatch in CI
91+
2. Update the `CODE_REFERENCE` comment with new line numbers
92+
3. Update the GitHub URL with matching line numbers
93+
4. The plugin will automatically fetch the updated code
94+
95+
### Important: workflow for adding code references
96+
97+
<!-- prettier-ignore-start -->
98+
99+
:::caution
100+
101+
Code references must always point to code that exists on the `develop` branch.
102+
The verification script compares local code with GitHub's `develop` branch.
103+
104+
:::
105+
106+
<!-- prettier-ignore-end -->
107+
108+
**Recommended workflow:**
109+
110+
1. **First PR**: Implement and merge your code changes to `develop`
111+
2. **Second PR**: Add documentation with code references
112+
113+
This ensures:
114+
115+
- Code references are always valid in CI
116+
- Documentation doesn't break due to uncommitted changes
117+
- The plugin can fetch code from GitHub successfully
118+
119+
**Why separate PRs?**
120+
121+
- The verification script compares local code with GitHub's `develop` branch
122+
- If code isn't merged yet, the script will fail with a "code mismatch" error
123+
- This prevents documentation from referencing code that doesn't exist on
124+
`develop`

website/docusaurus.config.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@ const config: Config = {
6565
],
6666
],
6767

68+
themes: ['docusaurus-theme-github-codeblock'],
69+
6870

6971
themeConfig: {
7072
// Replace with your project's social card

website/package-lock.json

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

website/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
"@docusaurus/preset-classic": "^3.8.1",
2020
"@mdx-js/react": "^3.0.0",
2121
"clsx": "^2.0.0",
22+
"docusaurus-theme-github-codeblock": "^2.0.2",
2223
"prism-react-renderer": "^2.3.0",
2324
"react": "^19.0.0",
2425
"react-dom": "^19.0.0"

website/sidebars.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,13 @@ const sidebars: SidebarsConfig = {
133133
'developers/testing/ocaml-node-tests',
134134
],
135135
},
136+
{
137+
type: 'category',
138+
label: 'Documentation',
139+
items: [
140+
'developers/documentation-guidelines',
141+
],
142+
},
136143
{
137144
type: 'category',
138145
label: 'Future Work',

0 commit comments

Comments
 (0)