Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
8 changes: 4 additions & 4 deletions .github/workflows/build-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,16 @@ jobs:
run: pnpm -r --sequential run build

- name: Test all packages
run: pnpm -r --sequential run test
run: pnpm -r --sequential run test:self

- name: Test with coverage
run: pnpm -r --sequential run test:coverage
run: pnpm -r --sequential run test:coverage:self

- name: Find coverage files
id: coverage_files
run: |
# Find all coverage-final.json files
COVERAGE_FILES=$(find ./packages -name "coverage-final.json" -path "*/reports/coverage/*" | tr '\n' ',' | sed 's/,$//')
COVERAGE_FILES=$(find ./packages -name "coverage-final.json" -path "*/coverage/*" | tr '\n' ',' | sed 's/,$//')
echo "files=$COVERAGE_FILES" >> $GITHUB_OUTPUT
echo "Found coverage files: $COVERAGE_FILES"

Expand All @@ -47,4 +47,4 @@ jobs:
files: ${{ steps.coverage_files.outputs.files }}
flags: unittests
name: graphprotocol-contracts
fail_ci_if_error: true
fail_ci_if_error: false
18 changes: 0 additions & 18 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -167,15 +167,6 @@ jobs:
echo "sol_prettier_exit_code=0" >> $GITHUB_OUTPUT
fi

- name: Lint Solidity files (Natspec Documentation)
id: lint_sol_natspec
continue-on-error: true
run: |
echo "Checking Solidity documentation with natspec-smells..."
# Run natspec-smells from root to check all configured packages
npx natspec-smells
echo "sol_natspec_exit_code=$?" >> $GITHUB_OUTPUT

- name: Lint Markdown files (Markdownlint)
id: lint_md_markdownlint
continue-on-error: true
Expand Down Expand Up @@ -320,15 +311,6 @@ jobs:
WARNINGS=$((WARNINGS+1))
fi

# Solidity - Natspec Documentation
if [ "$SOL_NATSPEC_EXIT_CODE" = "1" ]; then
echo "::error::natspec-smells found documentation issues in Solidity files"
ERRORS=$((ERRORS+1))
elif [ "$SOL_NATSPEC_EXIT_CODE" != "0" ]; then
echo "::warning::natspec-smells found warnings in Solidity files"
WARNINGS=$((WARNINGS+1))
fi

# Markdown - Markdownlint
if [ "$MD_MARKDOWNLINT_EXIT_CODE" = "1" ]; then
echo "::error::Markdownlint found errors in Markdown files"
Expand Down
7 changes: 3 additions & 4 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@ core.*

# Dependency directories
node_modules/
forge-std/
**/lib/forge-std/
.pnpm-store/

# Yarn
.yarn/*
Expand Down Expand Up @@ -41,6 +40,8 @@ types-v5/
wagmi/
types/
deployments/hardhat/
*.js.map
*.d.ts.map

# TypeScript incremental compilation cache
**/tsconfig.tsbuildinfo
Expand Down Expand Up @@ -69,7 +70,6 @@ arbitrum-addresses-local.json
addresses-fork.json
addresses-hardhat.json
addresses-local*.json
addresses-local-network.json

# Keys
.keystore
Expand All @@ -78,7 +78,6 @@ addresses-local-network.json
cache_forge
forge-artifacts/
out/
packages/issuance/lib/forge-std/

# Graph client
.graphclient
Expand Down
6 changes: 3 additions & 3 deletions .markdownlint.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
{
"default": true,
"MD004": { "style": "dash" },
"MD007": { "indent": 2 },
"MD013": false,
"MD024": { "siblings_only": true },
"MD033": false,
"MD029": { "style": "ordered" },
"MD007": { "indent": 2 },
"MD004": { "style": "dash" }
"MD033": false
}
15 changes: 8 additions & 7 deletions .markdownlintignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# Autogenerated GraphClient files (committed but should not be linted)
**/.graphclient-extracted/
**/.graphclient/

# Dependencies
node_modules/

Expand Down Expand Up @@ -30,10 +34,7 @@ lcov.info
packages/*/.eslintcache
deployments/hardhat/
.graphclient
**/chain-31337/
**/chain-1377/
**/horizon-localhost/
**/horizon-hardhat/
**/subgraph-service-localhost/
**/subgraph-service-hardhat/
.changeset/
**/chain-*/
**/*-localhost/
**/*-hardhat/
.changeset/
11 changes: 4 additions & 7 deletions .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ node_modules/

# Third-party libraries in lib directories
**/lib/
forge-std/

# Build outputs (from .gitignore)
**/build/
Expand Down Expand Up @@ -36,9 +35,7 @@ lcov.info
packages/*/.eslintcache
deployments/hardhat/
.graphclient
**/chain-31337/
**/chain-1377/
**/horizon-localhost/
**/horizon-hardhat/
**/subgraph-service-localhost/
**/subgraph-service-hardhat/
**/.graphclient-extracted/
**/chain-*/
**/*-localhost/
**/*-hardhat/
201 changes: 200 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,11 @@ This repository is a pnpm workspaces monorepo containing the following packages:
| Package | Latest version | Description |
| ----------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------- |
| [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. |
| [data-edge](./packages/data-edge) | - | Data edge testing and utilities for The Graph protocol. |
| [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. |
| [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. |
| [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. |
| [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. |
| [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 |
| [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. |
| [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. |
| [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. |
Expand Down Expand Up @@ -67,6 +68,52 @@ $ pnpm install

# Build projects
$ pnpm build

# Run tests
$ pnpm test
```

### Script Patterns

This monorepo follows consistent script patterns across all packages to ensure reliable builds and tests:

#### Build Scripts

- **`pnpm build`** (root) - Builds all packages by calling `build:self` on each
- **`pnpm build`** (package) - Builds dependencies first, then the package itself
- **`pnpm build:self`** - Builds only the current package (no dependencies)
- **`pnpm build:dep`** - Builds workspace dependencies needed by the current package

#### Test Scripts

- **`pnpm test`** (root) - Builds everything once, then runs `test:self` on all packages
- **`pnpm test`** (package) - Builds dependencies first, then runs tests
- **`pnpm test:self`** - Runs only the package's tests (no building)
- **`pnpm test:coverage`** (root) - Builds everything once, then runs `test:coverage:self` on all packages
- **`pnpm test:coverage`** (package) - Builds dependencies first, then runs coverage
- **`pnpm test:coverage:self`** - Runs only the package's coverage tests (no building)

#### Key Benefits

- **Efficiency**: Root `pnpm test` builds once, then tests all packages
- **Reliability**: Individual package tests always ensure dependencies are built
- **Consistency**: Same patterns work at any level (root or package)
- **Child Package Support**: Packages with child packages delegate testing appropriately

#### Examples

```bash
# Build everything from root
pnpm build

# Test everything from root (builds once, tests all)
pnpm test

# Test a specific package (builds its dependencies, then tests)
cd packages/horizon && pnpm test

# Test without building (assumes dependencies already built)
cd packages/horizon && pnpm test:self
```

### Versioning and publishing packages
Expand Down Expand Up @@ -118,6 +165,158 @@ pnpm publish --recursive

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

## Linting Configuration

This monorepo uses a comprehensive linting setup with multiple tools to ensure code quality and consistency across all packages.

### Linting Tools Overview

- **ESLint**: JavaScript/TypeScript code quality and style enforcement
- **Prettier**: Code formatting for JavaScript, TypeScript, JSON, Markdown, YAML, and Solidity
- **Solhint**: Solidity-specific linting for smart contracts
- **Markdownlint**: Markdown formatting and style consistency
- **YAML Lint**: YAML file validation and formatting

### Configuration Architecture

The linting configuration follows a hierarchical structure where packages inherit from root-level configurations:

#### ESLint Configuration

- **Root Configuration**: `eslint.config.mjs` - Modern flat config format
- **Direct Command**: `npx eslint '**/*.{js,ts,cjs,mjs,jsx,tsx}' --fix`
- **Behavior**: ESLint automatically searches up parent directories to find configuration files
- **Package Inheritance**: Packages automatically inherit the root ESLint configuration without needing local config files
- **Global Ignores**: Configured to exclude autogenerated files (`.graphclient-extracted/`, `lib/`) and build outputs

#### Prettier Configuration

- **Root Configuration**: `prettier.config.cjs` - Base formatting rules for all file types
- **Direct Command**: `npx prettier -w --cache '**/*.{js,ts,cjs,mjs,jsx,tsx,json,md,sol,yml,yaml}'`
- **Package Inheritance**: Packages that need Prettier must have a `prettier.config.cjs` file that inherits from the shared config
- **Example Package Config**:

```javascript
const baseConfig = require('../../prettier.config.cjs')
module.exports = { ...baseConfig }
```

- **Ignore Files**: `.prettierignore` excludes lock files, build outputs, and third-party dependencies

#### Solidity Linting (Solhint)

- **Root Configuration**: `.solhint.json` - Base Solidity linting rules extending `solhint:recommended`
- **Direct Command**: `npx solhint 'contracts/**/*.sol'` (add `--fix` for auto-fixing)
- **List Applied Rules**: `npx solhint list-rules`
- **TODO Comment Checking**: `scripts/check-todos.sh` - Blocks commits and linting if TODO/FIXME/XXX/HACK comments are found in changed Solidity files
- **Package Inheritance**: Packages can extend the root config with package-specific rules
- **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.
- **Recommended Package Extension Pattern**:

```json
{
"extends": ["solhint:recommended", "./../../.solhint.json"],
"rules": {
"no-console": "off",
"import-path-check": "off"
}
}
```

#### Markdown Linting (Markdownlint)

- **Root Configuration**: `.markdownlint.json` - Markdown formatting and style rules
- **Direct Command**: `npx markdownlint '**/*.md' --fix`
- **Ignore Files**: `.markdownlintignore` automatically picked up by markdownlint CLI
- **Global Application**: Applied to all markdown files across the monorepo

### Linting Scripts

#### Root Level Scripts

```bash
# Run all linting tools
pnpm lint

# Individual linting commands
pnpm lint:ts # ESLint + Prettier for TypeScript/JavaScript
pnpm lint:sol # TODO check + Solhint + Prettier for Solidity (runs recursively)
pnpm lint:md # Markdownlint + Prettier for Markdown
pnpm lint:json # Prettier for JSON files
pnpm lint:yaml # YAML linting + Prettier

# Lint only staged files (useful for manual pre-commit checks)
pnpm lint:staged # Run linting on git-staged files only
```

#### Package Level Scripts

Each package can define its own linting scripts that work with the inherited configurations:

```bash
# Example from packages/contracts
pnpm lint:sol # Solhint for contracts in this package only
pnpm lint:ts # ESLint for TypeScript files in this package
```

### Pre-commit Hooks (lint-staged)

The repository uses `lint-staged` with Husky to run linting on staged files before commits:

- **Automatic**: Runs automatically on `git commit` via Husky pre-commit hook
- **Manual**: Run `pnpm lint:staged` to manually check staged files before committing
- **Configuration**: Root `package.json` contains lint-staged configuration
- **Custom Script**: `scripts/lint-staged-run.sh` filters out generated files that shouldn't be linted
- **File Type Handling**:
- `.{js,ts,cjs,mjs,jsx,tsx}`: ESLint + Prettier
- `.sol`: TODO check + Solhint + Prettier
- `.md`: Markdownlint + Prettier
- `.json`: Prettier only
- `.{yml,yaml}`: YAML lint + Prettier

**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.

### TODO Comment Enforcement

The repository enforces TODO comment resolution to maintain code quality:

- **Scope**: Applies only to Solidity (`.sol`) files
- **Detection**: Finds TODO, FIXME, XXX, and HACK comments (case-insensitive)
- **Triggers**:
- **Pre-commit**: Blocks commits if TODO comments exist in files being committed
- **Regular linting**: Flags TODO comments in locally changed, staged, or untracked Solidity files
- **Script**: `scripts/check-todos.sh` (must be run from repository root)
- **Bypass**: Use `git commit --no-verify` to bypass (not recommended for production)

### Key Design Principles

1. **Hierarchical Configuration**: Root configurations provide base rules, packages can extend as needed
2. **Tool-Specific Inheritance**: ESLint searches up automatically, Prettier requires explicit inheritance
3. **Generated File Exclusion**: Multiple layers of exclusion for autogenerated content
4. **Consistent Formatting**: Prettier ensures consistent code formatting across all file types
5. **Fail-Fast Linting**: Pre-commit hooks catch issues before they enter the repository

### Configuration Files Reference

| Tool | Root Config | Package Config | Ignore Files |
| ------------ | --------------------- | -------------------------------- | ---------------------------- |
| ESLint | `eslint.config.mjs` | Auto-inherited | Built into config |
| Prettier | `prettier.config.cjs` | `prettier.config.cjs` (inherits) | `.prettierignore` |
| Solhint | `.solhint.json` | `.solhint.json` (array extends) | N/A |
| Markdownlint | `.markdownlint.json` | Auto-inherited | `.markdownlintignore` |
| Lint-staged | `package.json` | N/A | `scripts/lint-staged-run.sh` |

### Troubleshooting

- **ESLint not finding config**: ESLint searches up parent directories automatically - no local config needed
- **Prettier not working**: Packages need a `prettier.config.cjs` that inherits from root config
- **Solhint missing rules**: If extending a parent config, use array format: `["solhint:recommended", "./../../.solhint.json"]` to ensure all rules are loaded
- **Solhint inheritance not working**: Nested extends don't work - parent config's `solhint:recommended` won't be inherited with simple string extends
- **Solhint rule reference**: Use `npx solhint list-rules` to see all available rules and their descriptions
- **Generated files being linted**: Check ignore patterns in `.prettierignore`, `.markdownlintignore`, and ESLint config
- **Preview lint changes before commit**: Use `pnpm lint:staged` to see what changes will be applied to staged files
- **Commit blocked by linting**: Fix the linting issues or use `git commit --no-verify` to bypass (not recommended)

## Documentation

> Coming soon
Expand Down
17 changes: 17 additions & 0 deletions codecov.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
coverage:
status:
project:
default:
informational: true
patch:
default:
informational: true

ignore:
- '**/tests/**'
- '**/test/**'
- '**/*.test.sol'
- '**/*.t.sol'
- '**/Mock*.sol'
- '**/mocks/**'
- '**/scripts/**'
Loading
Loading