Skip to content

Commit 0429dcb

Browse files
committed
feat: upgrade build processing and linting
• Standardize linting configs across all packages (.solhint.json, .markdownlint.json) • Remove deprecated natspec-smells and storage verification scripts • Add new utility scripts (check-todos.sh, lint-staged-run.sh, verify-solhint-disables.js) • Update CI workflows and pnpm workspace configuration
1 parent 2f3fdb8 commit 0429dcb

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+4222
-4159
lines changed

.github/workflows/build-test.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,10 @@ jobs:
2626
run: pnpm -r --sequential run build
2727

2828
- name: Test all packages
29-
run: pnpm -r --sequential run test
29+
run: pnpm -r --sequential run test:self
3030

3131
- name: Test with coverage
32-
run: pnpm -r --sequential run test:coverage
32+
run: pnpm -r --sequential run test:coverage:self
3333

3434
- name: Find coverage files
3535
id: coverage_files
@@ -47,4 +47,4 @@ jobs:
4747
files: ${{ steps.coverage_files.outputs.files }}
4848
flags: unittests
4949
name: graphprotocol-contracts
50-
fail_ci_if_error: true
50+
fail_ci_if_error: false

.github/workflows/lint.yml

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -167,15 +167,6 @@ jobs:
167167
echo "sol_prettier_exit_code=0" >> $GITHUB_OUTPUT
168168
fi
169169
170-
- name: Lint Solidity files (Natspec Documentation)
171-
id: lint_sol_natspec
172-
continue-on-error: true
173-
run: |
174-
echo "Checking Solidity documentation with natspec-smells..."
175-
# Run natspec-smells from root to check all configured packages
176-
npx natspec-smells
177-
echo "sol_natspec_exit_code=$?" >> $GITHUB_OUTPUT
178-
179170
- name: Lint Markdown files (Markdownlint)
180171
id: lint_md_markdownlint
181172
continue-on-error: true
@@ -320,15 +311,6 @@ jobs:
320311
WARNINGS=$((WARNINGS+1))
321312
fi
322313
323-
# Solidity - Natspec Documentation
324-
if [ "$SOL_NATSPEC_EXIT_CODE" = "1" ]; then
325-
echo "::error::natspec-smells found documentation issues in Solidity files"
326-
ERRORS=$((ERRORS+1))
327-
elif [ "$SOL_NATSPEC_EXIT_CODE" != "0" ]; then
328-
echo "::warning::natspec-smells found warnings in Solidity files"
329-
WARNINGS=$((WARNINGS+1))
330-
fi
331-
332314
# Markdown - Markdownlint
333315
if [ "$MD_MARKDOWNLINT_EXIT_CODE" = "1" ]; then
334316
echo "::error::Markdownlint found errors in Markdown files"

.gitignore

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,7 @@ core.*
99

1010
# Dependency directories
1111
node_modules/
12-
forge-std/
13-
**/lib/forge-std/
12+
.pnpm-store/
1413

1514
# Yarn
1615
.yarn/*
@@ -41,6 +40,8 @@ types-v5/
4140
wagmi/
4241
types/
4342
deployments/hardhat/
43+
*.js.map
44+
*.d.ts.map
4445

4546
# TypeScript incremental compilation cache
4647
**/tsconfig.tsbuildinfo
@@ -69,7 +70,6 @@ arbitrum-addresses-local.json
6970
addresses-fork.json
7071
addresses-hardhat.json
7172
addresses-local*.json
72-
addresses-local-network.json
7373

7474
# Keys
7575
.keystore
@@ -78,7 +78,6 @@ addresses-local-network.json
7878
cache_forge
7979
forge-artifacts/
8080
out/
81-
packages/issuance/lib/forge-std/
8281

8382
# Graph client
8483
.graphclient

.markdownlint.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
{
22
"default": true,
3+
"MD004": { "style": "dash" },
4+
"MD007": { "indent": 2 },
35
"MD013": false,
46
"MD024": { "siblings_only": true },
5-
"MD033": false,
67
"MD029": { "style": "ordered" },
7-
"MD007": { "indent": 2 },
8-
"MD004": { "style": "dash" }
8+
"MD033": false
99
}

.markdownlintignore

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
# Autogenerated GraphClient files (committed but should not be linted)
2+
**/.graphclient-extracted/
3+
**/.graphclient/
4+
15
# Dependencies
26
node_modules/
37

@@ -30,10 +34,7 @@ lcov.info
3034
packages/*/.eslintcache
3135
deployments/hardhat/
3236
.graphclient
33-
**/chain-31337/
34-
**/chain-1377/
35-
**/horizon-localhost/
36-
**/horizon-hardhat/
37-
**/subgraph-service-localhost/
38-
**/subgraph-service-hardhat/
39-
.changeset/
37+
**/chain-*/
38+
**/*-localhost/
39+
**/*-hardhat/
40+
.changeset/

.prettierignore

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ node_modules/
88

99
# Third-party libraries in lib directories
1010
**/lib/
11-
forge-std/
1211

1312
# Build outputs (from .gitignore)
1413
**/build/
@@ -36,9 +35,7 @@ lcov.info
3635
packages/*/.eslintcache
3736
deployments/hardhat/
3837
.graphclient
39-
**/chain-31337/
40-
**/chain-1377/
41-
**/horizon-localhost/
42-
**/horizon-hardhat/
43-
**/subgraph-service-localhost/
44-
**/subgraph-service-hardhat/
38+
**/.graphclient-extracted/
39+
**/chain-*/
40+
**/*-localhost/
41+
**/*-hardhat/

README.md

Lines changed: 200 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,11 @@ This repository is a pnpm workspaces monorepo containing the following packages:
3636
| Package | Latest version | Description |
3737
| ----------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------- |
3838
| [contracts](./packages/contracts) | [![npm version](https://badge.fury.io/js/@graphprotocol%2Fcontracts.svg)](https://badge.fury.io/js/@graphprotocol%2Fcontracts) | Contracts enabling the open and permissionless decentralized network known as The Graph protocol. |
39-
| [data-edge](./packages/data-edge) | - | Data edge testing and utilities for The Graph protocol. |
39+
| [data-edge](./packages/data-edge) | [![npm version](https://badge.fury.io/js/@graphprotocol%2Fdata-edge.svg)](https://badge.fury.io/js/@graphprotocol%2Fdata-edge) | Data edge testing and utilities for The Graph protocol. |
4040
| [hardhat-graph-protocol](./packages/hardhat-graph-protocol) | [![npm version](https://badge.fury.io/js/hardhat-graph-protocol.svg)](https://badge.fury.io/js/hardhat-graph-protocol) | A Hardhat plugin that extends the runtime environment with functionality for The Graph protocol. |
4141
| [horizon](./packages/horizon) | [![npm version](https://badge.fury.io/js/@graphprotocol%2Fhorizon.svg)](https://badge.fury.io/js/@graphprotocol%2Fhorizon) | Contracts for Graph Horizon, the next iteration of The Graph protocol. |
4242
| [interfaces](./packages/interfaces) | [![npm version](https://badge.fury.io/js/@graphprotocol%2Finterfaces.svg)](https://badge.fury.io/js/@graphprotocol%2Finterfaces) | Contract interfaces for The Graph protocol contracts. |
43+
| [issuance](./packages/issuance) | [![npm version](https://badge.fury.io/js/@graphprotocol%2Fissuance.svg)](https://badge.fury.io/js/@graphprotocol%2Fissuance) | Smart contracts for The Graph's token issuance functionality |
4344
| [subgraph-service](./packages/subgraph-service) | [![npm version](https://badge.fury.io/js/@graphprotocol%2Fsubgraph-service.svg)](https://badge.fury.io/js/@graphprotocol%2Fsubgraph-service) | Contracts for the Subgraph data service in Graph Horizon. |
4445
| [token-distribution](./packages/token-distribution) | [![npm version](https://badge.fury.io/js/@graphprotocol%2Ftoken-distribution.svg)](https://badge.fury.io/js/@graphprotocol%2Ftoken-distribution) | Contracts managing token locks for network participants. |
4546
| [toolshed](./packages/toolshed) | [![npm version](https://badge.fury.io/js/@graphprotocol%2Ftoolshed.svg)](https://badge.fury.io/js/@graphprotocol%2Ftoolshed) | A collection of tools and utilities for the Graph Protocol TypeScript components. |
@@ -67,6 +68,52 @@ $ pnpm install
6768

6869
# Build projects
6970
$ pnpm build
71+
72+
# Run tests
73+
$ pnpm test
74+
```
75+
76+
### Script Patterns
77+
78+
This monorepo follows consistent script patterns across all packages to ensure reliable builds and tests:
79+
80+
#### Build Scripts
81+
82+
- **`pnpm build`** (root) - Builds all packages by calling `build:self` on each
83+
- **`pnpm build`** (package) - Builds dependencies first, then the package itself
84+
- **`pnpm build:self`** - Builds only the current package (no dependencies)
85+
- **`pnpm build:dep`** - Builds workspace dependencies needed by the current package
86+
87+
#### Test Scripts
88+
89+
- **`pnpm test`** (root) - Builds everything once, then runs `test:self` on all packages
90+
- **`pnpm test`** (package) - Builds dependencies first, then runs tests
91+
- **`pnpm test:self`** - Runs only the package's tests (no building)
92+
- **`pnpm test:coverage`** (root) - Builds everything once, then runs `test:coverage:self` on all packages
93+
- **`pnpm test:coverage`** (package) - Builds dependencies first, then runs coverage
94+
- **`pnpm test:coverage:self`** - Runs only the package's coverage tests (no building)
95+
96+
#### Key Benefits
97+
98+
- **Efficiency**: Root `pnpm test` builds once, then tests all packages
99+
- **Reliability**: Individual package tests always ensure dependencies are built
100+
- **Consistency**: Same patterns work at any level (root or package)
101+
- **Child Package Support**: Packages with child packages delegate testing appropriately
102+
103+
#### Examples
104+
105+
```bash
106+
# Build everything from root
107+
pnpm build
108+
109+
# Test everything from root (builds once, tests all)
110+
pnpm test
111+
112+
# Test a specific package (builds its dependencies, then tests)
113+
cd packages/horizon && pnpm test
114+
115+
# Test without building (assumes dependencies already built)
116+
cd packages/horizon && pnpm test:self
70117
```
71118

72119
### Versioning and publishing packages
@@ -118,6 +165,158 @@ pnpm publish --recursive
118165

119166
Alternatively, there is a GitHub action that can be manually triggered to publish a package.
120167

168+
## Linting Configuration
169+
170+
This monorepo uses a comprehensive linting setup with multiple tools to ensure code quality and consistency across all packages.
171+
172+
### Linting Tools Overview
173+
174+
- **ESLint**: JavaScript/TypeScript code quality and style enforcement
175+
- **Prettier**: Code formatting for JavaScript, TypeScript, JSON, Markdown, YAML, and Solidity
176+
- **Solhint**: Solidity-specific linting for smart contracts
177+
- **Markdownlint**: Markdown formatting and style consistency
178+
- **YAML Lint**: YAML file validation and formatting
179+
180+
### Configuration Architecture
181+
182+
The linting configuration follows a hierarchical structure where packages inherit from root-level configurations:
183+
184+
#### ESLint Configuration
185+
186+
- **Root Configuration**: `eslint.config.mjs` - Modern flat config format
187+
- **Direct Command**: `npx eslint '**/*.{js,ts,cjs,mjs,jsx,tsx}' --fix`
188+
- **Behavior**: ESLint automatically searches up parent directories to find configuration files
189+
- **Package Inheritance**: Packages automatically inherit the root ESLint configuration without needing local config files
190+
- **Global Ignores**: Configured to exclude autogenerated files (`.graphclient-extracted/`, `lib/`) and build outputs
191+
192+
#### Prettier Configuration
193+
194+
- **Root Configuration**: `prettier.config.cjs` - Base formatting rules for all file types
195+
- **Direct Command**: `npx prettier -w --cache '**/*.{js,ts,cjs,mjs,jsx,tsx,json,md,sol,yml,yaml}'`
196+
- **Package Inheritance**: Packages that need Prettier must have a `prettier.config.cjs` file that inherits from the shared config
197+
- **Example Package Config**:
198+
199+
```javascript
200+
const baseConfig = require('../../prettier.config.cjs')
201+
module.exports = { ...baseConfig }
202+
```
203+
204+
- **Ignore Files**: `.prettierignore` excludes lock files, build outputs, and third-party dependencies
205+
206+
#### Solidity Linting (Solhint)
207+
208+
- **Root Configuration**: `.solhint.json` - Base Solidity linting rules extending `solhint:recommended`
209+
- **Direct Command**: `npx solhint 'contracts/**/*.sol'` (add `--fix` for auto-fixing)
210+
- **List Applied Rules**: `npx solhint list-rules`
211+
- **TODO Comment Checking**: `scripts/check-todos.sh` - Blocks commits and linting if TODO/FIXME/XXX/HACK comments are found in changed Solidity files
212+
- **Package Inheritance**: Packages can extend the root config with package-specific rules
213+
- **Configuration Inheritance Limitation**: Solhint has a limitation where nested `extends` don't work properly. When a local config extends a parent config that itself extends `solhint:recommended`, the built-in ruleset is ignored.
214+
- **Recommended Package Extension Pattern**:
215+
216+
```json
217+
{
218+
"extends": ["solhint:recommended", "./../../.solhint.json"],
219+
"rules": {
220+
"no-console": "off",
221+
"import-path-check": "off"
222+
}
223+
}
224+
```
225+
226+
#### Markdown Linting (Markdownlint)
227+
228+
- **Root Configuration**: `.markdownlint.json` - Markdown formatting and style rules
229+
- **Direct Command**: `npx markdownlint '**/*.md' --fix`
230+
- **Ignore Files**: `.markdownlintignore` automatically picked up by markdownlint CLI
231+
- **Global Application**: Applied to all markdown files across the monorepo
232+
233+
### Linting Scripts
234+
235+
#### Root Level Scripts
236+
237+
```bash
238+
# Run all linting tools
239+
pnpm lint
240+
241+
# Individual linting commands
242+
pnpm lint:ts # ESLint + Prettier for TypeScript/JavaScript
243+
pnpm lint:sol # TODO check + Solhint + Prettier for Solidity (runs recursively)
244+
pnpm lint:md # Markdownlint + Prettier for Markdown
245+
pnpm lint:json # Prettier for JSON files
246+
pnpm lint:yaml # YAML linting + Prettier
247+
248+
# Lint only staged files (useful for manual pre-commit checks)
249+
pnpm lint:staged # Run linting on git-staged files only
250+
```
251+
252+
#### Package Level Scripts
253+
254+
Each package can define its own linting scripts that work with the inherited configurations:
255+
256+
```bash
257+
# Example from packages/contracts
258+
pnpm lint:sol # Solhint for contracts in this package only
259+
pnpm lint:ts # ESLint for TypeScript files in this package
260+
```
261+
262+
### Pre-commit Hooks (lint-staged)
263+
264+
The repository uses `lint-staged` with Husky to run linting on staged files before commits:
265+
266+
- **Automatic**: Runs automatically on `git commit` via Husky pre-commit hook
267+
- **Manual**: Run `pnpm lint:staged` to manually check staged files before committing
268+
- **Configuration**: Root `package.json` contains lint-staged configuration
269+
- **Custom Script**: `scripts/lint-staged-run.sh` filters out generated files that shouldn't be linted
270+
- **File Type Handling**:
271+
- `.{js,ts,cjs,mjs,jsx,tsx}`: ESLint + Prettier
272+
- `.sol`: TODO check + Solhint + Prettier
273+
- `.md`: Markdownlint + Prettier
274+
- `.json`: Prettier only
275+
- `.{yml,yaml}`: YAML lint + Prettier
276+
277+
**Usage**: `pnpm lint:staged` is particularly useful when you want to check what linting changes will be applied to your staged files before actually committing.
278+
279+
### TODO Comment Enforcement
280+
281+
The repository enforces TODO comment resolution to maintain code quality:
282+
283+
- **Scope**: Applies only to Solidity (`.sol`) files
284+
- **Detection**: Finds TODO, FIXME, XXX, and HACK comments (case-insensitive)
285+
- **Triggers**:
286+
- **Pre-commit**: Blocks commits if TODO comments exist in files being committed
287+
- **Regular linting**: Flags TODO comments in locally changed, staged, or untracked Solidity files
288+
- **Script**: `scripts/check-todos.sh` (must be run from repository root)
289+
- **Bypass**: Use `git commit --no-verify` to bypass (not recommended for production)
290+
291+
### Key Design Principles
292+
293+
1. **Hierarchical Configuration**: Root configurations provide base rules, packages can extend as needed
294+
2. **Tool-Specific Inheritance**: ESLint searches up automatically, Prettier requires explicit inheritance
295+
3. **Generated File Exclusion**: Multiple layers of exclusion for autogenerated content
296+
4. **Consistent Formatting**: Prettier ensures consistent code formatting across all file types
297+
5. **Fail-Fast Linting**: Pre-commit hooks catch issues before they enter the repository
298+
299+
### Configuration Files Reference
300+
301+
| Tool | Root Config | Package Config | Ignore Files |
302+
| ------------ | --------------------- | -------------------------------- | ---------------------------- |
303+
| ESLint | `eslint.config.mjs` | Auto-inherited | Built into config |
304+
| Prettier | `prettier.config.cjs` | `prettier.config.cjs` (inherits) | `.prettierignore` |
305+
| Solhint | `.solhint.json` | `.solhint.json` (array extends) | N/A |
306+
| Markdownlint | `.markdownlint.json` | Auto-inherited | `.markdownlintignore` |
307+
| Lint-staged | `package.json` | N/A | `scripts/lint-staged-run.sh` |
308+
309+
### Troubleshooting
310+
311+
- **ESLint not finding config**: ESLint searches up parent directories automatically - no local config needed
312+
- **Prettier not working**: Packages need a `prettier.config.cjs` that inherits from root config
313+
- **Solhint missing rules**: If extending a parent config, use array format: `["solhint:recommended", "./../../.solhint.json"]` to ensure all rules are loaded
314+
- **Solhint inheritance not working**: Nested extends don't work - parent config's `solhint:recommended` won't be inherited with simple string extends
315+
- **Solhint rule reference**: Use `npx solhint list-rules` to see all available rules and their descriptions
316+
- **Generated files being linted**: Check ignore patterns in `.prettierignore`, `.markdownlintignore`, and ESLint config
317+
- **Preview lint changes before commit**: Use `pnpm lint:staged` to see what changes will be applied to staged files
318+
- **Commit blocked by linting**: Fix the linting issues or use `git commit --no-verify` to bypass (not recommended)
319+
121320
## Documentation
122321

123322
> Coming soon

0 commit comments

Comments
 (0)