From 563d2ad55c348cb99e24e39871aa098f2b959531 Mon Sep 17 00:00:00 2001 From: David Lutterkort Date: Mon, 18 May 2026 14:52:11 -0700 Subject: [PATCH 1/7] ci: switch publishing to npm Trusted Publishing, drop pinax infra Replace the broken NPM_TOKEN-based publish path with npm OIDC Trusted Publishing. The token belonged to a pinax-network bot that no longer has publish rights on @graphprotocol/graph-cli, causing snapshot releases to fail with E404 despite valid OIDC provenance being signed. Consolidate stable releases and alpha/rc snapshots into a single publish.yml because npmjs.com Trusted Publisher accepts only one workflow filename per package. Move auto-changesets for Renovate PRs to mscharley/dependency-changesets-action (actively maintained); the old the-guild-org upstream is unmaintained since 2023. Drop all pinax-network infrastructure: actions, bot identity, GPG signing secrets, and the misnamed "shared" workflow files (they were only used by this repo). Bot commits are now authored by github-actions[bot] and signed by GitHub's web-flow key via changesets/action, preserving the "Verified" badge. Requires Trusted Publisher to be registered on npmjs.com for both @graphprotocol/graph-cli and @graphprotocol/graph-ts before merging, pointing at workflow filename publish.yml. The NPM_TOKEN, PINAX_BOT_GITHUB_TOKEN, and PINAX_BOT_PGP_* secrets can be removed from repo settings after the first stable release succeeds. --- .github/workflows/changeset-deps.yml | 28 ++++ .github/workflows/pr.yml | 46 ------- .github/workflows/publish.yml | 123 ++++++++++++++++++ .github/workflows/release.yml | 65 --------- .../shared-changesets-dependencies.yml | 78 ----------- .github/workflows/shared-release-snapshot.yml | 89 ------------- 6 files changed, 151 insertions(+), 278 deletions(-) create mode 100644 .github/workflows/changeset-deps.yml delete mode 100644 .github/workflows/pr.yml create mode 100644 .github/workflows/publish.yml delete mode 100644 .github/workflows/release.yml delete mode 100644 .github/workflows/shared-changesets-dependencies.yml delete mode 100644 .github/workflows/shared-release-snapshot.yml diff --git a/.github/workflows/changeset-deps.yml b/.github/workflows/changeset-deps.yml new file mode 100644 index 000000000..54fe6754e --- /dev/null +++ b/.github/workflows/changeset-deps.yml @@ -0,0 +1,28 @@ +name: Auto changesets for dep updates +on: + pull_request: + branches: + - main + +permissions: + contents: write + pull-requests: write + +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 + with: + token: ${{ secrets.GITHUB_TOKEN }} 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..135b7c621 --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,123 @@ +name: Publish +on: + push: + branches: + - main + pull_request: + branches: + - main + +permissions: + contents: read + +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: Set variables + id: vars + run: echo "date=$(date +'%B %d, %Y')" >> "$GITHUB_OUTPUT" + + - name: Build + if: startsWith(github.event.head_commit.message, 'chore(release): update monorepo packages versions') + run: pnpm --filter=@graphprotocol/graph-cli build + + - name: Pack binaries + if: startsWith(github.event.head_commit.message, 'chore(release): update monorepo packages versions') + run: pnpm --filter=@graphprotocol/graph-cli oclif:pack + + - name: Create Release PR or Publish + uses: changesets/action@v1 + with: + publish: pnpm release + version: pnpm changeset version + commit: 'chore(release): update monorepo packages versions' + title: Upcoming Release Changes + createGithubReleases: true + githubReleaseName: ${{ steps.vars.outputs.date }} + githubReleaseAssets: packages/cli/dist/*.tar.gz + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + NPM_CONFIG_PROVENANCE: 'true' + + 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' + run: pnpm changeset version --snapshot ${{ steps.tag.outputs.tag }} + + - name: Publish snapshot + if: steps.has_changesets.outputs.has == 'true' + env: + 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 }} From 3d29527a2a578ef69173a432a31f475b994d650a Mon Sep 17 00:00:00 2001 From: David Lutterkort Date: Mon, 18 May 2026 15:01:05 -0700 Subject: [PATCH 2/7] ci(publish): fix prettier YAML parse error and restore asset upload MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Lift the release commit message into an env var so the inline `chore(release):` colon no longer breaks YAML's plain-scalar rules in `if:` conditions (prettier's parser was rejecting the file). - Drop `githubReleaseName` and `githubReleaseAssets` — those were pinax-fork extensions, not inputs on upstream `changesets/action@v1`. - Re-add asset upload as a follow-up step using `gh release upload`, gated on `steps.changesets.outputs.published`. Recent stable releases (0.97.0, 0.98.0) had hundreds of binary downloads, so this behavior should not regress. --- .github/workflows/publish.yml | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 135b7c621..d15fff7f7 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -10,6 +10,9 @@ on: permissions: contents: read +env: + RELEASE_COMMIT_MSG: 'chore(release): update monorepo packages versions' + jobs: stable: name: Stable @@ -35,32 +38,38 @@ jobs: packageManager: pnpm packageManagerVersion: 9 - - name: Set variables - id: vars - run: echo "date=$(date +'%B %d, %Y')" >> "$GITHUB_OUTPUT" - - name: Build - if: startsWith(github.event.head_commit.message, 'chore(release): update monorepo packages versions') + 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, 'chore(release): update monorepo packages versions') + 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: 'chore(release): update monorepo packages versions' + commit: ${{ env.RELEASE_COMMIT_MSG }} title: Upcoming Release Changes createGithubReleases: true - githubReleaseName: ${{ steps.vars.outputs.date }} - githubReleaseAssets: packages/cli/dist/*.tar.gz 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: | From 23f3aba24fa529032399bd102c575febdfae3598 Mon Sep 17 00:00:00 2001 From: David Lutterkort Date: Mon, 18 May 2026 15:08:22 -0700 Subject: [PATCH 3/7] ci(publish): pass GITHUB_TOKEN to snapshot changeset steps `@changesets/changelog-github` (the configured changelog generator) calls the GitHub REST API to enrich entries with PR and user info, and fails closed with `Please create a GitHub personal access token` when no token is set. The old pinax snapshot action injected GITHUB_TOKEN implicitly; the inlined version has to set it explicitly on the version and publish steps. The "Package X must depend on the current version" messages in the same log are harmless warnings about ignored example packages (.changeset/config.json: ignore=[example-*]) and were also present in the prior pinax-driven runs. --- .github/workflows/publish.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index d15fff7f7..34713d2c8 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -123,10 +123,13 @@ jobs: - 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 From 221ca991f3a6bb4178df71a09a2abb1b480f07c3 Mon Sep 17 00:00:00 2001 From: David Lutterkort Date: Mon, 18 May 2026 15:10:37 -0700 Subject: [PATCH 4/7] ci: drop Node 20 actions, replace styfle cancel with concurrency MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GitHub will force Node.js 20 actions to Node.js 24 starting 2026-06-02 and remove Node 20 from runners on 2026-09-16. The deprecation warning called out two actions used by the composite setup-node: - pnpm/action-setup@v4.2.0 → bumped to v6 (drop-in; same inputs). - styfle/cancel-workflow-action@0.12.1 → removed entirely. It's been superseded by GitHub's built-in `concurrency:` keyword. Add matching concurrency groups to ci.yml (cancel PR runs, preserve main) and changeset-deps.yml (cancel per-PR). publish.yml already has concurrency on both jobs. Also pin mscharley/dependency-changesets-action to v1.2.4 — the action publishes specific patch tags but no floating v1. --- .github/actions/setup-node/action.yml | 8 +------- .github/workflows/changeset-deps.yml | 6 +++++- .github/workflows/ci.yml | 4 ++++ 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/.github/actions/setup-node/action.yml b/.github/actions/setup-node/action.yml index ffcf33d9a..29d861e36 100644 --- a/.github/actions/setup-node/action.yml +++ b/.github/actions/setup-node/action.yml @@ -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 index 54fe6754e..8f82ea04c 100644 --- a/.github/workflows/changeset-deps.yml +++ b/.github/workflows/changeset-deps.yml @@ -8,6 +8,10 @@ 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 @@ -23,6 +27,6 @@ jobs: fetch-depth: 0 - name: Add changeset - uses: mscharley/dependency-changesets-action@v1 + 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..ecd0cb40b 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 From e906ab36895e8746f30b5f5ff3921fa3c858e56b Mon Sep 17 00:00:00 2001 From: David Lutterkort Date: Mon, 18 May 2026 15:20:17 -0700 Subject: [PATCH 5/7] test(example-event-handlers): pin in-container hardfork to cancun The hardhat node in examples/ethereum-basic-event-handlers/hardhat runs with `"hardhat": "^2.22.1"` and no lockfile, so each CI run picks the latest matching release (currently 2.28.6). Hardhat 2.26+ defaults to the Prague hardfork, which enforces EIP-7825's per- transaction gas cap of 2^24 (16,777,216). The test contract deploy needs ~30M gas and gets rejected with `ProviderError: Transaction gas limit is 30000000 and exceeds transaction gas cap of 16777216`. Pinning the in-container network's hardfork to `cancun` restores pre-EIP-7825 behavior without locking the hardhat version. --- .../hardhat/hardhat.config.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/examples/ethereum-basic-event-handlers/hardhat/hardhat.config.js b/examples/ethereum-basic-event-handlers/hardhat/hardhat.config.js index 7a75edfae..cf864557f 100644 --- a/examples/ethereum-basic-event-handlers/hardhat/hardhat.config.js +++ b/examples/ethereum-basic-event-handlers/hardhat/hardhat.config.js @@ -1,3 +1,10 @@ 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. + hardfork: 'cancun', + }, + }, }; From 34852f9ac99f5935e21ad16af7561a242cafefef Mon Sep 17 00:00:00 2001 From: David Lutterkort Date: Mon, 18 May 2026 15:22:26 -0700 Subject: [PATCH 6/7] test(example-event-handlers): link tracking issue from hardfork workaround Link #2127 from the cancun-hardfork comment so anyone touching the file finds the tracking ticket for the proper fix (deterministic hardhat version via lockfile or pinned version). --- examples/ethereum-basic-event-handlers/hardhat/hardhat.config.js | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/ethereum-basic-event-handlers/hardhat/hardhat.config.js b/examples/ethereum-basic-event-handlers/hardhat/hardhat.config.js index cf864557f..45709c8c8 100644 --- a/examples/ethereum-basic-event-handlers/hardhat/hardhat.config.js +++ b/examples/ethereum-basic-event-handlers/hardhat/hardhat.config.js @@ -4,6 +4,7 @@ module.exports = { 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', }, }, From 7fe67ac310e5f4f17dbdaabb0cb0ee0812e4101a Mon Sep 17 00:00:00 2001 From: David Lutterkort Date: Mon, 18 May 2026 16:41:26 -0700 Subject: [PATCH 7/7] chore: drop Node.js 20 support, require Node 22+ Node 20 reached EOL on 2026-04-30. Bump the declared minimum to Node 22 (22.11.0 for the CLI package), replace Node 20 with Node 22 in the single-version CI jobs, and shift the CLI test matrix from [20, 22] to [22, 24] so what we test matches what publish.yml already ships on. --- .changeset/drop-node-20.md | 7 +++++++ .github/actions/setup-node/action.yml | 2 +- .github/workflows/ci.yml | 8 ++++---- README.md | 2 +- examples/ethereum-basic-event-handlers/hardhat/Dockerfile | 2 +- package.json | 2 +- packages/cli/package.json | 2 +- 7 files changed, 16 insertions(+), 9 deletions(-) create mode 100644 .changeset/drop-node-20.md 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 29d861e36..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 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ecd0cb40b..6f771a09d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,7 +24,7 @@ jobs: - uses: ./.github/actions/setup-node name: Setup Env with: - nodeVersion: 20 + nodeVersion: 22 packageManager: pnpm packageManagerVersion: 9 @@ -38,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 @@ -80,7 +80,7 @@ jobs: - uses: ./.github/actions/setup-node name: Setup Env with: - nodeVersion: 20 + nodeVersion: 22 packageManager: pnpm packageManagerVersion: 9 @@ -110,7 +110,7 @@ jobs: - uses: ./.github/actions/setup-node name: Setup Env with: - nodeVersion: 20 + nodeVersion: 22 packageManager: pnpm packageManagerVersion: 9 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/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"