diff --git a/.changeset/drop-node-20.md b/.changeset/drop-node-20.md new file mode 100644 index 000000000..9192b722f --- /dev/null +++ b/.changeset/drop-node-20.md @@ -0,0 +1,7 @@ +--- +'@graphprotocol/graph-cli': minor +--- + +Drop support for Node.js 20 (end-of-life 2026-04-30). The minimum supported +Node.js version is now 22.11.0 (Node 22 LTS). CI now tests on Node 22 and 24; +released binaries continue to be built on Node 24. diff --git a/.github/actions/setup-node/action.yml b/.github/actions/setup-node/action.yml index ffcf33d9a..1b9fe3d0c 100644 --- a/.github/actions/setup-node/action.yml +++ b/.github/actions/setup-node/action.yml @@ -7,7 +7,7 @@ inputs: nodeVersion: description: Node.js version to use required: true - default: '20' + default: '22' workingDirectory: description: Working directory required: false @@ -24,12 +24,6 @@ inputs: runs: using: composite steps: - - name: Cancel Previous Runs - uses: styfle/cancel-workflow-action@0.12.1 - continue-on-error: true - with: - access_token: ${{ github.token }} - - name: check pnpm version shell: bash id: pnpm @@ -50,7 +44,7 @@ runs: - name: Setup ${{ inputs.packageManager }} id: pnpm_setup if: inputs.packageManager == 'pnpm' - uses: pnpm/action-setup@v4.2.0 + uses: pnpm/action-setup@v6 with: version: ${{ steps.pnpm.outputs.version }} run_install: false diff --git a/.github/workflows/changeset-deps.yml b/.github/workflows/changeset-deps.yml new file mode 100644 index 000000000..8f82ea04c --- /dev/null +++ b/.github/workflows/changeset-deps.yml @@ -0,0 +1,32 @@ +name: Auto changesets for dep updates +on: + pull_request: + branches: + - main + +permissions: + contents: write + pull-requests: write + +concurrency: + group: changeset-deps-${{ github.event.pull_request.number }} + cancel-in-progress: true + +jobs: + changeset: + name: Add changeset for dep bump + if: | + github.event.pull_request.head.repo.full_name == github.repository && + github.event.pull_request.user.login == 'renovate[bot]' + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v5 + with: + ref: ${{ github.event.pull_request.head.ref }} + fetch-depth: 0 + + - name: Add changeset + uses: mscharley/dependency-changesets-action@v1.2.4 + with: + token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1f7c21d7e..6f771a09d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,6 +7,10 @@ on: - 'main' pull_request: +concurrency: + group: tests-${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ github.ref != 'refs/heads/main' }} + jobs: lint: name: Lint @@ -20,7 +24,7 @@ jobs: - uses: ./.github/actions/setup-node name: Setup Env with: - nodeVersion: 20 + nodeVersion: 22 packageManager: pnpm packageManagerVersion: 9 @@ -34,7 +38,7 @@ jobs: strategy: fail-fast: false matrix: - node-version: [20, 22] + node-version: [22, 24] steps: - name: Checkout Repository uses: actions/checkout@v5 @@ -76,7 +80,7 @@ jobs: - uses: ./.github/actions/setup-node name: Setup Env with: - nodeVersion: 20 + nodeVersion: 22 packageManager: pnpm packageManagerVersion: 9 @@ -106,7 +110,7 @@ jobs: - uses: ./.github/actions/setup-node name: Setup Env with: - nodeVersion: 20 + nodeVersion: 22 packageManager: pnpm packageManagerVersion: 9 diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml deleted file mode 100644 index 1f359f9f0..000000000 --- a/.github/workflows/pr.yml +++ /dev/null @@ -1,46 +0,0 @@ -name: Snapshot Release -on: - pull_request: - branches: - - main - -permissions: write-all - -jobs: - dependencies: - uses: ./.github/workflows/shared-changesets-dependencies.yml - with: - gitUserEmail: ops@pinax.network - gitUserName: pinax-bot - if: ${{ github.event.pull_request.title != 'Upcoming Release Changes' }} - secrets: - githubToken: ${{ secrets.PINAX_BOT_GITHUB_TOKEN }} - pgpPrivateKey: ${{ secrets.PINAX_BOT_PGP_PRIVATE_KEY }} - pgpPassphrase: ${{ secrets.PINAX_BOT_PGP_PASSPHRASE }} - - alpha: - uses: ./.github/workflows/shared-release-snapshot.yml - if: ${{ github.event.pull_request.title != 'Upcoming Release Changes' }} - with: - npmTag: alpha - buildScript: build - nodeVersion: 20 - packageManager: pnpm - packageManagerVersion: 9 - secrets: - githubToken: ${{ secrets.GITHUB_TOKEN }} - npmToken: ${{ secrets.NPM_TOKEN }} - - release-candidate: - uses: ./.github/workflows/shared-release-snapshot.yml - if: ${{ github.event.pull_request.title == 'Upcoming Release Changes' }} - with: - npmTag: rc - buildScript: build - nodeVersion: 20 - packageManager: pnpm - packageManagerVersion: 9 - restoreDeletedChangesets: true - secrets: - githubToken: ${{ secrets.GITHUB_TOKEN }} - npmToken: ${{ secrets.NPM_TOKEN }} diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 000000000..34713d2c8 --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,135 @@ +name: Publish +on: + push: + branches: + - main + pull_request: + branches: + - main + +permissions: + contents: read + +env: + RELEASE_COMMIT_MSG: 'chore(release): update monorepo packages versions' + +jobs: + stable: + name: Stable + if: github.event_name == 'push' + runs-on: ubuntu-latest + concurrency: + group: publish-stable + cancel-in-progress: false + permissions: + contents: write + pull-requests: write + id-token: write + steps: + - name: Checkout + uses: actions/checkout@v5 + with: + fetch-depth: 0 + + - name: Setup environment + uses: ./.github/actions/setup-node + with: + nodeVersion: 24 + packageManager: pnpm + packageManagerVersion: 9 + + - name: Build + if: ${{ startsWith(github.event.head_commit.message, env.RELEASE_COMMIT_MSG) }} + run: pnpm --filter=@graphprotocol/graph-cli build + + - name: Pack binaries + if: ${{ startsWith(github.event.head_commit.message, env.RELEASE_COMMIT_MSG) }} + run: pnpm --filter=@graphprotocol/graph-cli oclif:pack + + - name: Create Release PR or Publish + id: changesets + uses: changesets/action@v1 + with: + publish: pnpm release + version: pnpm changeset version + commit: ${{ env.RELEASE_COMMIT_MSG }} + title: Upcoming Release Changes + createGithubReleases: true + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + NPM_CONFIG_PROVENANCE: 'true' + + - name: Attach oclif binaries to GitHub Release + if: steps.changesets.outputs.published == 'true' + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + PUBLISHED: ${{ steps.changesets.outputs.publishedPackages }} + run: | + tag=$(jq -r '.[] | select(.name == "@graphprotocol/graph-cli") | "\(.name)@\(.version)"' <<< "$PUBLISHED") + if [ -n "$tag" ]; then + gh release upload "$tag" packages/cli/dist/*.tar.gz --clobber + fi + + snapshot: + name: Snapshot + if: | + github.event_name == 'pull_request' && + github.event.pull_request.head.repo.full_name == github.repository + runs-on: ubuntu-latest + concurrency: + group: publish-snapshot-${{ github.event.pull_request.number }} + cancel-in-progress: true + permissions: + contents: read + pull-requests: write + id-token: write + steps: + - name: Checkout + uses: actions/checkout@v5 + with: + fetch-depth: 0 + ref: ${{ github.event.pull_request.head.sha }} + + - name: Setup environment + uses: ./.github/actions/setup-node + with: + nodeVersion: 24 + packageManager: pnpm + packageManagerVersion: 9 + + - name: Determine snapshot tag + id: tag + run: | + if [ "${{ github.event.pull_request.title }}" = "Upcoming Release Changes" ]; then + echo "tag=rc" >> "$GITHUB_OUTPUT" + # rc snapshots are taken from the Version PR — restore deleted changesets + git checkout HEAD~1 -- .changeset + else + echo "tag=alpha" >> "$GITHUB_OUTPUT" + fi + + - name: Check for changesets + id: has_changesets + run: | + if ls .changeset/*.md 2>/dev/null | grep -v README | grep -q .; then + echo "has=true" >> "$GITHUB_OUTPUT" + else + echo "has=false" >> "$GITHUB_OUTPUT" + fi + + - name: Build + if: steps.has_changesets.outputs.has == 'true' + run: pnpm build + + - name: Snapshot version + if: steps.has_changesets.outputs.has == 'true' + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: pnpm changeset version --snapshot ${{ steps.tag.outputs.tag }} + + - name: Publish snapshot + if: steps.has_changesets.outputs.has == 'true' + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + NPM_CONFIG_PROVENANCE: 'true' + run: pnpm changeset publish --tag ${{ steps.tag.outputs.tag }} --no-git-tag diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml deleted file mode 100644 index 26948f5cc..000000000 --- a/.github/workflows/release.yml +++ /dev/null @@ -1,65 +0,0 @@ -name: Release -on: - push: - branches: - - main - -permissions: write-all - -env: - RELEASE_COMMIT_MSG: 'chore(release): update monorepo packages versions' - -jobs: - stable: - name: Stable - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v5 - with: - fetch-depth: 0 - token: ${{ github.token }} - - name: Setup environment - uses: ./.github/actions/setup-node - with: - nodeVersion: 20 - packageManager: pnpm - packageManagerVersion: 9 - - - name: Import bot's GPG key for signing commits - id: import-gpg - uses: crazy-max/ghaction-import-gpg@v6 - with: - gpg_private_key: ${{ secrets.PINAX_BOT_PGP_PRIVATE_KEY }} - passphrase: ${{ secrets.PINAX_BOT_PGP_PASSPHRASE }} - git_committer_name: pinax-bot - git_committer_email: ops@pinax.network - git_config_global: true - git_user_signingkey: true - git_commit_gpgsign: true - - - name: Set variables - id: vars - run: | - echo "sha_short=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT - echo "date=$(date +"%B %d, %Y")" >> $GITHUB_OUTPUT - - name: Build - if: ${{ startsWith(github.event.head_commit.message, env.RELEASE_COMMIT_MSG) }} - run: pnpm --filter=@graphprotocol/graph-cli build - - name: Pack binaries - if: ${{ startsWith(github.event.head_commit.message, env.RELEASE_COMMIT_MSG) }} - run: pnpm --filter=@graphprotocol/graph-cli oclif:pack - - name: Release / pull_request - uses: pinax-network/changesets-release-action@v1.5.2 - with: - publish: pnpm release - version: pnpm changeset version - commit: ${{ env.RELEASE_COMMIT_MSG }} - title: Upcoming Release Changes - createGithubReleases: true - setupGitUser: false - githubReleaseName: ${{ steps.vars.outputs.date }} - githubReleaseAssets: packages/cli/dist/*.tar.gz - env: - NPM_TOKEN: ${{ secrets.NPM_TOKEN }} - GITHUB_TOKEN: ${{ secrets.PINAX_BOT_GITHUB_TOKEN }} diff --git a/.github/workflows/shared-changesets-dependencies.yml b/.github/workflows/shared-changesets-dependencies.yml deleted file mode 100644 index 349694200..000000000 --- a/.github/workflows/shared-changesets-dependencies.yml +++ /dev/null @@ -1,78 +0,0 @@ -# Note: this is a shared pipeline used by other repositories. -# Docs: https://docs.github.com/en/actions/using-workflows/reusing-workflows - -on: - workflow_call: - inputs: - installDependencies: - type: boolean - default: false - preCommit: - type: string - required: false - packageManager: - type: string - required: false - default: yarn - packageManagerVersion: - type: string - description: Package manager version - required: false - default: '' - nodeVersion: - required: false - type: string - default: '20' - gitUserEmail: - required: false - type: string - default: '' - gitUserName: - required: false - type: string - default: '' - secrets: - githubToken: - required: true - pgpPrivateKey: - required: true - pgpPassphrase: - required: true - -jobs: - changeset: - runs-on: ubuntu-24.04 - if: github.event.pull_request.head.repo.full_name == github.repository - steps: - - name: Checkout - uses: actions/checkout@v5 - with: - fetch-depth: 0 - token: ${{ github.token }} - - - name: Import bot's GPG key for signing commits - id: import-gpg - uses: crazy-max/ghaction-import-gpg@v6 - with: - gpg_private_key: ${{ secrets.pgpPrivateKey }} - passphrase: ${{ secrets.pgpPassphrase }} - git_config_global: true - git_user_signingkey: true - git_commit_gpgsign: true - - - uses: ./.github/actions/setup-node - name: setup env and install dependencies - if: ${{ inputs.installDependencies }} - with: - nodeVersion: ${{ inputs.nodeVersion }} - packageManager: ${{ inputs.packageManager }} - packageManagerVersion: ${{ inputs.packageManagerVersion }} - - - name: Create/Update Changesets - uses: pinax-network/changesets-dependencies-action@v1.3.0 - with: - preCommit: ${{ inputs.preCommit }} - gitUserEmail: ${{ inputs.gitUserEmail }} - gitUserName: ${{ inputs.gitUserName }} - env: - GITHUB_TOKEN: ${{ secrets.githubToken }} diff --git a/.github/workflows/shared-release-snapshot.yml b/.github/workflows/shared-release-snapshot.yml deleted file mode 100644 index 510581a12..000000000 --- a/.github/workflows/shared-release-snapshot.yml +++ /dev/null @@ -1,89 +0,0 @@ -# Note: this is a shared pipeline used by other repositories. -# Docs: https://docs.github.com/en/actions/using-workflows/reusing-workflows - -on: - workflow_call: - inputs: - packageManager: - type: string - required: false - default: yarn - packageManagerVersion: - description: Package manager version - type: string - required: false - default: '' - nodeVersion: - required: false - type: string - default: '20' - buildScript: - required: false - type: string - default: build - npmTag: - required: false - type: string - default: npmTag - exitPre: - required: false - type: boolean - default: false - restoreDeletedChangesets: - required: false - type: boolean - default: false - secrets: - githubToken: - required: true - npmToken: - required: true - outputs: - published: - description: A boolean value to indicate whether a publishing is happened or not - value: ${{ jobs.snapshot.outputs.published }} - publishedPackages: - description: - 'A JSON array to present the published packages. The format is [{"name": "@xx/xx", - "version": "1.2.0"}, {"name": "@xx/xy", "version": "0.8.9"}]' - value: ${{ jobs.snapshot.outputs.publishedPackages }} - -jobs: - snapshot: - runs-on: ubuntu-24.04 - if: github.event.pull_request.head.repo.full_name == github.repository - outputs: - published: ${{ steps.changesets.outputs.published }} - publishedPackages: ${{ steps.changesets.outputs.publishedPackages }} - steps: - - name: checkout - uses: actions/checkout@v5 - with: - token: ${{ github.token }} - fetch-depth: 0 - ref: ${{ github.event.pull_request.head.sha }} - - - uses: ./.github/actions/setup-node - name: setup env - with: - nodeVersion: ${{inputs.nodeVersion}} - packageManager: ${{inputs.packageManager}} - packageManagerVersion: ${{inputs.packageManagerVersion}} - - - if: inputs.exitPre - name: Exit Prerelease Mode - run: ${{inputs.packageManager}} run changeset pre exit - - - if: inputs.restoreDeletedChangesets - name: restore deleted changesets - run: git checkout HEAD~1 -- . - - - name: ${{ inputs.npmTag }} release - id: changesets - uses: pinax-network/changesets-snapshot-action@v0.0.3 - with: - tag: ${{ inputs.npmTag }} - prepareScript: '${{inputs.packageManager}} run ${{ inputs.buildScript }}' - env: - NPM_TOKEN: ${{ secrets.npmToken }} - GITHUB_TOKEN: ${{ secrets.githubToken }} diff --git a/README.md b/README.md index 71d750206..98a4c592b 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ all the communications. To run this project locally: 1. Clone the repository -2. Make sure you have [Node.js](https://nodejs.org/en) `>=20.x` installed +2. Make sure you have [Node.js](https://nodejs.org/en) `>=22.x` installed 3. Make sure you have [`pnpm` installed](https://pnpm.io/installation) 4. Run `pnpm install` to install dependencies 5. Run `pnpm build` to build the packages diff --git a/examples/ethereum-basic-event-handlers/hardhat/Dockerfile b/examples/ethereum-basic-event-handlers/hardhat/Dockerfile index c50a089db..c639c616c 100644 --- a/examples/ethereum-basic-event-handlers/hardhat/Dockerfile +++ b/examples/ethereum-basic-event-handlers/hardhat/Dockerfile @@ -1,4 +1,4 @@ -FROM node:20-alpine +FROM node:22-alpine COPY . /usr/src/app diff --git a/examples/ethereum-basic-event-handlers/hardhat/hardhat.config.js b/examples/ethereum-basic-event-handlers/hardhat/hardhat.config.js index 7a75edfae..45709c8c8 100644 --- a/examples/ethereum-basic-event-handlers/hardhat/hardhat.config.js +++ b/examples/ethereum-basic-event-handlers/hardhat/hardhat.config.js @@ -1,3 +1,11 @@ module.exports = { solidity: '0.8.9', + networks: { + hardhat: { + // Pin to Cancun: Prague (default in hardhat >=2.26) enforces EIP-7825's + // per-transaction gas cap of 2^24, which rejects the test deployments. + // Tracking proper fix (pin hardhat / lockfile / fit gas cap) in #2127. + hardfork: 'cancun', + }, + }, }; diff --git a/package.json b/package.json index 3ce7350e4..2d48ff9e6 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "license": "(Apache-2.0 OR MIT)", "private": true, "engines": { - "node": ">=20.0.0", + "node": ">=22.0.0", "pnpm": "9" }, "scripts": { diff --git a/packages/cli/package.json b/packages/cli/package.json index c8bd2531d..0c34a470d 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -10,7 +10,7 @@ }, "license": "(Apache-2.0 OR MIT)", "engines": { - "node": ">=20.18.1" + "node": ">=22.11.0" }, "bin": { "graph": "bin/run.js"