-
Notifications
You must be signed in to change notification settings - Fork 34
Add markdown docs templates #225
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
- Updated all README.adoc to README.mdx - Moved `templates-md` and the contents to just `templates` - Updated `hardhat.config.js` to use `docs/config` - Updated `helpers.js` to account for adoc change - Updated `docs/config.js` to use mdx
Updated the following legacy patterns: - `https://url[Link Text]` -> `[Link Text](https://url)` - `WARNING: | IMPORTANT: | CAUTION: | IMPORTANT:` -> `<Callout type=warn"></Callout>` - `NOTE: | TIP:` -> <Callout></Callout> - Delimitters such as `====` -> `####` or removed if no header text present
Co-authored-by: James Toussaint <33313130+james-toussaint@users.noreply.github.com>
Co-authored-by: James Toussaint <33313130+james-toussaint@users.noreply.github.com>
Co-authored-by: James Toussaint <33313130+james-toussaint@users.noreply.github.com>
Co-authored-by: James Toussaint <33313130+james-toussaint@users.noreply.github.com>
Co-authored-by: Ernesto García <ernestognw@gmail.com>
WalkthroughThis change migrates documentation infrastructure from AsciiDoc to MDX format, refactors documentation templates to support structured HTML card layouts with processed NatSpec content, updates Solidity contract doc comments with Markdown-style links, and introduces a new shell script-based build orchestration that synchronizes with an external OpenZeppelin docs repository. Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes
Possibly related PRs
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 10
🧹 Nitpick comments (6)
contracts/utils/cryptography/README.mdx (1)
12-12: Consider standardizing "onchain" vs "on-chain".The term "onchain" is flagged by the linter. While both "onchain" and "on-chain" are acceptable in blockchain contexts, consider standardizing on one form across the documentation for consistency.
scripts/prepare-docs.sh (1)
5-6: Remove unused ROOT variable.The
ROOTvariable is set but never used in the script. Since the script uses relative paths and doesn't reference$ROOT, this variable can be safely removed.🔎 Proposed fix
cd "$(dirname "$0")/.." -ROOT="$(pwd)" -docs/templates/properties.js (1)
20-34: Consider handling multiple trailing dashes.The current logic only removes a single trailing
-. Ifslug()produces consecutive dashes (e.g., fromtype[][]→type----), multiple trailing dashes could remain. However, looking at theslugimplementation which replaces\Wwith-, this seems unlikely in practice for type strings.🔎 Optional fix using regex to handle all trailing dashes
- if (res.charAt(res.length - 1) === '-') { - return res.slice(0, -1); - } - return res; + return res.replace(/-+$/, '');scripts/oz-docs.sh (2)
14-30: Consider adding error handling for network failures during clone/fetch.The
git cloneandgit fetchoperations could fail due to network issues. Whileset -ewill cause the script to exit, a more informative error message might help users troubleshoot.🔎 Optional: Add explicit error handling
init() { if [ -d "$OZ_DOCS/.git" ]; then echo "[oz-docs] updating cached docs repo..." cd "$OZ_DOCS" - git fetch origin main - git reset --hard origin/main + git fetch origin main || { echo "error: failed to fetch docs repo" >&2; exit 1; } + git reset --hard origin/main || { echo "error: failed to reset docs repo" >&2; exit 1; } git clean -fd else
65-78: Background watcher process is not cleaned up on script exit.The chokidar process is started in the background (
&) but there's no trap to kill it when the script exits (e.g., via Ctrl+C). This could leave orphaned processes.🔎 Add cleanup trap for background processes
+# Cleanup function for background processes +cleanup() { + jobs -p | xargs -r kill 2>/dev/null || true +} +trap cleanup EXIT INT TERM + if [ "${WATCH:-false}" = "true" ]; then if [ ! -x "$CHOKIDAR_BIN" ]; then echo "error: chokidar-cli not found (run: npm i -D chokidar-cli)" >&2 exit 1 fidocs/templates/helpers.js (1)
240-298: Complex regex chain is fragile and hard to maintain.The
processCalloutsfunction has ~15 regex replacements handling various admonition formats. This is prone to breaking when new formats are encountered and difficult to debug.Consider extracting patterns into a configuration array for easier maintenance:
const CALLOUT_PATTERNS = [ { pattern: /^\[(NOTE|TIP)\]\s*\n====\s*\n([\s\S]*?)\n====$/gm, type: '' }, { pattern: /^\[(IMPORTANT|WARNING|CAUTION)\]\s*\n====\s*\n([\s\S]*?)\n====$/gm, type: 'warn' }, // ... etc ];
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (48)
.github/workflows/docs.yml.gitignorecontracts/access/README.adoccontracts/access/README.mdxcontracts/account/README.adoccontracts/account/README.mdxcontracts/account/modules/ERC7579DelayedExecutor.solcontracts/account/paymaster/PaymasterCore.solcontracts/account/paymaster/PaymasterERC20.solcontracts/crosschain/README.mdxcontracts/governance/README.adoccontracts/governance/README.mdxcontracts/interfaces/README.mdxcontracts/proxy/README.adoccontracts/proxy/README.mdxcontracts/token/ERC20/extensions/ERC20Restricted.solcontracts/token/ERC20/extensions/ERC20uRWA.solcontracts/token/ERC20/extensions/ERC4626Fees.solcontracts/token/README.adoccontracts/token/README.mdxcontracts/utils/README.adoccontracts/utils/README.mdxcontracts/utils/cryptography/DKIMRegistry.solcontracts/utils/cryptography/README.adoccontracts/utils/cryptography/README.mdxcontracts/utils/cryptography/ZKEmailUtils.solcontracts/utils/cryptography/signers/SignerZKEmail.solcontracts/utils/structs/EnumerableMapExtended.solcontracts/utils/structs/EnumerableSetExtended.soldocs/antora.ymldocs/config.jsdocs/index.mddocs/modules/ROOT/nav.adocdocs/modules/ROOT/pages/account-modules.adocdocs/modules/ROOT/pages/crosschain.adocdocs/modules/ROOT/pages/index.adocdocs/modules/ROOT/pages/utilities.adocdocs/templates/contract.hbsdocs/templates/helpers.jsdocs/templates/page.hbsdocs/templates/properties.jsnetlify.tomlpackage.jsonscripts/gen-nav.jsscripts/generate/templates/EnumerableMapExtended.jsscripts/generate/templates/EnumerableSetExtended.jsscripts/oz-docs.shscripts/prepare-docs.sh
💤 Files with no reviewable changes (15)
- contracts/utils/README.adoc
- docs/modules/ROOT/pages/utilities.adoc
- docs/modules/ROOT/pages/index.adoc
- scripts/gen-nav.js
- docs/modules/ROOT/pages/crosschain.adoc
- contracts/proxy/README.adoc
- contracts/utils/cryptography/README.adoc
- docs/antora.yml
- docs/index.md
- contracts/access/README.adoc
- docs/modules/ROOT/nav.adoc
- contracts/governance/README.adoc
- contracts/token/README.adoc
- contracts/account/README.adoc
- docs/modules/ROOT/pages/account-modules.adoc
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-09-04T15:44:43.674Z
Learnt from: aviggiano
Repo: OpenZeppelin/openzeppelin-community-contracts PR: 214
File: contracts/governance/TimelockControllerEnumerable.sol:103-115
Timestamp: 2025-09-04T15:44:43.674Z
Learning: The base TimelockController contract intentionally preserves executed operations in the `_timestamps` mapping with `_DONE_TIMESTAMP` value to allow confirmation of executed status. This is by design, not a storage leak, and extensions like TimelockControllerEnumerable should follow the same pattern.
Applied to files:
contracts/governance/README.mdx
🧬 Code graph analysis (2)
docs/templates/properties.js (1)
docs/templates/helpers.js (1)
slug(64-69)
docs/templates/helpers.js (1)
docs/config.js (1)
fs(2-2)
🪛 LanguageTool
contracts/token/README.mdx
[grammar] ~9-~9: Ensure spelling is correct
Context: ...ens (e.g ERC-20, ERC-721, ERC-1155) and derivated ERCs (e.g. ERC-4626, ERC-1363). * {OnT...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
contracts/interfaces/README.mdx
[grammar] ~11-~11: Use a hyphen to join words.
Context: ... These are useful to interact with third party contracts that implement them. * ...
(QB_NEW_EN_HYPHEN)
contracts/utils/cryptography/README.mdx
[grammar] ~12-~12: Ensure spelling is correct
Context: ...s.ethereum.org/EIPS/eip-7969) to enable onchain verification of DomainKeys Identified M...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
🪛 Shellcheck (0.11.0)
scripts/prepare-docs.sh
[warning] 6-6: ROOT appears unused. Verify use (or export if used externally).
(SC2034)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
- GitHub Check: Redirect rules - community-contracts
- GitHub Check: Header rules - community-contracts
- GitHub Check: Pages changed - community-contracts
- GitHub Check: tests-foundry
- GitHub Check: coverage
- GitHub Check: slither
- GitHub Check: tests
🔇 Additional comments (36)
contracts/token/ERC20/extensions/ERC20Restricted.sol (1)
9-9: Documentation link format aligns with Markdown migration objectives.The EIP-7943 reference is properly formatted as a Markdown link and maintains accuracy. This change fits the PR's documentation infrastructure migration without affecting contract functionality or behavior.
contracts/account/paymaster/PaymasterERC20.sol (1)
175-175: Verify the Markdown heading level is intentional.The change converts AsciiDoc syntax
====(h2 heading) to Markdown syntax####(h4 heading), which is a two-level drop in the semantic heading hierarchy. Confirm this heading level aligns with your documentation structure, especially if other headings in the codebase follow a different pattern.contracts/token/ERC20/extensions/ERC20uRWA.sol (1)
12-12: Documentation link formatting aligned with PR objectives.The NatSpec comment was correctly updated to use Markdown-style inline link syntax, improving consistency with the documentation migration effort. The link syntax and target URL are both valid.
contracts/account/paymaster/PaymasterCore.sol (1)
129-129: Verify markdown syntax in NatSpec comments is supported by the docs pipeline.The markdown link syntax
[access control](url)in the NatSpec comment (line 129) departs from standard Solidity documentation conventions. While this aligns with the PR's migration to MDX, confirm that your documentation processing pipeline correctly handles and renders markdown syntax within NatSpec comments. Standard Solidity documentation viewers may not interpret markdown correctly without special preprocessing.To verify this is handled correctly, you can:
- Check the documentation build pipeline configuration for markdown/MDX processing
- Verify the URL is accessible:
https://docs.openzeppelin.com/contracts/5.x/access-control- Ensure similar changes across the PR follow the same pattern for consistency
contracts/access/README.mdx (1)
11-11: Clarify the{AccessManagerLight}reference syntax.The syntax
{AccessManagerLight}is non-standard for Markdown/MDX. Confirm whether this is intentional custom processor syntax or if it should use standard MDX component or markdown link syntax (e.g.,<AccessManagerLight />or[AccessManagerLight](path)).contracts/token/ERC20/extensions/ERC4626Fees.sol (1)
10-10: LGTM! Improved documentation formatting.The conversion from inline URL to Markdown link format improves readability and follows documentation best practices.
.gitignore (1)
40-40: LGTM! Appropriate addition of generated docs to .gitignore.Adding
docs/oz-docsto the ignore list is correct since this directory contains generated documentation artifacts that should not be committed to version control.scripts/generate/templates/EnumerableSetExtended.js (1)
13-13: LGTM! Consistent Markdown link formatting.The documentation comments have been properly updated to use Markdown-style links, which will render correctly in the new MDX-based documentation system.
Also applies to: 40-40
contracts/utils/cryptography/DKIMRegistry.sol (1)
7-7: LGTM! Improved documentation formatting.The ERC-7969 reference has been properly formatted as a Markdown link, consistent with the documentation migration across the repository.
contracts/utils/cryptography/ZKEmailUtils.sol (1)
13-13: LGTM! Consistent Markdown link formatting for external documentation.All ZKEmail documentation references have been properly converted to Markdown link format, improving readability and consistency with the new documentation system.
Also applies to: 21-21, 23-23, 25-25
scripts/generate/templates/EnumerableMapExtended.js (1)
12-12: LGTM! Consistent Markdown link formatting.The documentation comments have been updated with proper Markdown-style links, consistent with the changes in EnumerableSetExtended.js and the broader documentation migration.
Also applies to: 41-41
contracts/utils/structs/EnumerableSetExtended.sol (1)
12-12: LGTM! Documentation link formatting improved.The conversion from inline URL references to proper Markdown link syntax improves readability and follows documentation best practices.
Also applies to: 39-39
contracts/crosschain/README.mdx (1)
1-25: Documentation structure looks good.The MDX file follows a clear structure with proper front matter, callout, and content sections. The crosschain concepts are well-documented.
contracts/utils/cryptography/signers/SignerZKEmail.sol (1)
12-12: LGTM! Documentation link formatting improved.The conversion to proper Markdown link syntax enhances documentation readability and consistency across the codebase.
Also applies to: 61-61, 79-79, 87-87
contracts/proxy/README.mdx (1)
1-15: LGTM! Clear proxy documentation.The MDX file provides clear documentation about proxy patterns and the HybridProxy implementation. The structure is consistent with other documentation files in this PR.
contracts/governance/README.mdx (1)
1-15: LGTM! Governance documentation is clear.The MDX file properly documents the governance extensions, particularly the TimelockControllerEnumerable. The structure is consistent with other documentation files in this PR.
contracts/account/modules/ERC7579DelayedExecutor.sol (1)
12-12: LGTM! Section headers migrated to Markdown format.The conversion from AsciiDoc-style section markers to Markdown headers aligns with the broader documentation migration to MDX format.
Also applies to: 27-27, 35-35
contracts/utils/structs/EnumerableMapExtended.sol (1)
11-11: LGTM! Documentation link formatting improved.The conversion to proper Markdown link syntax for both the Solidity documentation reference and the GitHub issue improves consistency and readability.
Also applies to: 40-40
docs/templates/contract.hbs (1)
1-158: LGTM: Well-structured card-based layout.The template successfully introduces a modern card-based documentation layout with proper anchoring, GitHub links, and processed NatSpec content. The use of React/JSX syntax (className, style attributes) aligns well with MDX output format.
contracts/utils/README.mdx (1)
1-22: LGTM: Clean and consistent MDX documentation.The utilities README follows the same structure and conventions as the other MDX documentation files in this PR.
docs/templates/page.hbs (1)
1-13: LGTM: Clean template structure with proper front matter.The page template correctly introduces YAML front matter for MDX compatibility and delegates item rendering to the contract partial. The structure is simple and maintainable.
.github/workflows/docs.yml (2)
12-18: Verify the DOCS_REPO_TOKEN secret exists.The workflow now relies on the
DOCS_REPO_TOKENsecret to trigger the external workflow. Ensure this secret is configured in the repository settings with appropriate permissions to trigger workflows in theOpenZeppelin/docsrepository.
1-18: LGTM: Workflow simplification improves maintainability.The change from a multi-step in-repo docs generation to delegating to an external workflow in the OpenZeppelin/docs repository is a good architectural decision. This centralizes docs generation logic and reduces duplication. The addition of
workflow_dispatchfor manual triggers is also helpful for testing.scripts/prepare-docs.sh (1)
17-33: LGTM: Clean refactoring into prepare() function.Wrapping the preparation logic in a
prepare()function improves code organization and makes the script easier to understand and maintain. The function encapsulates all the doc preparation steps logically.package.json (2)
14-18: LGTM!The script reorganization cleanly delegates to
oz-docs.shfor both regular builds and watch mode. TheWATCH=trueenvironment variable pattern is a clean approach for mode switching.
51-51: The version specification"chokidar-cli": "^3.0.0"is appropriate. The latest available version is 3.0.0 on the npm registry, and no critical issues have been reported. The semver range correctly pins to the latest major.minor version while allowing patch updates.docs/templates/properties.js (3)
36-45: LGTM!Returning an empty array for non-contracts (interfaces, libraries) is appropriate defensive behavior that prevents downstream errors when consumers iterate over inheritance.
47-57: LGTM!The
inheritance &&guards properly handle cases whereinheritanceis undefined or empty, preventing runtime errors when these helpers are called on non-contract items.
74-82: LGTM!Early return for missing inheritance prevents errors and aligns with the defensive pattern used in the
has-*functions.scripts/oz-docs.sh (2)
1-11: LGTM!Good use of
set -euo pipefailfor strict error handling. The path setup and variable definitions are clear and well-organized.
39-45: LGTM!The sync function properly creates directories before rsync and uses
--deleteto ensure the destination mirrors the source exactly.docs/templates/helpers.js (5)
153-158: Regex may match unintended standalone words.The pattern
^([A-Z][a-zA-Z0-9]+)$matches any PascalCase word on its own line, not just contract names. This could unintentionally convert words like "Overview" or "Introduction" to links if they happen to match a contract name.Consider whether this is the intended behavior. If contract names should be explicit, this pattern might be too broad.
71-108: LGTM!The WeakMap caching with per-page Map keys is a good pattern for memoizing link generation without memory leaks. The cache properly invalidates when
itemsreference changes.
198-213: LGTM!The HTML entity decoding and URL format normalization are correctly implemented. The regex for converting AsciiDoc-style links (
url[text]) to Markdown ([text](url)) is appropriate.
300-317: LGTM!The
titleanddescriptionhelpers properly derive display text from page IDs with appropriate formatting.
28-44:simple-idhelper is not used anywhere in the codebase.The
functionNameCountsglobal state andreset-function-countsexist but are unused. Theanchorproperty is generated dynamically inproperties.js, not via thesimple-idhelper. Whilereset-function-countsis called at line 1 ofcontract.hbs, it has no practical effect. Consider removing these unused helpers to reduce code complexity.Likely an incorrect or invalid review comment.
| ## AccessManager | ||
|
|
||
| AccessManagerLight |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix incomplete section structure.
The "## AccessManager" section header is followed immediately by "AccessManagerLight" with no content. Either:
- Add content under the AccessManager section, or
- Rename to "## AccessManagerLight" with appropriate content, or
- Restructure with proper subsections
The file appears to be incomplete or malformed.
🤖 Prompt for AI Agents
In contracts/access/README.mdx around lines 13 to 15, the "## AccessManager"
header is followed directly by the bare text "AccessManagerLight", leaving the
section incomplete or malformed; either add explanatory content and examples
under "## AccessManager" about its purpose and relationship to
AccessManagerLight, or rename the header to "## AccessManagerLight" and provide
appropriate content (description, usage, API/props or links), or split into
proper subsections (e.g., "## AccessManager" with "### AccessManagerLight") so
the README is well structured and each header has matching content.
|
|
||
| This directory includes contracts to build accounts for ERC-4337. These include: | ||
|
|
||
| * {ERC7579Executor}: An executor module that enables executing calls from accounts where the it’s installed. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix grammatical error: remove extra "the".
The phrase "where the it's installed" contains an extra "the" before "it's".
🔎 Proposed fix
-* {ERC7579Executor}: An executor module that enables executing calls from accounts where the it's installed.
+* {ERC7579Executor}: An executor module that enables executing calls from accounts where it's installed.📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| * {ERC7579Executor}: An executor module that enables executing calls from accounts where the it’s installed. | |
| * {ERC7579Executor}: An executor module that enables executing calls from accounts where it's installed. |
🤖 Prompt for AI Agents
In contracts/account/README.mdx around line 11, the phrase "where the it’s
installed" contains an extra "the"; remove the extra word so the sentence reads
"where it's installed" (i.e., replace "where the it’s installed" with "where
it’s installed").
|
|
||
| ## List of standardized interfaces | ||
|
|
||
| These interfaces are available as `.sol` files. These are useful to interact with third party contracts that implement them. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider hyphenating "third-party" when used as an adjective.
The phrase "third party contracts" should be "third-party contracts" for grammatically correct usage when the term modifies a noun.
🔎 Suggested fix
-These are useful to interact with third party contracts that implement them.
+These are useful to interact with third-party contracts that implement them.📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| These interfaces are available as `.sol` files. These are useful to interact with third party contracts that implement them. | |
| These interfaces are available as `.sol` files. These are useful to interact with third-party contracts that implement them. |
🧰 Tools
🪛 LanguageTool
[grammar] ~11-~11: Use a hyphen to join words.
Context: ... These are useful to interact with third party contracts that implement them. * ...
(QB_NEW_EN_HYPHEN)
🤖 Prompt for AI Agents
In contracts/interfaces/README.mdx at line 11, change the phrase "third party
contracts" to the hyphenated form "third-party contracts" so the compound
adjective correctly modifies "contracts"; update the line accordingly.
| This document is better viewed at https://docs.openzeppelin.com/community-contracts/token | ||
| </Callout> | ||
|
|
||
| Set of extensions and utilities for tokens (e.g ERC-20, ERC-721, ERC-1155) and derivated ERCs (e.g. ERC-4626, ERC-1363). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix spelling error: "derivated" should be "derived".
The word "derivated" is not standard English. Use "derived" instead.
🔎 Proposed fix
-Set of extensions and utilities for tokens (e.g ERC-20, ERC-721, ERC-1155) and derivated ERCs (e.g. ERC-4626, ERC-1363).
+Set of extensions and utilities for tokens (e.g ERC-20, ERC-721, ERC-1155) and derived ERCs (e.g. ERC-4626, ERC-1363).📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| Set of extensions and utilities for tokens (e.g ERC-20, ERC-721, ERC-1155) and derivated ERCs (e.g. ERC-4626, ERC-1363). | |
| Set of extensions and utilities for tokens (e.g ERC-20, ERC-721, ERC-1155) and derived ERCs (e.g. ERC-4626, ERC-1363). |
🧰 Tools
🪛 LanguageTool
[grammar] ~9-~9: Ensure spelling is correct
Context: ...ens (e.g ERC-20, ERC-721, ERC-1155) and derivated ERCs (e.g. ERC-4626, ERC-1363). * {OnT...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
🤖 Prompt for AI Agents
In contracts/token/README.mdx around line 9, change the misspelled word
"derivated" to the correct word "derived" so the sentence reads "...and derived
ERCs (e.g. ERC-4626, ERC-1363)." Update the file accordingly and run a quick
spell-check to ensure no other instances of the same typo remain.
| templates: 'docs/templates', | ||
| exclude: ['mocks'], | ||
| pageExtension: '.adoc', | ||
| pageExtension: '.mdx', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Examine the docs/config.js file and repository structure
echo "=== Checking docs/config.js file ==="
if [ -f "docs/config.js" ]; then
cat -n docs/config.js
else
echo "docs/config.js not found - searching for config files in docs/"
fd -e js . docs/ | head -20
fi
echo -e "\n=== Repository structure overview ==="
ls -la | head -20
echo -e "\n=== Checking for .adoc files in entire repository ==="
fd -e adoc . | head -30
echo -e "\n=== Checking for .mdx files in entire repository ==="
fd -e mdx . | head -30
echo -e "\n=== Checking for .adoc references in JS files ==="
rg "\.adoc" --type=js -g '!node_modules' -g '!package-lock.json' | head -20Repository: OpenZeppelin/openzeppelin-community-contracts
Length of output: 2751
Configuration is correct but remove stale AsciiDoc files to complete the migration. The pageExtension: '.mdx' setting is properly configured for solidity-docgen. However, three .adoc files remain and should be deleted:
contracts/crosschain/README.adoccontracts/interfaces/README.adocdocs/modules/ROOT/pages/paymasters.adoc
These are duplicates of successfully migrated .mdx files (except paymasters.adoc which has no .mdx equivalent). Clean up these remnants to complete the MDX migration across the repository.
🤖 Prompt for AI Agents
In docs/config.js at line 9, the pageExtension is correctly set to '.mdx' but
there are stale AsciiDoc files left; delete the three files
contracts/crosschain/README.adoc, contracts/interfaces/README.adoc, and
docs/modules/ROOT/pages/paymasters.adoc from the repository, and update or
remove any references/links to them (or replace with the corresponding .mdx
where applicable) so the MDX migration is complete.
| [.hljs-theme-light.nopadding] | ||
| ```solidity | ||
| import "@openzeppelin/community-{{__item_context.file.absolutePath}}"; | ||
| import "@openzeppelin/{{__item_context.file.absolutePath}}"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Check the contract.hbs template file
if [ -f "docs/templates/contract.hbs" ]; then
echo "=== Contract template content ==="
cat -n docs/templates/contract.hbs | head -30
fi
# Search for other template files
echo -e "\n=== Looking for other templates ==="
find docs/templates -name "*.hbs" -type f 2>/dev/null | head -10
# Check package.json name
echo -e "\n=== Package name ==="
if [ -f "package.json" ]; then
cat package.json | grep -A 1 '"name"'
fiRepository: OpenZeppelin/openzeppelin-community-contracts
Length of output: 1748
Add missing package name to import statement.
The import path is missing the "community-contracts" package name. It should be @openzeppelin/community-contracts/{{__item_context.file.absolutePath}} to match the actual package name and reflect the correct import users should use.
🤖 Prompt for AI Agents
In docs/templates/contract.hbs around line 14, the import path is missing the
package name; update the import to include the "community-contracts" package
segment so it reads the full package path
(@openzeppelin/community-contracts/{{__item_context.file.absolutePath}})
ensuring generated imports reference the correct package.
| function generateLinkPath(pagePath, currentPagePath, anchor) { | ||
| if ( | ||
| currentPagePath && | ||
| (pagePath === currentPagePath || pagePath.split('/').pop() === currentPagePath.split('/').pop()) | ||
| ) { | ||
| return `#${anchor}`; | ||
| } | ||
|
|
||
| if (currentPagePath) { | ||
| const currentParts = currentPagePath.split('/'); | ||
| const targetParts = pagePath.split('/'); | ||
|
|
||
| // Find common base | ||
| let i = 0; | ||
| while (i < currentParts.length && i < targetParts.length && currentParts[i] === targetParts[i]) { | ||
| i++; | ||
| } | ||
|
|
||
| const upLevels = Math.max(0, currentParts.length - 1 - i); | ||
| const downPath = targetParts.slice(i); | ||
|
|
||
| if (upLevels === 0 && downPath.length === 1) { | ||
| return `${PATH_PREFIX}${downPath[0]}#${anchor}`; | ||
| } else if (upLevels === 0) { | ||
| return `${PATH_PREFIX}${downPath.join('/')}#${anchor}`; | ||
| } else { | ||
| const relativePath = downPath.join('/'); | ||
| return `${PATH_PREFIX}${relativePath}#${anchor}`; | ||
| } | ||
| } | ||
|
|
||
| return `${PATH_PREFIX}${pagePath}#${anchor}`; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Path comparison may produce incorrect results for similar path endings.
Line 113 compares only the last path segment (split('/').pop()), which could incorrectly match utils/token and extensions/token as the same page, generating anchor-only links when full paths are needed.
🔎 Suggested fix: require exact path match
if (
currentPagePath &&
- (pagePath === currentPagePath || pagePath.split('/').pop() === currentPagePath.split('/').pop())
+ pagePath === currentPagePath
) {
return `#${anchor}`;
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| function generateLinkPath(pagePath, currentPagePath, anchor) { | |
| if ( | |
| currentPagePath && | |
| (pagePath === currentPagePath || pagePath.split('/').pop() === currentPagePath.split('/').pop()) | |
| ) { | |
| return `#${anchor}`; | |
| } | |
| if (currentPagePath) { | |
| const currentParts = currentPagePath.split('/'); | |
| const targetParts = pagePath.split('/'); | |
| // Find common base | |
| let i = 0; | |
| while (i < currentParts.length && i < targetParts.length && currentParts[i] === targetParts[i]) { | |
| i++; | |
| } | |
| const upLevels = Math.max(0, currentParts.length - 1 - i); | |
| const downPath = targetParts.slice(i); | |
| if (upLevels === 0 && downPath.length === 1) { | |
| return `${PATH_PREFIX}${downPath[0]}#${anchor}`; | |
| } else if (upLevels === 0) { | |
| return `${PATH_PREFIX}${downPath.join('/')}#${anchor}`; | |
| } else { | |
| const relativePath = downPath.join('/'); | |
| return `${PATH_PREFIX}${relativePath}#${anchor}`; | |
| } | |
| } | |
| return `${PATH_PREFIX}${pagePath}#${anchor}`; | |
| } | |
| function generateLinkPath(pagePath, currentPagePath, anchor) { | |
| if ( | |
| currentPagePath && | |
| pagePath === currentPagePath | |
| ) { | |
| return `#${anchor}`; | |
| } | |
| if (currentPagePath) { | |
| const currentParts = currentPagePath.split('/'); | |
| const targetParts = pagePath.split('/'); | |
| // Find common base | |
| let i = 0; | |
| while (i < currentParts.length && i < targetParts.length && currentParts[i] === targetParts[i]) { | |
| i++; | |
| } | |
| const upLevels = Math.max(0, currentParts.length - 1 - i); | |
| const downPath = targetParts.slice(i); | |
| if (upLevels === 0 && downPath.length === 1) { | |
| return `${PATH_PREFIX}${downPath[0]}#${anchor}`; | |
| } else if (upLevels === 0) { | |
| return `${PATH_PREFIX}${downPath.join('/')}#${anchor}`; | |
| } else { | |
| const relativePath = downPath.join('/'); | |
| return `${PATH_PREFIX}${relativePath}#${anchor}`; | |
| } | |
| } | |
| return `${PATH_PREFIX}${pagePath}#${anchor}`; | |
| } |
🤖 Prompt for AI Agents
In docs/templates/helpers.js around lines 110 to 142, the current comparison
treats pages with the same final segment as identical
(pagePath.split('/').pop()), which incorrectly collapses distinct paths like
utils/token and extensions/token into anchor-only links; update the logic to
require an exact path match (normalize and compare full paths, e.g., strip
trailing slashes or index filenames if your routing uses them) and remove the
last-segment equality check so only true identical page paths return `#anchor`,
otherwise build a full path as before.
| // Ensure relative image paths start with / | ||
| .replace(/!\[([^\]]*)\]\(([^/)][^)]*\.(png|jpg|jpeg|gif|svg|webp))\)/g, '') | ||
| // Remove any title headers (they're in frontmatter now) | ||
| .replace(/^#+\s+.+$/m, '') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Regex removes all top-level headers, not just title headers.
Line 229 (/^#+\s+.+$/m) removes the first header it finds, but the comment says "title headers." If a README has a title header already removed by frontmatter, this could remove meaningful content headers.
🔎 Suggested fix: only remove h1 headers
- // Remove any title headers (they're in frontmatter now)
- .replace(/^#+\s+.+$/m, '')
+ // Remove any h1 title headers (they're in frontmatter now)
+ .replace(/^#\s+.+$/m, '')📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| // Ensure relative image paths start with / | |
| .replace(/!\[([^\]]*)\]\(([^/)][^)]*\.(png|jpg|jpeg|gif|svg|webp))\)/g, '') | |
| // Remove any title headers (they're in frontmatter now) | |
| .replace(/^#+\s+.+$/m, '') | |
| // Ensure relative image paths start with / | |
| .replace(/!\[([^\]]*)\]\(([^/)][^)]*\.(png|jpg|jpeg|gif|svg|webp))\)/g, '') | |
| // Remove any h1 title headers (they're in frontmatter now) | |
| .replace(/^#\s+.+$/m, '') |
🤖 Prompt for AI Agents
In docs/templates/helpers.js around lines 226 to 229, the current regex
.replace(/^#+\s+.+$/m, '') removes any header level (h1-h6) whereas we only want
to strip title headers; change the pattern to target only h1 headers (e.g. use a
regex matching lines that start with exactly one '#' followed by space) so only
top-level title headers are removed, keeping other meaningful section headers
intact.
| [build] | ||
| command = "npm run docs" | ||
| publish = "build/site" | ||
| command = "pnpm run docs" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Check for the docs script in package.json and pnpm configuration
# Check if docs script exists
echo "=== Checking for 'docs' script in package.json ==="
jq -r '.scripts.docs // "NOT FOUND"' package.json 2>/dev/null || echo "package.json not found or not valid JSON"
# Check for pnpm-specific configuration
echo -e "\n=== Checking for pnpm configuration ==="
if [ -f "pnpm-lock.yaml" ]; then
echo "pnpm-lock.yaml exists"
else
echo "pnpm-lock.yaml NOT FOUND"
fi
if [ -f ".npmrc" ]; then
echo ".npmrc exists with contents:"
cat .npmrc
else
echo ".npmrc NOT FOUND"
fi
# Check if netlify.toml specifies Node version or build image
echo -e "\n=== Checking netlify.toml for build settings ==="
cat netlify.tomlRepository: OpenZeppelin/openzeppelin-community-contracts
Length of output: 351
Add pnpm-lock.yaml or configure pnpm in package.json to enable Netlify pnpm support.
Netlify supports pnpm for Node.js 16.9.0 and later and automatically runs pnpm install when a pnpm-lock.yaml file is present. Your repository uses pnpm run docs in netlify.toml but lacks a pnpm-lock.yaml file. Without it, Netlify will default to npm for dependency installation, causing the build command to fail with "pnpm: command not found."
To fix this, either:
- Commit the pnpm-lock.yaml file to the repository, or
- Add
"packageManager": "pnpm@VERSION"to package.json to signal pnpm usage via Corepack
🤖 Prompt for AI Agents
In netlify.toml around line 2, the build command uses "pnpm run docs" but the
repo lacks pnpm configuration so Netlify will default to npm and fail; fix by
either committing your generated pnpm-lock.yaml into the repository so Netlify
detects and uses pnpm, or add a "packageManager": "pnpm@<version>" entry to
package.json (use the pnpm version you develop with) to enable pnpm via
Corepack; choose one of these fixes and ensure the lockfile or package.json
change is committed before redeploy.
| command = "npm run docs" | ||
| publish = "build/site" | ||
| command = "pnpm run docs" | ||
| publish = "docs/oz-docs/out" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Verify that the build process creates the expected output directory
# Check if there's a script that generates docs/oz-docs/out
echo "=== Checking package.json scripts for oz-docs ==="
jq -r '.scripts | to_entries[] | select(.key | contains("oz") or contains("docs")) | "\(.key): \(.value)"' package.json 2>/dev/null || echo "No package.json or jq unavailable"
# Check if there are any scripts in the scripts directory related to oz-docs
echo -e "\n=== Checking for oz-docs related scripts ==="
fd -t f "oz-docs" scripts/ 2>/dev/null || echo "No oz-docs scripts found"
# Check if docs/oz-docs directory exists
echo -e "\n=== Checking for docs/oz-docs directory ==="
if [ -d "docs/oz-docs" ]; then
echo "docs/oz-docs directory exists"
ls -la docs/oz-docs/ 2>/dev/null | head -20
else
echo "docs/oz-docs directory does not exist"
fi
# Look for antora.yml or antora-playbook files
echo -e "\n=== Looking for Antora configuration files ==="
find . -maxdepth 3 -name "*antora*.yml" -o -name "*antora*.yaml" 2>/dev/null | head -20
# Check package.json for docs-related dependencies
echo -e "\n=== Checking for docs dependencies in package.json ==="
jq -r '.devDependencies | keys[] | select(contains("antora") or contains("docs"))' package.json 2>/dev/null || echo "No relevant dependencies found"Repository: OpenZeppelin/openzeppelin-community-contracts
Length of output: 514
🏁 Script executed:
#!/bin/bash
cat scripts/oz-docs.shRepository: OpenZeppelin/openzeppelin-community-contracts
Length of output: 1965
🏁 Script executed:
#!/bin/bash
# Check the OpenZeppelin docs repository configuration for output directory
# Since oz-docs clones the docs repo, check what build output it would generate
echo "=== Checking if docs/oz-docs exists and what's inside ==="
if [ -d "docs/oz-docs" ]; then
echo "docs/oz-docs directory exists"
ls -la docs/oz-docs/ 2>/dev/null | grep -E "^\." | head -5
# Check for antora config
find docs/oz-docs -maxdepth 2 -name "*antora*" -o -name "package.json" 2>/dev/null | head
else
echo "docs/oz-docs does not exist (expected - it's cloned during build)"
fi
echo -e "\n=== Checking netlify.toml for current configuration ==="
cat netlify.toml 2>/dev/null || echo "netlify.toml not found"Repository: OpenZeppelin/openzeppelin-community-contracts
Length of output: 332
Correct the publish directory path to match the actual build output.
The build process generates output at docs/oz-docs/build/site (following Antora's default output directory), not docs/oz-docs/out. Update netlify.toml to use publish = "docs/oz-docs/build/site" or verify that the OpenZeppelin/docs repository has a custom antora configuration that outputs to an out directory. Without this correction, Netlify will fail to find the publish directory during deployment.
🤖 Prompt for AI Agents
In netlify.toml around line 3, the publish path is incorrect—Netlify is pointed
to docs/oz-docs/out but the site is actually built to docs/oz-docs/build/site;
update the publish setting to publish = "docs/oz-docs/build/site" (or, if the
repo intentionally outputs to out, adjust the Antora/build config to emit into
docs/oz-docs/out) so Netlify can find the build output during deployment.
Summary by CodeRabbit
Release Notes
New Features
Documentation
Chores
✏️ Tip: You can customize this high-level summary in your review settings.