diff --git a/.changeset/smooth-balloons-stare.md b/.changeset/smooth-balloons-stare.md deleted file mode 100644 index 66a578e07..000000000 --- a/.changeset/smooth-balloons-stare.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@graphprotocol/contracts": patch ---- - -make sdk and console table printer a dev dep diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile new file mode 100644 index 000000000..9c542e4d9 --- /dev/null +++ b/.devcontainer/Dockerfile @@ -0,0 +1,84 @@ +FROM mcr.microsoft.com/devcontainers/base:debian + +# Set non-interactive frontend for apt +ENV DEBIAN_FRONTEND=noninteractive + +# Switch to root for installing packages +USER root + +# Install additional dependencies +RUN apt update && apt install -y \ + build-essential \ + curl \ + jq \ + python3 \ + python3-pip \ + python3-venv \ + pipx \ + && apt clean \ + && rm -rf /var/lib/apt/lists/* + +# Install Node.js 20.x using NodeSource +RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash - && \ + apt update && \ + apt install -y nodejs && \ + apt clean && \ + rm -rf /var/lib/apt/lists/* + +# Install Solidity compiler using pipx (isolated environment) +RUN pipx install solc-select && \ + pipx ensurepath && \ + /root/.local/bin/solc-select install 0.8.27 && \ + /root/.local/bin/solc-select use 0.8.27 && \ + # Copy binaries to /usr/local/bin with proper permissions (not symlinks) + cp /root/.local/bin/solc /usr/local/bin/solc && \ + cp /root/.local/bin/solc-select /usr/local/bin/solc-select && \ + chmod 755 /usr/local/bin/solc && \ + chmod 755 /usr/local/bin/solc-select && \ + # Make sure pipx directory is accessible + chmod -R a+rx /root/.local/pipx && \ + # Set up for vscode user + mkdir -p /home/vscode/.solc-select && \ + cp -r /root/.solc-select/* /home/vscode/.solc-select/ && \ + chown -R vscode:vscode /home/vscode/.solc-select + +RUN npm install -g ethers@6.13.4 + +# Install cloc for code analysis +RUN npm install -g cloc + +# Install Foundry for Anvil (as root for global installation) +RUN curl -L https://foundry.paradigm.xyz | bash && \ + /root/.foundry/bin/foundryup && \ + # Copy binaries to /usr/local/bin with proper permissions + cp /root/.foundry/bin/anvil /usr/local/bin/anvil && \ + cp /root/.foundry/bin/cast /usr/local/bin/cast && \ + cp /root/.foundry/bin/forge /usr/local/bin/forge && \ + cp /root/.foundry/bin/chisel /usr/local/bin/chisel && \ + # Ensure proper permissions + chmod 755 /usr/local/bin/anvil && \ + chmod 755 /usr/local/bin/cast && \ + chmod 755 /usr/local/bin/forge && \ + chmod 755 /usr/local/bin/chisel + +# Set up pnpm +RUN corepack enable && \ + corepack prepare pnpm@9.0.6 --activate + +# Ensure all users have access to the tools +RUN chmod 755 /usr/local/bin/* && \ + # Create a directory for vscode user's binaries + mkdir -p /home/vscode/.local/bin && \ + chown -R vscode:vscode /home/vscode/.local/bin + +# Switch back to vscode user +USER vscode + +# Set environment variables +ENV PATH="/usr/local/bin:/home/vscode/.foundry/bin:/home/vscode/.local/bin:/root/.local/bin:$PATH" + +# Create .bashrc additions for PATH +RUN echo 'export PATH="/usr/local/bin:$HOME/.local/bin:$PATH"' >> $HOME/.bashrc + +# Set the default command +CMD ["sleep", "infinity"] diff --git a/.devcontainer/README.md b/.devcontainer/README.md new file mode 100644 index 000000000..73b33e9be --- /dev/null +++ b/.devcontainer/README.md @@ -0,0 +1,107 @@ +# Graph Protocol Contracts Dev Container + +This directory contains configuration files for the Graph Protocol contracts development container. + +> **Note:** This dev container setup is a work in progress and will not be fully portable. + +## Overview + +The dev container provides a consistent development environment with caching to improve performance. + +### Key Components + +1. **Docker Compose Configuration**: Defines the container setup, volume mounts, and environment variables +2. **Dockerfile**: Specifies the container image and installed tools +3. **project-setup.sh**: Configures the environment after container creation +4. **host-setup.sh**: Sets up the host environment before starting the container +5. **setup-git-signing.sh**: Automatically configures Git to use SSH signing with forwarded SSH keys + +## Cache System + +The container uses a conservative caching approach to prevent cache corruption issues: + +1. **Local Cache Directories**: Each container instance maintains its own cache directories + + - `vscode-cache` → `/home/vscode/.cache` (VS Code cache) + - `vscode-config` → `/home/vscode/.config` (VS Code configuration) + - `vscode-data` → `/home/vscode/.local/share` (VS Code data) + - `vscode-bin` → `/home/vscode/.local/bin` (User binaries) + +2. **Safe Caches Only**: Only caches that won't cause cross-branch issues are configured + + - GitHub CLI: `/home/vscode/.cache/github` + - Python packages: `/home/vscode/.cache/pip` + +3. **Intentionally Not Cached**: These tools use their default cache locations to avoid contamination + - NPM (different dependency versions per branch) + - Foundry, Solidity (different compilation artifacts per branch) + - Hardhat (different build artifacts per branch) + +## Setup Instructions + +### Start the Dev Container + +To start the dev container: + +1. Open VS Code +2. Use the "Remote-Containers: Open Folder in Container" command +3. Select the repository directory (for example `/git/graphprotocol/contracts`) + +When the container starts, the `project-setup.sh` script will automatically run and: + +- Install project dependencies using pnpm +- Configure Git to use SSH signing with your forwarded SSH key +- Source shell customizations if available in PATH + +## Environment Variables + +Environment variables are defined in two places: + +1. **docker-compose.yml**: Contains most of the environment variables for tools and caching +2. **Environment File**: Personal settings are stored in `/opt/configs/graphprotocol/contracts.env` on the host + +### Git Configuration + +To enable Git commit signing, add the following settings to your environment file: + +```env +# Git settings for commit signing +GIT_USER_NAME=Your Name +GIT_USER_EMAIL=your.email@example.com +``` + +These environment variables are needed for Git commit signing to work properly. If they are not defined, Git commit signing will not be configured, but the container will still work for other purposes. + +## Troubleshooting + +### Cache Issues + +If you encounter build or compilation issues that seem related to cached artifacts: + +1. **Rebuild the container**: This will start with fresh local caches +2. **Clean project caches**: Run `pnpm clean` to clear project-specific build artifacts +3. **Clear node modules**: Delete `node_modules` and run `pnpm install` again + +### Git SSH Signing Issues + +If you encounter issues with Git SSH signing: + +1. **SSH Agent Forwarding**: Make sure SSH agent forwarding is properly set up in your VS Code settings +2. **GitHub Configuration**: Ensure your SSH key is added to GitHub as a signing key in your account settings +3. **Manual Setup**: If automatic setup fails, you can manually configure SSH signing: + +```bash +# Check available SSH keys +ssh-add -l + +# Configure Git to use SSH signing +git config --global gpg.format ssh +git config --global user.signingkey "key::ssh-ed25519 YOUR_KEY_CONTENT" +git config --global gpg.ssh.allowedSignersFile ~/.ssh/allowed_signers +git config --global commit.gpgsign true + +# Create allowed signers file +echo "your.email@example.com ssh-ed25519 YOUR_KEY_CONTENT" > ~/.ssh/allowed_signers +``` + +For other issues, check the `project-setup.sh` and `setup-git-signing.sh` scripts for any errors. diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 000000000..8d7fb643d --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,42 @@ +{ + "name": "graph contracts", + "dockerComposeFile": ["docker-compose.yml"], + "service": "dev-graph-contracts", + "features": { + "ghcr.io/devcontainers/features/git:1": { + "configureGitHubCLI": true, + "gitCredentialHelper": "cache" + }, + "ghcr.io/devcontainers/features/github-cli:1": {}, + "ghcr.io/devcontainers/features/common-utils:2.5.3": {}, + "ghcr.io/devcontainers/features/node:1": { + "version": "20" + }, + "ghcr.io/devcontainers/features/docker-outside-of-docker:1": {} + }, + "postCreateCommand": ".devcontainer/project-setup.sh", + "remoteUser": "vscode", + "workspaceFolder": "${localWorkspaceFolder}", + "customizations": { + "vscode": { + "extensions": [ + "rust-lang.rust-analyzer", + "tamasfe.even-better-toml", + "usernamehw.errorlens", + "yzhang.markdown-all-in-one", + "DavidAnson.vscode-markdownlint", + "shd101wyy.markdown-preview-enhanced", + "bierner.markdown-preview-github-styles", + "Gruntfuggly.todo-tree", + "ms-azuretools.vscode-docker", + "donjayamanne.githistory", + "eamodio.gitlens", + "fill-labs.dependi", + "streetsidesoftware.code-spell-checker", + "Augment.vscode-augment", + "NomicFoundation.hardhat-solidity", + "foundry-rs.foundry-vscode" + ] + } + } +} diff --git a/.devcontainer/docker-compose.yml b/.devcontainer/docker-compose.yml new file mode 100644 index 000000000..d16a44b34 --- /dev/null +++ b/.devcontainer/docker-compose.yml @@ -0,0 +1,53 @@ +services: + dev-graph-contracts: + build: + context: . + dockerfile: Dockerfile + env_file: + - /opt/configs/graphprotocol/contracts.env + environment: + # Essential for large builds + - NODE_OPTIONS=--max-old-space-size=4096 + + # Clean development environment + - PYTHONDONTWRITEBYTECODE=1 + + # Disable interactive prompts + - COREPACK_ENABLE_DOWNLOAD_PROMPT=0 + + # Standard user directories + - XDG_CACHE_HOME=/home/vscode/.cache + - XDG_CONFIG_HOME=/home/vscode/.config + - XDG_DATA_HOME=/home/vscode/.local/share + + # Safe caches (won't cause cross-branch issues) + - GH_CONFIG_DIR=/home/vscode/.cache/github + - PIP_CACHE_DIR=/home/vscode/.cache/pip + + # pnpm cache is safe to share due to content-addressable storage + - PNPM_HOME=/home/vscode/.local/share/pnpm + - PNPM_CACHE_DIR=/home/vscode/.cache/pnpm + + # Note: NPM, Foundry, and Solidity caches are intentionally not set + # to avoid cross-branch contamination. Tools will use their default locations. + volumes: + # Git repo root + - /git:/git + + # Local directories for user data (keep local to container) + - vscode-cache:/home/vscode/.cache + - vscode-config:/home/vscode/.config + - vscode-data:/home/vscode/.local/share + - vscode-bin:/home/vscode/.local/bin + + # Shared pnpm cache (safe due to content-addressable storage) + - pnpm-store:/home/vscode/.local/share/pnpm + - pnpm-cache:/home/vscode/.cache/pnpm + +volumes: + vscode-cache: + vscode-config: + vscode-data: + vscode-bin: + pnpm-store: + pnpm-cache: diff --git a/.devcontainer/host-setup.sh b/.devcontainer/host-setup.sh new file mode 100755 index 000000000..b85093826 --- /dev/null +++ b/.devcontainer/host-setup.sh @@ -0,0 +1,48 @@ +#!/usr/bin/env bash +# Host setup script for Graph Protocol Contracts dev container +# Run this script on the host before starting the dev container +# Usage: sudo .devcontainer/host-setup.sh + +set -euo pipefail + +echo "Setting up host environment for Graph Protocol Contracts dev container..." + +# Check if running as root +if [ "$(id -u)" -ne 0 ]; then + echo "Error: This script must be run as root (sudo)" >&2 + exit 1 +fi + +CACHE_DIRS=( + "/cache/vscode-cache" + "/cache/vscode-config" + "/cache/vscode-data" + "/cache/vscode-bin" + "/cache/hardhat" + "/cache/npm" + "/cache/yarn" + "/cache/pip" + "/cache/pycache" + "/cache/solidity" + "/cache/foundry" + "/cache/github" + "/cache/apt" + "/cache/apt-lib" +) + +echo "Creating cache directories..." +for dir in "${CACHE_DIRS[@]}"; do + if [ ! -d "$dir" ]; then + echo "Creating $dir" + mkdir -p "$dir" + chmod 777 "$dir" + else + echo "$dir already exists" + fi +done + +# Note: Package-specific directories will be created by the project-setup.sh script +# inside the container, as they are tied to the project structure + +echo "Host setup completed successfully!" +echo "You can now start or rebuild your dev container." diff --git a/.devcontainer/project-setup.sh b/.devcontainer/project-setup.sh new file mode 100755 index 000000000..34fe59653 --- /dev/null +++ b/.devcontainer/project-setup.sh @@ -0,0 +1,82 @@ +#!/bin/bash +# Project-specific setup script for graph +set -euo pipefail + +echo "Running project-specific setup for graph..." + +# Get the script directory and repository root +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" + +echo "Script directory: $SCRIPT_DIR" +echo "Repository root: $REPO_ROOT" + +# Set up local user directories with proper permissions +echo "Setting up local user directories..." + +# Ensure all user directories exist and have proper ownership +sudo mkdir -p /home/vscode/.cache /home/vscode/.config /home/vscode/.local/share /home/vscode/.local/bin +sudo chown -R vscode:vscode /home/vscode/.cache /home/vscode/.config /home/vscode/.local +sudo chmod -R 755 /home/vscode/.cache /home/vscode/.config /home/vscode/.local + +echo "User directories set up with proper permissions" + +# Install project dependencies +echo "Installing project dependencies..." +if [ -f "$REPO_ROOT/package.json" ]; then + echo "Running pnpm to install dependencies..." + cd "$REPO_ROOT" + # Note: With set -e, if pnpm fails, the script will exit + # This is desirable as we want to ensure dependencies are properly installed + pnpm install +else + echo "No package.json found in the root directory, skipping dependency installation" +fi + +# Add CONTAINER_BIN_PATH to PATH if it's set +if [ -n "${CONTAINER_BIN_PATH:-}" ]; then + echo "CONTAINER_BIN_PATH is set to: $CONTAINER_BIN_PATH" + echo "Adding CONTAINER_BIN_PATH to PATH..." + + # Add to current PATH + export PATH="$CONTAINER_BIN_PATH:$PATH" + + # Add to .bashrc if not already there + if ! grep -q "export PATH=\"\$CONTAINER_BIN_PATH:\$PATH\"" "$HOME/.bashrc"; then + echo "Adding CONTAINER_BIN_PATH to .bashrc..." + echo ' +# Add CONTAINER_BIN_PATH to PATH if set +if [ -n "${CONTAINER_BIN_PATH:-}" ]; then + export PATH="$CONTAINER_BIN_PATH:$PATH" +fi' >> "$HOME/.bashrc" + fi + + echo "CONTAINER_BIN_PATH added to PATH" +else + echo "CONTAINER_BIN_PATH is not set, skipping PATH modification" +fi + +# Source shell customizations if available in PATH +if command -v shell-customizations &> /dev/null; then + SHELL_CUSTOMIZATIONS_PATH=$(command -v shell-customizations) + echo "Found shell customizations in PATH at: ${SHELL_CUSTOMIZATIONS_PATH}" + echo "Sourcing shell customizations..." + source "${SHELL_CUSTOMIZATIONS_PATH}" + + # Add to .bashrc if not already there + if ! grep -q "source.*shell-customizations" "$HOME/.bashrc"; then + echo "Adding shell customizations to .bashrc..." + echo "source ${SHELL_CUSTOMIZATIONS_PATH}" >> "$HOME/.bashrc" + fi +else + echo "Shell customizations not found in PATH, skipping..." +fi + +# Set up Git SSH signing +if [ -f "$SCRIPT_DIR/setup-git-signing.sh" ]; then + "$SCRIPT_DIR/setup-git-signing.sh" +else + echo "WARNING: setup-git-signing.sh not found, skipping Git SSH signing setup" +fi + +echo "Project-specific setup completed" diff --git a/.devcontainer/sample-graph.env b/.devcontainer/sample-graph.env new file mode 100644 index 000000000..b6eab6144 --- /dev/null +++ b/.devcontainer/sample-graph.env @@ -0,0 +1,12 @@ +# Sample environment file for Graph Protocol contracts development +# Copy the Git settings below to your actual environment file at: +# /opt/configs/graphprotocol/contracts.env + +# Git settings for commit signing +# Add these settings if you want to enable Git commit signing +GIT_USER_NAME=Your Name +GIT_USER_EMAIL=your.email@example.com + +# Custom binary path +# Add this setting if you want to add a custom binary path to the PATH inside the container +# CONTAINER_BIN_PATH=/path/to/your/binaries diff --git a/.devcontainer/setup-git-signing.sh b/.devcontainer/setup-git-signing.sh new file mode 100755 index 000000000..78969dd62 --- /dev/null +++ b/.devcontainer/setup-git-signing.sh @@ -0,0 +1,76 @@ +#!/usr/bin/env bash +# Automatically configure Git to use SSH signing with forwarded SSH keys +set -euo pipefail + +echo "Setting up Git SSH signing..." + +# Check if SSH agent forwarding is working +if ! ssh-add -l &>/dev/null; then + echo "ERROR: No SSH keys found in agent. SSH agent forwarding is not set up correctly." + echo "SSH signing will not work without SSH agent forwarding." + exit 1 +fi + +# Get the first SSH key from the agent +SSH_KEY=$(ssh-add -L | head -n 1) +if [ -z "$SSH_KEY" ]; then + echo "ERROR: No SSH keys found in agent. SSH signing will not work." + exit 1 +fi + +# Extract the key type and key content +KEY_TYPE=$(echo "$SSH_KEY" | awk '{print $1}') +KEY_CONTENT=$(echo "$SSH_KEY" | awk '{print $2}') + +# Check if Git user settings are available +if [[ -z "${GIT_USER_NAME:-}" || -z "${GIT_USER_EMAIL:-}" ]]; then + echo "WARNING: Git user settings (GIT_USER_NAME and/or GIT_USER_EMAIL) are not set." + echo "Git commit signing will not be configured." + echo "If you need Git commit signing, add these variables to your environment file." + exit 0 +fi + +# Set Git user name from environment variable +echo "Setting Git user.name: $GIT_USER_NAME" +git config --global user.name "$GIT_USER_NAME" + +# Set Git user email from environment variable +echo "Setting Git user.email: $GIT_USER_EMAIL" +git config --global user.email "$GIT_USER_EMAIL" + +# Create the .ssh directory if it doesn't exist +mkdir -p ~/.ssh +chmod 700 ~/.ssh + +# Create or update the allowed signers file +echo "Updating allowed signers file..." +ALLOWED_SIGNERS_FILE=~/.ssh/allowed_signers +SIGNER_LINE="$GIT_USER_EMAIL $KEY_TYPE $KEY_CONTENT" + +# Create the file if it doesn't exist +if [ ! -f "$ALLOWED_SIGNERS_FILE" ]; then + echo "$SIGNER_LINE" > "$ALLOWED_SIGNERS_FILE" + echo "Created new allowed signers file." +else + # Check if the key is already in the file + if ! grep -q "$KEY_CONTENT" "$ALLOWED_SIGNERS_FILE"; then + # Append the key if it's not already there + echo "$SIGNER_LINE" >> "$ALLOWED_SIGNERS_FILE" + echo "Added new key to allowed signers file." + else + echo "Key already exists in allowed signers file." + fi +fi + +chmod 600 "$ALLOWED_SIGNERS_FILE" + +# Configure Git to use SSH signing +echo "Configuring Git to use SSH signing..." +git config --global gpg.format ssh +git config --global user.signingkey "key::$KEY_TYPE $KEY_CONTENT" +git config --global gpg.ssh.allowedSignersFile ~/.ssh/allowed_signers +git config --global commit.gpgsign true + +echo "Git SSH signing setup complete!" +echo "Your commits will now be automatically signed using your SSH key." +echo "Make sure this key is added to GitHub as a signing key in your account settings." diff --git a/.github/actions/setup/action.yml b/.github/actions/setup/action.yml index 780ab1aa9..d34d8e5d4 100644 --- a/.github/actions/setup/action.yml +++ b/.github/actions/setup/action.yml @@ -4,14 +4,24 @@ runs: using: composite steps: - - name: Enable corepack for modern yarn + - name: Install system dependencies + shell: bash + run: | + sudo apt-get update + sudo apt-get install -y libudev-dev libusb-1.0-0-dev + - name: Install Foundry + uses: foundry-rs/foundry-toolchain@v1 + - name: Enable Corepack shell: bash run: corepack enable - name: Install Node.js uses: actions/setup-node@v4 with: - node-version: 18 - cache: 'yarn' + node-version: 20 + cache: 'pnpm' + - name: Set up pnpm via Corepack + shell: bash + run: corepack prepare pnpm@9.0.6 --activate - name: Install dependencies shell: bash - run: yarn --immutable + run: pnpm install --frozen-lockfile diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml new file mode 100644 index 000000000..391188237 --- /dev/null +++ b/.github/workflows/build-test.yml @@ -0,0 +1,50 @@ +name: Build and Test + +env: + CI: true + STUDIO_API_KEY: ${{ secrets.STUDIO_API_KEY }} + +on: + pull_request: + branches: '*' + workflow_dispatch: + +jobs: + test: + name: Build and Test + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Set up environment + uses: ./.github/actions/setup + + - name: Build all packages + run: pnpm build + + - name: Test all packages + run: pnpm -r --sequential run test + + - name: Test with coverage + run: pnpm -r --sequential run test:coverage + + - 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/,$//') + echo "files=$COVERAGE_FILES" >> $GITHUB_OUTPUT + echo "Found coverage files: $COVERAGE_FILES" + + - name: Upload coverage reports + if: steps.coverage_files.outputs.files != '' + uses: codecov/codecov-action@v3 + with: + token: ${{ secrets.CODECOV_TOKEN }} + files: ${{ steps.coverage_files.outputs.files }} + flags: unittests + name: graphprotocol-contracts + fail_ci_if_error: true diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml deleted file mode 100644 index f35ed6d37..000000000 --- a/.github/workflows/build.yml +++ /dev/null @@ -1,23 +0,0 @@ -name: Build - -env: - CI: true - STUDIO_API_KEY: ${{ secrets.STUDIO_API_KEY }} - -on: - push: - branches: "*" - pull_request: - branches: "*" - workflow_dispatch: - -jobs: - build: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v4 - - name: Set up environment - uses: ./.github/actions/setup - - name: Build - run: yarn build || yarn build \ No newline at end of file diff --git a/.github/workflows/ci-contracts.yml b/.github/workflows/ci-contracts.yml deleted file mode 100644 index 421a64b24..000000000 --- a/.github/workflows/ci-contracts.yml +++ /dev/null @@ -1,40 +0,0 @@ -name: CI - packages/contracts - -env: - CI: true - -on: - push: - branches: "*" - paths: - - packages/contracts/** - pull_request: - branches: "*" - paths: - - packages/contracts/** - workflow_dispatch: - -jobs: - test-ci: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v4 - - name: Set up environment - uses: ./.github/actions/setup - - name: Build - run: | - pushd packages/contracts - yarn build || yarn build - - name: Run tests - run: | - pushd packages/contracts - yarn test:coverage - - name: Upload coverage report - uses: codecov/codecov-action@v3 - with: - token: ${{ secrets.CODECOV_TOKEN }} - files: ./packages/contracts/coverage.json - flags: unittests - name: graphprotocol-contracts - fail_ci_if_error: true diff --git a/.github/workflows/ci-data-edge.yml b/.github/workflows/ci-data-edge.yml deleted file mode 100644 index a8046aa7e..000000000 --- a/.github/workflows/ci-data-edge.yml +++ /dev/null @@ -1,30 +0,0 @@ -name: CI - packages/data-edge - -env: - CI: true - -on: - push: - branches: "*" - paths: - - packages/data-edge/** - pull_request: - branches: "*" - paths: - - packages/data-edge/** - workflow_dispatch: - -jobs: - test-ci: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v4 - - name: Set up environment - uses: ./.github/actions/setup - - name: Build - run: | - pushd packages/data-edge - yarn build - - name: Run tests - run: yarn test \ No newline at end of file diff --git a/.github/workflows/ci-hardhat-graph-protocol.yml b/.github/workflows/ci-hardhat-graph-protocol.yml new file mode 100644 index 000000000..60b93f52a --- /dev/null +++ b/.github/workflows/ci-hardhat-graph-protocol.yml @@ -0,0 +1,51 @@ +name: CI - packages/toolshed + +env: + CI: true + +on: + push: + branches: '*' + paths: + - packages/toolshed/** + pull_request: + branches: '*' + paths: + - packages/toolshed/** + workflow_dispatch: + +jobs: + test-ci: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + submodules: recursive + - name: Set up environment + uses: ./.github/actions/setup + - name: Build contracts + run: | + pushd packages/contracts + pnpm build + popd + - name: Build horizon + run: | + pushd packages/horizon + pnpm build + popd + - name: Build subgraph service + run: | + pushd packages/subgraph-service + pnpm build + popd + - name: Build toolshed + run: | + pushd packages/toolshed + pnpm build + popd + - name: Build hardhat-graph-protocol + run: | + pushd packages/hardhat-graph-protocol + pnpm build + popd diff --git a/.github/workflows/ci-horizon.yml b/.github/workflows/ci-horizon.yml new file mode 100644 index 000000000..f4f99398b --- /dev/null +++ b/.github/workflows/ci-horizon.yml @@ -0,0 +1,55 @@ +name: CI - packages/horizon + +env: + CI: true + +on: + push: + branches: '*' + paths: + - packages/horizon/** + pull_request: + branches: '*' + paths: + - packages/horizon/** + workflow_dispatch: + +jobs: + test-ci: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + submodules: recursive + - name: Set up environment + uses: ./.github/actions/setup + - name: Build contracts + run: | + pushd packages/contracts + pnpm build + popd + - name: Build horizon + run: | + pushd packages/horizon + pnpm build + popd + - name: Build subgraph service + run: | + pushd packages/subgraph-service + pnpm build + popd + - name: Build toolshed + run: | + pushd packages/toolshed + pnpm build + popd + - name: Build hardhat-graph-protocol + run: | + pushd packages/hardhat-graph-protocol + pnpm build + popd + - name: Run tests + run: | + pushd packages/horizon + pnpm test diff --git a/.github/workflows/ci-subgraph-service.yml b/.github/workflows/ci-subgraph-service.yml new file mode 100644 index 000000000..2ce65dcc8 --- /dev/null +++ b/.github/workflows/ci-subgraph-service.yml @@ -0,0 +1,55 @@ +name: CI - packages/subgraph-service + +env: + CI: true + +on: + push: + branches: '*' + paths: + - packages/subgraph-service/** + pull_request: + branches: '*' + paths: + - packages/subgraph-service/** + workflow_dispatch: + +jobs: + test-ci: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + submodules: recursive + - name: Set up environment + uses: ./.github/actions/setup + - name: Build contracts + run: | + pushd packages/contracts + pnpm build + popd + - name: Build horizon + run: | + pushd packages/horizon + pnpm build + popd + - name: Build subgraph service + run: | + pushd packages/subgraph-service + pnpm build + popd + - name: Build toolshed + run: | + pushd packages/toolshed + pnpm build + popd + - name: Build hardhat-graph-protocol + run: | + pushd packages/hardhat-graph-protocol + pnpm build + popd + - name: Run tests + run: | + pushd packages/subgraph-service + pnpm test diff --git a/.github/workflows/ci-token-dist.yml b/.github/workflows/ci-token-dist.yml deleted file mode 100644 index 864654227..000000000 --- a/.github/workflows/ci-token-dist.yml +++ /dev/null @@ -1,31 +0,0 @@ -name: CI - packages/token-distribution - -env: - CI: true - STUDIO_API_KEY: ${{ secrets.STUDIO_API_KEY }} - -on: - push: - branches: "*" - paths: - - packages/token-distribution/** - pull_request: - branches: "*" - paths: - - packages/token-distribution/** - workflow_dispatch: - -jobs: - test-ci: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v4 - - name: Set up environment - uses: ./.github/actions/setup - - name: Build - run: | - pushd packages/token-distribution - yarn build - - name: Run tests - run: yarn test \ No newline at end of file diff --git a/.github/workflows/ci-toolshed.yml b/.github/workflows/ci-toolshed.yml new file mode 100644 index 000000000..54c2cb747 --- /dev/null +++ b/.github/workflows/ci-toolshed.yml @@ -0,0 +1,46 @@ +name: CI - packages/toolshed + +env: + CI: true + +on: + push: + branches: '*' + paths: + - packages/toolshed/** + pull_request: + branches: '*' + paths: + - packages/toolshed/** + workflow_dispatch: + +jobs: + test-ci: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + submodules: recursive + - name: Set up environment + uses: ./.github/actions/setup + - name: Build contracts + run: | + pushd packages/contracts + pnpm build + popd + - name: Build horizon + run: | + pushd packages/horizon + pnpm build + popd + - name: Build subgraph service + run: | + pushd packages/subgraph-service + pnpm build + popd + - name: Build toolshed + run: | + pushd packages/toolshed + pnpm build + popd diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 000000000..db28bb954 --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,394 @@ +name: Lint + +# This workflow runs linting on files in the repository +# It can be configured to run on all files or just changed files +# It will fail the build if there are errors, but only report warnings + +env: + CI: true + +on: + pull_request: + branches: '*' + workflow_dispatch: + inputs: + lint_mode: + description: 'Linting mode' + required: true + default: 'changed' + type: choice + options: + - all + - changed + +jobs: + lint: + name: Lint Files + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 # Needed to get all history for comparing changes + + - name: Set up environment + uses: ./.github/actions/setup + + - name: Determine lint mode + id: lint_mode + run: | + # Default to 'changed' for push and PR events, but allow override via workflow_dispatch + if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then + LINT_MODE="${{ github.event.inputs.lint_mode }}" + else + LINT_MODE="changed" + fi + echo "mode=$LINT_MODE" >> $GITHUB_OUTPUT + echo "Lint mode: $LINT_MODE" + + - name: Get changed files + id: changed_files + if: steps.lint_mode.outputs.mode == 'changed' + run: | + if [ "${{ github.event_name }}" = "pull_request" ]; then + # For pull requests, compare with the base branch + BASE_SHA=${{ github.event.pull_request.base.sha }} + HEAD_SHA=${{ github.event.pull_request.head.sha }} + else + # For pushes, compare with the parent commit + BASE_SHA=$(git rev-parse HEAD^) + HEAD_SHA=$(git rev-parse HEAD) + fi + + echo "Base SHA: $BASE_SHA" + echo "Head SHA: $HEAD_SHA" + + # Get changed files, filtering out deleted files and files in ignored directories + CHANGED_TS_JS=$(git diff --name-only --diff-filter=d $BASE_SHA $HEAD_SHA | grep -E '\.(js|ts|jsx|tsx|cjs|mjs)$' | grep -v -E '(node_modules|dist|build|cache|reports|lib|coverage|artifacts|typechain|hardhat-cache|ignition/deployments|ignition/modules/artifacts)' || true) + CHANGED_SOL=$(git diff --name-only --diff-filter=d $BASE_SHA $HEAD_SHA | grep -E '\.sol$' | grep -v -E '(node_modules|dist|build|cache|reports|lib|coverage|artifacts|typechain|hardhat-cache|ignition/deployments|ignition/modules/artifacts)' || true) + CHANGED_MD=$(git diff --name-only --diff-filter=d $BASE_SHA $HEAD_SHA | grep -E '\.md$' | grep -v -E '(node_modules|dist|build|cache|reports|lib|coverage|artifacts|typechain|hardhat-cache|ignition/deployments|ignition/modules/artifacts)' || true) + CHANGED_JSON=$(git diff --name-only --diff-filter=d $BASE_SHA $HEAD_SHA | grep -E '\.json$' | grep -v -E '(node_modules|dist|build|cache|reports|lib|coverage|artifacts|typechain|hardhat-cache|ignition/deployments|ignition/modules/artifacts)' || true) + CHANGED_YAML=$(git diff --name-only --diff-filter=d $BASE_SHA $HEAD_SHA | grep -E '\.(yml|yaml)$' | grep -v -E '(node_modules|dist|build|cache|reports|lib|coverage|artifacts|typechain|hardhat-cache|ignition/deployments|ignition/modules/artifacts)' || true) + + # Save to files for later use + echo "$CHANGED_TS_JS" > changed_ts_js.txt + echo "$CHANGED_SOL" > changed_sol.txt + echo "$CHANGED_MD" > changed_md.txt + echo "$CHANGED_JSON" > changed_json.txt + echo "$CHANGED_YAML" > changed_yaml.txt + + # Count changed files + TS_JS_COUNT=$(echo "$CHANGED_TS_JS" | grep -v '^$' | wc -l) + SOL_COUNT=$(echo "$CHANGED_SOL" | grep -v '^$' | wc -l) + MD_COUNT=$(echo "$CHANGED_MD" | grep -v '^$' | wc -l) + JSON_COUNT=$(echo "$CHANGED_JSON" | grep -v '^$' | wc -l) + YAML_COUNT=$(echo "$CHANGED_YAML" | grep -v '^$' | wc -l) + TOTAL_COUNT=$((TS_JS_COUNT + SOL_COUNT + MD_COUNT + JSON_COUNT + YAML_COUNT)) + + echo "ts_js_count=$TS_JS_COUNT" >> $GITHUB_OUTPUT + echo "sol_count=$SOL_COUNT" >> $GITHUB_OUTPUT + echo "md_count=$MD_COUNT" >> $GITHUB_OUTPUT + echo "json_count=$JSON_COUNT" >> $GITHUB_OUTPUT + echo "yaml_count=$YAML_COUNT" >> $GITHUB_OUTPUT + echo "total_count=$TOTAL_COUNT" >> $GITHUB_OUTPUT + + echo "Found $TOTAL_COUNT changed files to lint:" + echo "- TypeScript/JavaScript: $TS_JS_COUNT" + echo "- Solidity: $SOL_COUNT" + echo "- Markdown: $MD_COUNT" + echo "- JSON: $JSON_COUNT" + echo "- YAML: $YAML_COUNT" + + - name: Lint TypeScript/JavaScript files (ESLint) + id: lint_ts_eslint + continue-on-error: true + run: | + if [ "${{ steps.lint_mode.outputs.mode }}" = "all" ]; then + echo "Running ESLint on all TypeScript/JavaScript files..." + npx eslint --max-warnings=0 '**/*.{js,ts,cjs,mjs,jsx,tsx}' + echo "ts_eslint_exit_code=$?" >> $GITHUB_OUTPUT + elif [ "${{ steps.changed_files.outputs.ts_js_count }}" -gt "0" ]; then + echo "Running ESLint on changed TypeScript/JavaScript files..." + cat changed_ts_js.txt | xargs npx eslint --max-warnings=0 + echo "ts_eslint_exit_code=$?" >> $GITHUB_OUTPUT + else + echo "No TypeScript/JavaScript files to lint with ESLint." + echo "ts_eslint_exit_code=0" >> $GITHUB_OUTPUT + fi + + - name: Lint TypeScript/JavaScript files (Prettier) + id: lint_ts_prettier + continue-on-error: true + run: | + if [ "${{ steps.lint_mode.outputs.mode }}" = "all" ]; then + echo "Checking all TypeScript/JavaScript files with Prettier..." + npx prettier --check --cache --log-level warn '**/*.{js,ts,cjs,mjs,jsx,tsx}' + echo "ts_prettier_exit_code=$?" >> $GITHUB_OUTPUT + elif [ "${{ steps.changed_files.outputs.ts_js_count }}" -gt "0" ]; then + echo "Checking changed TypeScript/JavaScript files with Prettier..." + cat changed_ts_js.txt | xargs npx prettier --check --cache --log-level warn + echo "ts_prettier_exit_code=$?" >> $GITHUB_OUTPUT + else + echo "No TypeScript/JavaScript files to check with Prettier." + echo "ts_prettier_exit_code=0" >> $GITHUB_OUTPUT + fi + + - name: Lint Solidity files (Solhint) + id: lint_sol_solhint + continue-on-error: true + run: | + if [ "${{ steps.lint_mode.outputs.mode }}" = "all" ]; then + echo "Running Solhint on all Solidity files..." + npx solhint --max-warnings=0 --noPrompt --noPoster 'packages/*/contracts/**/*.sol' + echo "sol_solhint_exit_code=$?" >> $GITHUB_OUTPUT + elif [ "${{ steps.changed_files.outputs.sol_count }}" -gt "0" ]; then + echo "Running Solhint on changed Solidity files..." + cat changed_sol.txt | xargs npx solhint --max-warnings=0 --noPrompt --noPoster + echo "sol_solhint_exit_code=$?" >> $GITHUB_OUTPUT + else + echo "No Solidity files to lint with Solhint." + echo "sol_solhint_exit_code=0" >> $GITHUB_OUTPUT + fi + + - name: Lint Solidity files (Prettier) + id: lint_sol_prettier + continue-on-error: true + run: | + if [ "${{ steps.lint_mode.outputs.mode }}" = "all" ]; then + echo "Checking all Solidity files with Prettier..." + npx prettier --check --cache --log-level warn '**/*.sol' + echo "sol_prettier_exit_code=$?" >> $GITHUB_OUTPUT + elif [ "${{ steps.changed_files.outputs.sol_count }}" -gt "0" ]; then + echo "Checking changed Solidity files with Prettier..." + cat changed_sol.txt | xargs npx prettier --check --cache --log-level warn + echo "sol_prettier_exit_code=$?" >> $GITHUB_OUTPUT + else + echo "No Solidity files to check with Prettier." + 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 + run: | + if [ "${{ steps.lint_mode.outputs.mode }}" = "all" ]; then + echo "Running Markdownlint on all Markdown files..." + npx markdownlint --ignore-path .gitignore --ignore-path .markdownlintignore '**/*.md' + echo "md_markdownlint_exit_code=$?" >> $GITHUB_OUTPUT + elif [ "${{ steps.changed_files.outputs.md_count }}" -gt "0" ]; then + echo "Running Markdownlint on changed Markdown files..." + cat changed_md.txt | xargs npx markdownlint --ignore-path .gitignore --ignore-path .markdownlintignore + echo "md_markdownlint_exit_code=$?" >> $GITHUB_OUTPUT + else + echo "No Markdown files to lint with Markdownlint." + echo "md_markdownlint_exit_code=0" >> $GITHUB_OUTPUT + fi + + - name: Lint Markdown files (Prettier) + id: lint_md_prettier + continue-on-error: true + run: | + if [ "${{ steps.lint_mode.outputs.mode }}" = "all" ]; then + echo "Checking all Markdown files with Prettier..." + npx prettier --check --cache --log-level warn '**/*.md' + echo "md_prettier_exit_code=$?" >> $GITHUB_OUTPUT + elif [ "${{ steps.changed_files.outputs.md_count }}" -gt "0" ]; then + echo "Checking changed Markdown files with Prettier..." + cat changed_md.txt | xargs npx prettier --check --cache --log-level warn + echo "md_prettier_exit_code=$?" >> $GITHUB_OUTPUT + else + echo "No Markdown files to check with Prettier." + echo "md_prettier_exit_code=0" >> $GITHUB_OUTPUT + fi + + - name: Lint JSON files (Prettier) + id: lint_json_prettier + continue-on-error: true + run: | + if [ "${{ steps.lint_mode.outputs.mode }}" = "all" ]; then + echo "Checking all JSON files with Prettier..." + npx prettier --check --cache --log-level warn '**/*.json' + echo "json_prettier_exit_code=$?" >> $GITHUB_OUTPUT + elif [ "${{ steps.changed_files.outputs.json_count }}" -gt "0" ]; then + echo "Checking changed JSON files with Prettier..." + cat changed_json.txt | xargs npx prettier --check --cache --log-level warn + echo "json_prettier_exit_code=$?" >> $GITHUB_OUTPUT + else + echo "No JSON files to check with Prettier." + echo "json_prettier_exit_code=0" >> $GITHUB_OUTPUT + fi + + - name: Lint YAML files (yaml-lint) + id: lint_yaml_yamllint + continue-on-error: true + run: | + if [ "${{ steps.lint_mode.outputs.mode }}" = "all" ]; then + echo "Running yaml-lint on all YAML files..." + npx yaml-lint .github/**/*.{yml,yaml} + echo "yaml_yamllint_exit_code=$?" >> $GITHUB_OUTPUT + elif [ "${{ steps.changed_files.outputs.yaml_count }}" -gt "0" ]; then + echo "Running yaml-lint on changed YAML files..." + cat changed_yaml.txt | xargs npx yaml-lint + echo "yaml_yamllint_exit_code=$?" >> $GITHUB_OUTPUT + else + echo "No YAML files to lint with yaml-lint." + echo "yaml_yamllint_exit_code=0" >> $GITHUB_OUTPUT + fi + + - name: Lint YAML files (Prettier) + id: lint_yaml_prettier + continue-on-error: true + run: | + if [ "${{ steps.lint_mode.outputs.mode }}" = "all" ]; then + echo "Checking all YAML files with Prettier..." + npx prettier --check --cache --log-level warn '**/*.{yml,yaml}' + echo "yaml_prettier_exit_code=$?" >> $GITHUB_OUTPUT + elif [ "${{ steps.changed_files.outputs.yaml_count }}" -gt "0" ]; then + echo "Checking changed YAML files with Prettier..." + cat changed_yaml.txt | xargs npx prettier --check --cache --log-level warn + echo "yaml_prettier_exit_code=$?" >> $GITHUB_OUTPUT + else + echo "No YAML files to check with Prettier." + echo "yaml_prettier_exit_code=0" >> $GITHUB_OUTPUT + fi + + - name: Determine overall status + id: status + run: | + # Collect all exit codes + TS_ESLINT_EXIT_CODE="${{ steps.lint_ts_eslint.outputs.ts_eslint_exit_code }}" + TS_PRETTIER_EXIT_CODE="${{ steps.lint_ts_prettier.outputs.ts_prettier_exit_code }}" + SOL_SOLHINT_EXIT_CODE="${{ steps.lint_sol_solhint.outputs.sol_solhint_exit_code }}" + SOL_PRETTIER_EXIT_CODE="${{ steps.lint_sol_prettier.outputs.sol_prettier_exit_code }}" + SOL_NATSPEC_EXIT_CODE="${{ steps.lint_sol_natspec.outputs.sol_natspec_exit_code }}" + MD_MARKDOWNLINT_EXIT_CODE="${{ steps.lint_md_markdownlint.outputs.md_markdownlint_exit_code }}" + MD_PRETTIER_EXIT_CODE="${{ steps.lint_md_prettier.outputs.md_prettier_exit_code }}" + JSON_PRETTIER_EXIT_CODE="${{ steps.lint_json_prettier.outputs.json_prettier_exit_code }}" + YAML_YAMLLINT_EXIT_CODE="${{ steps.lint_yaml_yamllint.outputs.yaml_yamllint_exit_code }}" + YAML_PRETTIER_EXIT_CODE="${{ steps.lint_yaml_prettier.outputs.yaml_prettier_exit_code }}" + + # Initialize counters + ERRORS=0 + WARNINGS=0 + + # Check each exit code + # Exit code 1 typically indicates errors + # Exit code 2 or higher might indicate warnings or other issues + + # TypeScript/JavaScript - ESLint + if [ "$TS_ESLINT_EXIT_CODE" = "1" ]; then + echo "::error::ESLint found errors in TypeScript/JavaScript files" + ERRORS=$((ERRORS+1)) + elif [ "$TS_ESLINT_EXIT_CODE" != "0" ]; then + echo "::warning::ESLint found warnings in TypeScript/JavaScript files" + WARNINGS=$((WARNINGS+1)) + fi + + # TypeScript/JavaScript - Prettier + if [ "$TS_PRETTIER_EXIT_CODE" = "1" ]; then + echo "::error::Prettier found formatting issues in TypeScript/JavaScript files" + ERRORS=$((ERRORS+1)) + elif [ "$TS_PRETTIER_EXIT_CODE" != "0" ]; then + echo "::warning::Prettier found warnings in TypeScript/JavaScript files" + WARNINGS=$((WARNINGS+1)) + fi + + # Solidity - Solhint + if [ "$SOL_SOLHINT_EXIT_CODE" = "1" ]; then + echo "::error::Solhint found errors in Solidity files" + ERRORS=$((ERRORS+1)) + elif [ "$SOL_SOLHINT_EXIT_CODE" != "0" ]; then + echo "::warning::Solhint found warnings in Solidity files" + WARNINGS=$((WARNINGS+1)) + fi + + # Solidity - Prettier + if [ "$SOL_PRETTIER_EXIT_CODE" = "1" ]; then + echo "::error::Prettier found formatting issues in Solidity files" + ERRORS=$((ERRORS+1)) + elif [ "$SOL_PRETTIER_EXIT_CODE" != "0" ]; then + echo "::warning::Prettier found warnings in Solidity files" + 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" + ERRORS=$((ERRORS+1)) + elif [ "$MD_MARKDOWNLINT_EXIT_CODE" != "0" ]; then + echo "::warning::Markdownlint found warnings in Markdown files" + WARNINGS=$((WARNINGS+1)) + fi + + # Markdown - Prettier + if [ "$MD_PRETTIER_EXIT_CODE" = "1" ]; then + echo "::error::Prettier found formatting issues in Markdown files" + ERRORS=$((ERRORS+1)) + elif [ "$MD_PRETTIER_EXIT_CODE" != "0" ]; then + echo "::warning::Prettier found warnings in Markdown files" + WARNINGS=$((WARNINGS+1)) + fi + + # JSON - Prettier + if [ "$JSON_PRETTIER_EXIT_CODE" = "1" ]; then + echo "::error::Prettier found formatting issues in JSON files" + ERRORS=$((ERRORS+1)) + elif [ "$JSON_PRETTIER_EXIT_CODE" != "0" ]; then + echo "::warning::Prettier found warnings in JSON files" + WARNINGS=$((WARNINGS+1)) + fi + + # YAML - yaml-lint + if [ "$YAML_YAMLLINT_EXIT_CODE" = "1" ]; then + echo "::error::yaml-lint found errors in YAML files" + ERRORS=$((ERRORS+1)) + elif [ "$YAML_YAMLLINT_EXIT_CODE" != "0" ]; then + echo "::warning::yaml-lint found warnings in YAML files" + WARNINGS=$((WARNINGS+1)) + fi + + # YAML - Prettier + if [ "$YAML_PRETTIER_EXIT_CODE" = "1" ]; then + echo "::error::Prettier found formatting issues in YAML files" + ERRORS=$((ERRORS+1)) + elif [ "$YAML_PRETTIER_EXIT_CODE" != "0" ]; then + echo "::warning::Prettier found warnings in YAML files" + WARNINGS=$((WARNINGS+1)) + fi + + # Create summary + LINT_MODE="${{ steps.lint_mode.outputs.mode }}" + if [ "$ERRORS" -gt 0 ]; then + echo "summary=❌ Linting ($LINT_MODE files) failed with $ERRORS error types and $WARNINGS warning types." >> $GITHUB_OUTPUT + echo "Linting failed with errors. CI build will fail." + exit 1 + elif [ "$WARNINGS" -gt 0 ]; then + echo "summary=⚠️ Linting ($LINT_MODE files) passed with $WARNINGS warning types. CI build will continue." >> $GITHUB_OUTPUT + echo "Linting found warnings but no errors. CI build will continue." + exit 0 + else + echo "summary=✅ All linters ($LINT_MODE files) passed successfully with no errors or warnings." >> $GITHUB_OUTPUT + echo "All linters passed successfully." + exit 0 + fi + + - name: Post Summary + run: echo "${{ steps.status.outputs.summary }}" >> $GITHUB_STEP_SUMMARY diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index dc01211d7..ea8d80315 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -8,8 +8,8 @@ on: required: true type: choice options: - - contracts - - sdk + - contracts + - sdk tag: description: 'Tag to publish' required: true @@ -23,12 +23,14 @@ jobs: steps: - name: Checkout uses: actions/checkout@v4 + with: + submodules: recursive - name: Set up environment uses: ./.github/actions/setup + - name: Set npm token for publishing + run: pnpm config set //registry.npmjs.org/:_authToken ${{ secrets.GRAPHPROTOCOL_NPM_TOKEN }} - name: Publish 🚀 shell: bash run: | pushd packages/${{ inputs.package }} - yarn npm publish --tag ${{ inputs.tag }} --access public - env: - YARN_NPM_AUTH_TOKEN: ${{ secrets.GRAPHPROTOCOL_NPM_TOKEN }} \ No newline at end of file + pnpm publish --tag ${{ inputs.tag }} --access public --no-git-checks diff --git a/.github/workflows/verifydeployed.yml b/.github/workflows/verifydeployed.yml index 1f5d848d8..ba682fc21 100644 --- a/.github/workflows/verifydeployed.yml +++ b/.github/workflows/verifydeployed.yml @@ -13,10 +13,10 @@ on: type: choice default: mainnet options: - - mainnet - - arbitrum-one - - goerli - - arbitrum-goerli + - mainnet + - arbitrum-one + - goerli + - arbitrum-goerli jobs: build: @@ -25,22 +25,24 @@ jobs: steps: - name: Checkout uses: actions/checkout@v3 + with: + submodules: recursive - name: Set up environment uses: ./.github/actions/setup - name: Build run: | pushd packages/contracts - yarn build || yarn build + pnpm build - name: Save build artifacts uses: actions/upload-artifact@v3 with: name: contract-artifacts path: | - packages/contracts/build + packages/contracts/artifacts packages/contracts/cache/*.json - + verify: name: Verify deployments runs-on: ubuntu-latest @@ -53,16 +55,16 @@ jobs: - name: Build run: | pushd packages/contracts - yarn build || yarn build + pnpm build || pnpm build - name: Get build artifacts uses: actions/download-artifact@v3 with: name: contract-artifacts - name: Verify contracts on Defender - run: cd packages/contracts && yarn hardhat --network ${{ inputs.network }} verify-defender ${{ inputs.contracts }} + run: cd packages/contracts && pnpm hardhat --network ${{ inputs.network }} verify-defender ${{ inputs.contracts }} env: - DEFENDER_API_KEY: "${{ secrets.DEFENDER_API_KEY }}" - DEFENDER_API_SECRET: "${{ secrets.DEFENDER_API_SECRET }}" - INFURA_KEY: "${{ secrets.INFURA_KEY }}" - WORKFLOW_URL: "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" + DEFENDER_API_KEY: '${{ secrets.DEFENDER_API_KEY }}' + DEFENDER_API_SECRET: '${{ secrets.DEFENDER_API_SECRET }}' + INFURA_KEY: '${{ secrets.INFURA_KEY }}' + WORKFLOW_URL: '${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}' diff --git a/.gitignore b/.gitignore index ecd5f0d2c..53ff30156 100644 --- a/.gitignore +++ b/.gitignore @@ -1,15 +1,18 @@ # Logs yarn-debug.log* yarn-error.log* +node.log # Dependency directories node_modules/ +forge-std/ +**/lib/forge-std/ # Yarn -.yarn/ +.yarn/* !.yarn/patches -!.yarn/releases !.yarn/plugins +!.yarn/releases !.yarn/sdks !.yarn/versions @@ -17,12 +20,23 @@ node_modules/ artifacts/ cache/ cached/ +cache + +# ESLint cache +.eslintcache +packages/*/.eslintcache # Build artifacts dist/ build/ +typechain/ +typechain-types/ +types/ deployments/hardhat/ +# TypeScript incremental compilation cache +**/tsconfig.tsbuildinfo + # Ignore solc bin output bin/ @@ -32,21 +46,41 @@ bin/ .vscode # Coverage and other reports +coverage/ reports/ coverage.json +lcov.info +hardhat-dependency-compiler/ # Local test files -addresses-local.json localNetwork.json arbitrum-addresses-local.json -tx-*.log addresses-fork.json +addresses-hardhat.json +addresses-local*.json # Keys .keystore +# Forge artifacts +cache_forge +forge-artifacts/ +out/ +packages/issuance/lib/forge-std/ + # Graph client .graphclient +# Tx builder and logger +tx-*.log tx-builder-*.json -!tx-builder-template.json \ No newline at end of file +!tx-builder-template.json + +# Hardhat Ignition +**/chain-31337/ +**/chain-1337/ +**/horizon-localhost/ +**/horizon-hardhat/ +**/subgraph-service-localhost/ +**/subgraph-service-hardhat/ +!**/ignition/**/artifacts/ diff --git a/.husky/commit-msg b/.husky/commit-msg index fe4c17a22..dab272daf 100755 --- a/.husky/commit-msg +++ b/.husky/commit-msg @@ -1,4 +1 @@ -#!/bin/sh -. "$(dirname "$0")/_/husky.sh" - npx --no-install commitlint --edit "" diff --git a/.husky/pre-commit b/.husky/pre-commit index 487427eda..083cf3f3c 100755 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -1,12 +1,3 @@ #!/usr/bin/env sh -. "$(dirname -- "$0")/_/husky.sh" -# contracts -pushd packages/contracts -npx --no-install lint-staged -popd - -# data-edge -pushd packages/data-edge -npx --no-install lint-staged -popd \ No newline at end of file +npx lint-staged diff --git a/.markdownlint.json b/.markdownlint.json new file mode 100644 index 000000000..5b37d3bd4 --- /dev/null +++ b/.markdownlint.json @@ -0,0 +1,9 @@ +{ + "default": true, + "MD013": false, + "MD024": { "siblings_only": true }, + "MD033": false, + "MD029": { "style": "ordered" }, + "MD007": { "indent": 2 }, + "MD004": { "style": "dash" } +} diff --git a/.markdownlintignore b/.markdownlintignore new file mode 100644 index 000000000..d1a8b4f6e --- /dev/null +++ b/.markdownlintignore @@ -0,0 +1,38 @@ +# Dependencies +node_modules/ + +# Third-party libraries in lib directories +**/lib/ + +# Build outputs +**/build/ +**/dist/ +**/artifacts/ +**/typechain-types/ +**/types/ +**/cache/ +**/cached/ +cache +typechain/ +bin/ +forge-artifacts/ +out/ + +# Coverage and reports +coverage/ +reports/ +coverage.json +lcov.info +.nyc_output/ + +# Other generated files +.eslintcache +packages/*/.eslintcache +deployments/hardhat/ +.graphclient +**/chain-31337/ +**/chain-1377/ +**/horizon-localhost/ +**/horizon-hardhat/ +**/subgraph-service-localhost/ +**/subgraph-service-hardhat/ diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 000000000..a4c074c62 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,43 @@ +# Lock files (auto-generated, should not be formatted) +pnpm-lock.yaml +package-lock.json +yarn.lock + +# Dependencies (from .gitignore) +node_modules/ + +# Third-party libraries in lib directories +**/lib/ + +# Build outputs (from .gitignore) +**/build/ +**/dist/ +**/artifacts/ +**/typechain-types/ +**/types/ +**/cache/ +**/cached/ +cache +typechain/ +bin/ +forge-artifacts/ +out/ + +# Coverage and reports (from .gitignore) +coverage/ +reports/ +coverage.json +lcov.info +.nyc_output/ + +# Other generated files (from .gitignore) +.eslintcache +packages/*/.eslintcache +deployments/hardhat/ +.graphclient +**/chain-31337/ +**/chain-1377/ +**/horizon-localhost/ +**/horizon-hardhat/ +**/subgraph-service-localhost/ +**/subgraph-service-hardhat/ diff --git a/.solhint.json b/.solhint.json new file mode 100644 index 000000000..ab0553207 --- /dev/null +++ b/.solhint.json @@ -0,0 +1,21 @@ +{ + "extends": "solhint:recommended", + "plugins": ["graph"], + "rules": { + "func-visibility": ["warn", { "ignoreConstructors": true }], + "compiler-version": ["off"], + "constructor-syntax": "warn", + "quotes": ["error", "double"], + "reason-string": ["off"], + "not-rely-on-time": "off", + "no-empty-blocks": "off", + "named-parameters-mapping": "warn", + "private-vars-leading-underscore": "off", + "graph/leading-underscore": "warn", + "func-name-mixedcase": "off", + "graph/func-name-mixedcase": "warn", + "var-name-mixedcase": "off", + "graph/var-name-mixedcase": "warn", + "gas-custom-errors": "off" + } +} diff --git a/.yamllint b/.yamllint new file mode 100644 index 000000000..b41cd8a3b --- /dev/null +++ b/.yamllint @@ -0,0 +1,37 @@ +--- +extends: default + +rules: + line-length: + max: 120 + level: warning + indentation: + spaces: 2 + indent-sequences: true + truthy: + allowed-values: ['true', 'false', 'yes', 'no'] + document-start: + present: true + document-end: + present: false + comments: + min-spaces-from-content: 1 + braces: + min-spaces-inside: 0 + max-spaces-inside: 1 + brackets: + min-spaces-inside: 0 + max-spaces-inside: 1 + commas: + max-spaces-before: 0 + min-spaces-after: 1 + max-spaces-after: 1 + +ignore: | + node_modules/ + dist/ + build/ + cache/ + coverage/ + .yarn/ + packages/ diff --git a/.yarnrc.yml b/.yarnrc.yml deleted file mode 100644 index 11969f789..000000000 --- a/.yarnrc.yml +++ /dev/null @@ -1,2 +0,0 @@ -nodeLinker: node-modules -nmHoistingLimits: workspaces \ No newline at end of file diff --git a/README.md b/README.md index dc813abb8..3ab0ce44b 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ + +