Skip to content

Push backport branches via GraphQL createCommitOnBranch (signed commits)#1937

Merged
TooTallNate merged 1 commit intomainfrom
backport-signed-commits-via-graphql
May 5, 2026
Merged

Push backport branches via GraphQL createCommitOnBranch (signed commits)#1937
TooTallNate merged 1 commit intomainfrom
backport-signed-commits-via-graphql

Conversation

@TooTallNate
Copy link
Copy Markdown
Member

Summary

Backport of PR #1902 (label-triggered) failed with:

remote: error: GH013: Repository rule violations found for refs/heads/backport/pr-1902-to-stable.
remote: - Commits must have verified signatures.

The repo has an enterprise-level branch ruleset matching ~ALL that requires verified signatures on every ref, so a normal git push of a locally cherry-picked commit is rejected because CI doesn't have a signing key.

This replaces the git push step with a GraphQL createCommitOnBranch mutation, which signs commits automatically with GitHub's internal key (the same way commits made via the web UI or by changesets/action with commitMode: github-api are signed).

Implementation

After the local cherry-pick (with optional AI conflict resolution) succeeds, a new Push backport branch via GitHub API step:

  1. Walks git diff --name-status -z between the parent (stable HEAD) and the cherry-pick HEAD.
  2. For each addition/modification, reads the blob raw bytes via git cat-file blob and base64-encodes them into a FileAddition. For each deletion, emits a FileDeletion. Renames are handled as add(new) + delete(old).
  3. Ensures the backport/<...> branch exists on the remote and points at the stable HEAD (the mutation requires the branch to already exist with the expected expectedHeadOid).
  4. Runs the createCommitOnBranch mutation. GitHub creates a verified-signed commit and updates the branch ref atomically.

The subsequent Create backport PR step is unchanged.

Caveats

  • Authorship is lost. createCommitOnBranch always attributes commits to the token owner (github-actions[bot]), so we lose original-author attribution in the git log. The original commit SHA is still referenced in the PR body.
  • Non-regular files (executable bit, symlinks, submodules) are not supported by the GraphQL mutation. The step warns and proceeds with mode 100644 for affected paths. This matches the documented limitations of @changesets/ghcommit, which the release.yml workflow uses for its own commitMode: github-api. Backports involving these file types will need manual signed pushes (the failure-comment instructions now mention git cherry-pick -S for that).

Manual fallback

The Comment on conflict failure step's manual instructions are also updated to mention that local cherry-picks must be signed (git cherry-pick -S) because of the same ruleset, and to push to a backport/<...> branch and open a PR rather than pushing directly to stable.

The repo has an enterprise-level branch ruleset requiring verified
signatures on every ref (`~ALL`), so a normal `git push` of a locally
cherry-picked commit is rejected ("Commits must have verified
signatures"). Replace the `git push` step with a GraphQL
`createCommitOnBranch` mutation, which signs commits automatically
with GitHub's internal key (the same way commits made via the web UI
are signed).

Walks the cherry-pick's diff against the parent (`stable` HEAD),
collects file additions (with binary-safe base64 contents read via
`git cat-file blob`) and deletions, ensures the backport branch
exists on the remote, then runs the mutation. Also updates the manual
conflict-resolution instructions in the failure comment to mention
that local cherry-picks must be signed (`git cherry-pick -S`)
because of the same ruleset.

Caveats:
- Authorship is lost — `createCommitOnBranch` always attributes
  commits to the token owner (`github-actions[bot]`). The original
  commit SHA is still referenced in the PR body.
- Non-regular files (executable bit, symlinks, submodules) are not
  supported by the mutation; the step warns and proceeds with mode
  100644 for affected paths.
Copilot AI review requested due to automatic review settings May 5, 2026 08:10
@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented May 5, 2026

⚠️ No Changeset found

Latest commit: bf2f2a3

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@vercel
Copy link
Copy Markdown
Contributor

vercel Bot commented May 5, 2026

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 5, 2026

🧪 E2E Test Results

All tests passed

Summary

Passed Failed Skipped Total
✅ ▲ Vercel Production 925 0 219 1144
✅ 💻 Local Development 1237 0 219 1456
✅ 📦 Local Production 1237 0 219 1456
✅ 🐘 Local Postgres 1237 0 219 1456
✅ 🪟 Windows 104 0 0 104
✅ 📋 Other 552 0 176 728
Total 5292 0 1052 6344

Details by Category

✅ ▲ Vercel Production
App Passed Failed Skipped
✅ astro 78 0 26
✅ example 78 0 26
✅ express 78 0 26
✅ fastify 78 0 26
✅ hono 78 0 26
✅ nextjs-turbopack 102 0 2
✅ nextjs-webpack 102 0 2
✅ nitro 78 0 26
✅ nuxt 78 0 26
✅ sveltekit 97 0 7
✅ vite 78 0 26
✅ 💻 Local Development
App Passed Failed Skipped
✅ astro-stable 79 0 25
✅ express-stable 79 0 25
✅ fastify-stable 79 0 25
✅ hono-stable 79 0 25
✅ nextjs-turbopack-canary 85 0 19
✅ nextjs-turbopack-stable-lazy-discovery-disabled 104 0 0
✅ nextjs-turbopack-stable-lazy-discovery-enabled 104 0 0
✅ nextjs-webpack-canary 85 0 19
✅ nextjs-webpack-stable-lazy-discovery-disabled 104 0 0
✅ nextjs-webpack-stable-lazy-discovery-enabled 104 0 0
✅ nitro-stable 79 0 25
✅ nuxt-stable 79 0 25
✅ sveltekit-stable 98 0 6
✅ vite-stable 79 0 25
✅ 📦 Local Production
App Passed Failed Skipped
✅ astro-stable 79 0 25
✅ express-stable 79 0 25
✅ fastify-stable 79 0 25
✅ hono-stable 79 0 25
✅ nextjs-turbopack-canary 85 0 19
✅ nextjs-turbopack-stable-lazy-discovery-disabled 104 0 0
✅ nextjs-turbopack-stable-lazy-discovery-enabled 104 0 0
✅ nextjs-webpack-canary 85 0 19
✅ nextjs-webpack-stable-lazy-discovery-disabled 104 0 0
✅ nextjs-webpack-stable-lazy-discovery-enabled 104 0 0
✅ nitro-stable 79 0 25
✅ nuxt-stable 79 0 25
✅ sveltekit-stable 98 0 6
✅ vite-stable 79 0 25
✅ 🐘 Local Postgres
App Passed Failed Skipped
✅ astro-stable 79 0 25
✅ express-stable 79 0 25
✅ fastify-stable 79 0 25
✅ hono-stable 79 0 25
✅ nextjs-turbopack-canary 85 0 19
✅ nextjs-turbopack-stable-lazy-discovery-disabled 104 0 0
✅ nextjs-turbopack-stable-lazy-discovery-enabled 104 0 0
✅ nextjs-webpack-canary 85 0 19
✅ nextjs-webpack-stable-lazy-discovery-disabled 104 0 0
✅ nextjs-webpack-stable-lazy-discovery-enabled 104 0 0
✅ nitro-stable 79 0 25
✅ nuxt-stable 79 0 25
✅ sveltekit-stable 98 0 6
✅ vite-stable 79 0 25
✅ 🪟 Windows
App Passed Failed Skipped
✅ nextjs-turbopack 104 0 0
✅ 📋 Other
App Passed Failed Skipped
✅ e2e-local-dev-nest-stable 79 0 25
✅ e2e-local-dev-tanstack-start- 79 0 25
✅ e2e-local-postgres-nest-stable 79 0 25
✅ e2e-local-postgres-tanstack-start- 79 0 25
✅ e2e-local-prod-nest-stable 79 0 25
✅ e2e-local-prod-tanstack-start- 79 0 25
✅ e2e-vercel-prod-tanstack-start 78 0 26

📋 View full workflow run

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 5, 2026

📊 Benchmark Results

📈 Comparing against baseline from main branch. Green 🟢 = faster, Red 🔺 = slower.

workflow with no steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
💻 Local 🥇 Nitro 0.032s (-26.9% 🟢) 1.006s (~) 0.974s 10 1.00x
💻 Local Express 0.033s (-24.6% 🟢) 1.006s (~) 0.973s 10 1.06x
🐘 Postgres Express 0.049s (-16.4% 🟢) 1.013s (~) 0.964s 10 1.54x
🐘 Postgres Nitro 0.054s (-43.5% 🟢) 1.013s (-2.9%) 0.959s 10 1.71x
💻 Local Next.js (Turbopack) ⚠️ missing - - - -
🐘 Postgres Next.js (Turbopack) ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Express 0.226s (-3.9%) 2.309s (+8.1% 🔺) 2.083s 10 1.00x
▲ Vercel Nitro 0.228s (-44.3% 🟢) 2.010s (-19.9% 🟢) 1.782s 10 1.01x
▲ Vercel Next.js (Turbopack) 0.822s (+226.9% 🔺) 2.891s (+23.9% 🔺) 2.069s 10 3.63x

🔍 Observability: Express | Nitro | Next.js (Turbopack)

workflow with 1 step

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
💻 Local 🥇 Express 1.067s (-5.2% 🟢) 2.007s (~) 0.940s 10 1.00x
💻 Local Nitro 1.073s (-5.1% 🟢) 2.007s (~) 0.934s 10 1.01x
🐘 Postgres Express 1.081s (-5.7% 🟢) 2.009s (~) 0.928s 10 1.01x
🐘 Postgres Nitro 1.084s (-4.9%) 2.008s (~) 0.924s 10 1.02x
💻 Local Next.js (Turbopack) ⚠️ missing - - - -
🐘 Postgres Next.js (Turbopack) ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Express 1.530s (-18.4% 🟢) 4.053s (+6.4% 🔺) 2.523s 10 1.00x
▲ Vercel Nitro 1.604s (-58.8% 🟢) 3.816s (-35.4% 🟢) 2.212s 10 1.05x
▲ Vercel Next.js (Turbopack) 2.444s (+20.1% 🔺) 5.515s (+44.0% 🔺) 3.071s 10 1.60x

🔍 Observability: Express | Nitro | Next.js (Turbopack)

workflow with 10 sequential steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
💻 Local 🥇 Express 10.390s (-4.9%) 11.022s (~) 0.632s 3 1.00x
🐘 Postgres Nitro 10.416s (-4.2%) 11.019s (~) 0.603s 3 1.00x
🐘 Postgres Express 10.426s (-4.9%) 11.018s (~) 0.592s 3 1.00x
💻 Local Nitro 10.432s (-4.7%) 11.022s (~) 0.590s 3 1.00x
💻 Local Next.js (Turbopack) ⚠️ missing - - - -
🐘 Postgres Next.js (Turbopack) ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 13.328s (-43.8% 🟢) 15.244s (-39.3% 🟢) 1.916s 2 1.00x
▲ Vercel Next.js (Turbopack) 13.499s (-22.1% 🟢) 15.421s (-20.5% 🟢) 1.921s 2 1.01x
▲ Vercel Express 13.634s (-19.7% 🟢) 15.581s (-22.2% 🟢) 1.947s 2 1.02x

🔍 Observability: Nitro | Next.js (Turbopack) | Express

workflow with 25 sequential steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
💻 Local 🥇 Express 13.405s (-10.5% 🟢) 14.026s (-6.7% 🟢) 0.622s 5 1.00x
🐘 Postgres Express 13.477s (-7.6% 🟢) 14.019s (-6.7% 🟢) 0.542s 5 1.01x
🐘 Postgres Nitro 13.487s (-7.6% 🟢) 14.019s (-6.7% 🟢) 0.532s 5 1.01x
💻 Local Nitro 13.501s (-10.4% 🟢) 14.027s (-12.5% 🟢) 0.526s 5 1.01x
💻 Local Next.js (Turbopack) ⚠️ missing - - - -
🐘 Postgres Next.js (Turbopack) ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 21.186s (-67.1% 🟢) 23.236s (-65.1% 🟢) 2.049s 3 1.00x
▲ Vercel Express 21.669s (-56.9% 🟢) 23.908s (-54.5% 🟢) 2.239s 3 1.02x
▲ Vercel Next.js (Turbopack) 22.502s (-57.2% 🟢) 25.855s (-52.7% 🟢) 3.353s 3 1.06x

🔍 Observability: Nitro | Express | Next.js (Turbopack)

workflow with 50 sequential steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
💻 Local 🥇 Express 11.805s (-28.9% 🟢) 12.023s (-29.4% 🟢) 0.218s 8 1.00x
🐘 Postgres Nitro 11.950s (-14.4% 🟢) 12.265s (-14.3% 🟢) 0.315s 8 1.01x
💻 Local Nitro 11.961s (-28.7% 🟢) 12.272s (-27.9% 🟢) 0.312s 8 1.01x
🐘 Postgres Express 11.999s (-14.3% 🟢) 12.395s (-15.1% 🟢) 0.396s 8 1.02x
💻 Local Next.js (Turbopack) ⚠️ missing - - - -
🐘 Postgres Next.js (Turbopack) ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 29.482s (-93.0% 🟢) 32.053s (-92.4% 🟢) 2.571s 3 1.00x
▲ Vercel Express 31.774s (-73.8% 🟢) 33.949s (-72.5% 🟢) 2.175s 3 1.08x
▲ Vercel Next.js (Turbopack) 32.588s (-91.7% 🟢) 34.963s (-91.2% 🟢) 2.375s 3 1.11x

🔍 Observability: Nitro | Express | Next.js (Turbopack)

Promise.all with 10 concurrent steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 1.149s (-9.9% 🟢) 2.008s (~) 0.860s 15 1.00x
🐘 Postgres Express 1.149s (-8.9% 🟢) 2.007s (~) 0.858s 15 1.00x
💻 Local Express 1.182s (-20.6% 🟢) 2.006s (~) 0.824s 15 1.03x
💻 Local Nitro 1.187s (-27.2% 🟢) 2.006s (-3.3%) 0.819s 15 1.03x
💻 Local Next.js (Turbopack) ⚠️ missing - - - -
🐘 Postgres Next.js (Turbopack) ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Express 2.393s (-16.3% 🟢) 4.076s (-11.8% 🟢) 1.683s 8 1.00x
▲ Vercel Nitro 3.586s (+27.2% 🔺) 6.167s (+42.7% 🔺) 2.582s 5 1.50x
▲ Vercel Next.js (Turbopack) 4.111s (+21.0% 🔺) 6.005s (+21.7% 🔺) 1.893s 5 1.72x

🔍 Observability: Express | Nitro | Next.js (Turbopack)

Promise.all with 25 concurrent steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Express 1.219s (-48.4% 🟢) 2.007s (-33.3% 🟢) 0.787s 15 1.00x
🐘 Postgres Nitro 1.226s (-47.8% 🟢) 2.007s (-33.3% 🟢) 0.781s 15 1.01x
💻 Local Express 1.696s (-42.6% 🟢) 2.005s (-41.9% 🟢) 0.309s 15 1.39x
💻 Local Nitro 1.813s (-42.3% 🟢) 2.150s (-44.7% 🟢) 0.337s 14 1.49x
💻 Local Next.js (Turbopack) ⚠️ missing - - - -
🐘 Postgres Next.js (Turbopack) ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Express 3.409s (-5.8% 🟢) 5.002s (-2.1%) 1.593s 6 1.00x
▲ Vercel Nitro 3.694s (-8.8% 🟢) 5.496s (-7.2% 🟢) 1.802s 6 1.08x
▲ Vercel Next.js (Turbopack) 5.534s (-22.1% 🟢) 8.109s (-8.9% 🟢) 2.575s 4 1.62x

🔍 Observability: Express | Nitro | Next.js (Turbopack)

Promise.all with 50 concurrent steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Express 1.380s (-60.4% 🟢) 2.010s (-49.9% 🟢) 0.629s 15 1.00x
🐘 Postgres Nitro 1.402s (-59.7% 🟢) 2.008s (-49.9% 🟢) 0.606s 15 1.02x
💻 Local Express 4.670s (-44.0% 🟢) 5.347s (-40.8% 🟢) 0.678s 6 3.38x
💻 Local Nitro 5.542s (-33.6% 🟢) 6.014s (-33.3% 🟢) 0.472s 5 4.02x
💻 Local Next.js (Turbopack) ⚠️ missing - - - -
🐘 Postgres Next.js (Turbopack) ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 5.291s (+50.1% 🔺) 6.876s (+24.2% 🔺) 1.585s 5 1.00x
▲ Vercel Express 6.062s (+43.0% 🔺) 7.819s (+27.6% 🔺) 1.757s 4 1.15x
▲ Vercel Next.js (Turbopack) 7.963s (-10.7% 🟢) 10.220s (-6.8% 🟢) 2.257s 3 1.51x

🔍 Observability: Nitro | Express | Next.js (Turbopack)

Promise.race with 10 concurrent steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Express 1.160s (-7.7% 🟢) 2.009s (~) 0.849s 15 1.00x
🐘 Postgres Nitro 1.166s (-7.2% 🟢) 2.008s (~) 0.842s 15 1.01x
💻 Local Express 1.373s (-27.5% 🟢) 2.006s (-15.1% 🟢) 0.633s 15 1.18x
💻 Local Nitro 1.416s (-24.1% 🟢) 2.006s (-14.3% 🟢) 0.590s 15 1.22x
💻 Local Next.js (Turbopack) ⚠️ missing - - - -
🐘 Postgres Next.js (Turbopack) ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 2.761s (+12.3% 🔺) 4.858s (+16.5% 🔺) 2.097s 7 1.00x
▲ Vercel Express 3.000s (+16.2% 🔺) 4.648s (+6.9% 🔺) 1.648s 7 1.09x
▲ Vercel Next.js (Turbopack) 4.394s (+49.9% 🔺) 6.773s (+45.9% 🔺) 2.379s 5 1.59x

🔍 Observability: Nitro | Express | Next.js (Turbopack)

Promise.race with 25 concurrent steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Express 1.236s (-47.2% 🟢) 2.009s (-33.3% 🟢) 0.773s 15 1.00x
🐘 Postgres Nitro 1.246s (-46.7% 🟢) 2.007s (-33.3% 🟢) 0.762s 15 1.01x
💻 Local Express 1.895s (-39.5% 🟢) 2.315s (-38.5% 🟢) 0.420s 13 1.53x
💻 Local Nitro 2.077s (-32.2% 🟢) 2.591s (-33.3% 🟢) 0.515s 12 1.68x
💻 Local Next.js (Turbopack) ⚠️ missing - - - -
🐘 Postgres Next.js (Turbopack) ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 3.692s (+14.2% 🔺) 5.687s (+12.0% 🔺) 1.994s 6 1.00x
▲ Vercel Express 3.848s (+20.5% 🔺) 5.646s (+17.8% 🔺) 1.798s 6 1.04x
▲ Vercel Next.js (Turbopack) 4.815s (+53.2% 🔺) 7.048s (+55.9% 🔺) 2.233s 5 1.30x

🔍 Observability: Nitro | Express | Next.js (Turbopack)

Promise.race with 50 concurrent steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Express 1.381s (-60.5% 🟢) 2.008s (-49.9% 🟢) 0.627s 15 1.00x
🐘 Postgres Nitro 1.391s (-60.0% 🟢) 2.008s (-49.9% 🟢) 0.617s 15 1.01x
💻 Local Express 5.537s (-37.1% 🟢) 6.017s (-35.1% 🟢) 0.480s 5 4.01x
💻 Local Nitro 5.929s (-35.2% 🟢) 6.413s (-36.0% 🟢) 0.484s 5 4.29x
💻 Local Next.js (Turbopack) ⚠️ missing - - - -
🐘 Postgres Next.js (Turbopack) ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Express 5.012s (-21.9% 🟢) 6.881s (-15.9% 🟢) 1.869s 5 1.00x
▲ Vercel Nitro 5.472s (+7.4% 🔺) 7.689s (+12.8% 🔺) 2.218s 4 1.09x
▲ Vercel Next.js (Turbopack) 5.785s (-14.4% 🟢) 7.606s (-11.0% 🟢) 1.822s 4 1.15x

🔍 Observability: Express | Nitro | Next.js (Turbopack)

workflow with 10 sequential data payload steps (10KB)

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Express 0.418s (-50.1% 🟢) 1.007s (-1.6%) 0.588s 60 1.00x
🐘 Postgres Nitro 0.456s (-44.4% 🟢) 1.006s (~) 0.550s 60 1.09x
💻 Local Express 0.475s (-51.7% 🟢) 1.004s (-6.7% 🟢) 0.529s 60 1.14x
💻 Local Nitro 0.561s (-42.8% 🟢) 1.095s (~) 0.535s 55 1.34x
💻 Local Next.js (Turbopack) ⚠️ missing - - - -
🐘 Postgres Next.js (Turbopack) ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Express 4.832s (-74.6% 🟢) 6.959s (-67.4% 🟢) 2.127s 9 1.00x
▲ Vercel Nitro 4.927s (-77.7% 🟢) 6.794s (-71.7% 🟢) 1.867s 9 1.02x
▲ Vercel Next.js (Turbopack) 7.374s (-49.2% 🟢) 9.277s (-42.3% 🟢) 1.902s 7 1.53x

🔍 Observability: Express | Nitro | Next.js (Turbopack)

workflow with 25 sequential data payload steps (10KB)

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 1.072s (-44.4% 🟢) 1.705s (-18.8% 🟢) 0.633s 53 1.00x
🐘 Postgres Express 1.109s (-43.9% 🟢) 1.923s (-14.8% 🟢) 0.813s 47 1.04x
💻 Local Express 1.163s (-61.4% 🟢) 2.005s (-44.1% 🟢) 0.843s 45 1.09x
💻 Local Nitro 1.192s (-60.7% 🟢) 2.006s (-46.6% 🟢) 0.814s 45 1.11x
💻 Local Next.js (Turbopack) ⚠️ missing - - - -
🐘 Postgres Next.js (Turbopack) ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Express 13.140s (-61.9% 🟢) 15.341s (-58.3% 🟢) 2.200s 6 1.00x
▲ Vercel Nitro 13.355s (-66.2% 🟢) 16.002s (-61.3% 🟢) 2.647s 6 1.02x
▲ Vercel Next.js (Turbopack) 16.463s (-66.9% 🟢) 18.716s (-63.8% 🟢) 2.253s 5 1.25x

🔍 Observability: Express | Nitro | Next.js (Turbopack)

workflow with 50 sequential data payload steps (10KB)

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Express 2.143s (-46.3% 🟢) 2.781s (-36.3% 🟢) 0.638s 44 1.00x
🐘 Postgres Nitro 2.158s (-47.4% 🟢) 2.781s (-39.6% 🟢) 0.623s 44 1.01x
💻 Local Express 2.649s (-71.2% 🟢) 3.008s (-70.0% 🟢) 0.358s 40 1.24x
💻 Local Nitro 2.729s (-70.6% 🟢) 3.008s (-70.0% 🟢) 0.278s 40 1.27x
💻 Local Next.js (Turbopack) ⚠️ missing - - - -
🐘 Postgres Next.js (Turbopack) ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Express 41.153s (-68.4% 🟢) 43.595s (-67.0% 🟢) 2.442s 3 1.00x
▲ Vercel Nitro 43.379s (-55.2% 🟢) 45.800s (-53.5% 🟢) 2.421s 3 1.05x
▲ Vercel Next.js (Turbopack) 49.075s (-54.2% 🟢) 51.250s (-52.9% 🟢) 2.175s 3 1.19x

🔍 Observability: Express | Nitro | Next.js (Turbopack)

workflow with 10 concurrent data payload steps (10KB)

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Express 0.192s (-31.9% 🟢) 1.006s (~) 0.814s 60 1.00x
🐘 Postgres Nitro 0.203s (-28.5% 🟢) 1.006s (~) 0.803s 60 1.05x
💻 Local Express 0.439s (-21.6% 🟢) 1.004s (~) 0.565s 60 2.28x
💻 Local Nitro 0.452s (-25.2% 🟢) 1.005s (-1.7%) 0.552s 60 2.35x
💻 Local Next.js (Turbopack) ⚠️ missing - - - -
🐘 Postgres Next.js (Turbopack) ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 2.128s (+28.1% 🔺) 4.004s (+19.5% 🔺) 1.876s 15 1.00x
▲ Vercel Express 2.485s (+27.2% 🔺) 4.316s (+18.7% 🔺) 1.830s 14 1.17x
▲ Vercel Next.js (Turbopack) 4.322s (+113.7% 🔺) 6.196s (+63.3% 🔺) 1.873s 10 2.03x

🔍 Observability: Nitro | Express | Next.js (Turbopack)

workflow with 25 concurrent data payload steps (10KB)

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 0.318s (-35.9% 🟢) 1.006s (~) 0.688s 90 1.00x
🐘 Postgres Express 0.322s (-36.8% 🟢) 1.007s (~) 0.684s 90 1.01x
💻 Local Nitro 2.170s (-14.5% 🟢) 2.976s (-1.1%) 0.806s 31 6.82x
💻 Local Express 2.288s (-9.0% 🟢) 2.945s (-2.1%) 0.657s 31 7.19x
💻 Local Next.js (Turbopack) ⚠️ missing - - - -
🐘 Postgres Next.js (Turbopack) ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Next.js (Turbopack) 6.901s (+95.2% 🔺) 8.807s (+69.6% 🔺) 1.906s 11 1.00x
▲ Vercel Express 7.484s (+145.6% 🔺) 9.450s (+96.6% 🔺) 1.966s 10 1.08x
▲ Vercel Nitro 8.029s (+148.9% 🔺) 10.079s (+109.0% 🔺) 2.050s 9 1.16x

🔍 Observability: Next.js (Turbopack) | Express | Nitro

workflow with 50 concurrent data payload steps (10KB)

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Express 0.648s (-20.8% 🟢) 1.006s (-1.1%) 0.358s 120 1.00x
🐘 Postgres Nitro 0.662s (-16.2% 🟢) 1.006s (~) 0.344s 120 1.02x
💻 Local Express 10.154s (-9.3% 🟢) 10.779s (-9.7% 🟢) 0.625s 12 15.67x
💻 Local Nitro 10.261s (-8.3% 🟢) 10.861s (-6.9% 🟢) 0.600s 12 15.83x
💻 Local Next.js (Turbopack) ⚠️ missing - - - -
🐘 Postgres Next.js (Turbopack) ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 21.143s (+173.8% 🔺) 23.663s (+151.7% 🔺) 2.520s 6 1.00x
▲ Vercel Next.js (Turbopack) 21.735s (+110.5% 🔺) 24.215s (+97.1% 🔺) 2.480s 5 1.03x
▲ Vercel Express 23.578s (+217.7% 🔺) 25.565s (+176.5% 🔺) 1.987s 6 1.12x

🔍 Observability: Nitro | Next.js (Turbopack) | Express

Stream Benchmarks (includes TTFB metrics)
workflow with stream

💻 Local Development

World Framework Workflow Time TTFB Slurp Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Express 1.133s (+452.3% 🔺) 1.998s (+100.1% 🔺) 0.001s (-18.8% 🟢) 2.010s (+98.7% 🔺) 0.877s 10 1.00x
🐘 Postgres Nitro 1.139s (+455.7% 🔺) 1.996s (+99.7% 🔺) 0.002s (+6.7% 🔺) 2.010s (+98.8% 🔺) 0.871s 10 1.01x
💻 Local Nitro 1.141s (+434.0% 🔺) 2.005s (+99.6% 🔺) 0.013s (+0.8%) 2.020s (+98.3% 🔺) 0.879s 10 1.01x
💻 Local Express 1.142s (+473.7% 🔺) 2.005s (+99.6% 🔺) 0.010s (-15.7% 🟢) 2.017s (+98.1% 🔺) 0.875s 10 1.01x
💻 Local Next.js (Turbopack) ⚠️ missing - - - - -
🐘 Postgres Next.js (Turbopack) ⚠️ missing - - - - -

▲ Production (Vercel)

World Framework Workflow Time TTFB Slurp Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Express 2.084s (-16.8% 🟢) 3.621s (-11.5% 🟢) 1.392s (+44.9% 🔺) 5.488s (-1.8%) 3.404s 10 1.00x
▲ Vercel Nitro 2.351s (-38.7% 🟢) 3.757s (-28.8% 🟢) 1.714s (+130.9% 🔺) 6.059s (-6.5% 🟢) 3.708s 10 1.13x
▲ Vercel Next.js (Turbopack) 4.987s (-27.2% 🟢) 5.551s (-35.8% 🟢) 0.780s (+23.4% 🔺) 8.218s (-16.0% 🟢) 3.230s 10 2.39x

🔍 Observability: Express | Nitro | Next.js (Turbopack)

stream pipeline with 5 transform steps (1MB)

💻 Local Development

World Framework Workflow Time TTFB Slurp Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 1.516s (+142.9% 🔺) 1.999s (+98.6% 🔺) 0.004s (-8.9% 🟢) 2.023s (+97.9% 🔺) 0.508s 30 1.00x
💻 Local Express 1.528s (+101.9% 🔺) 2.011s (+95.5% 🔺) 0.010s (+8.0% 🔺) 2.023s (+94.6% 🔺) 0.495s 30 1.01x
🐘 Postgres Express 1.530s (+142.9% 🔺) 2.001s (+98.8% 🔺) 0.004s (-3.4%) 2.025s (+98.0% 🔺) 0.495s 30 1.01x
💻 Local Nitro 1.532s (+82.7% 🔺) 2.012s (+98.8% 🔺) 0.010s (+7.4% 🔺) 2.024s (+81.4% 🔺) 0.491s 30 1.01x
💻 Local Next.js (Turbopack) ⚠️ missing - - - - -
🐘 Postgres Next.js (Turbopack) ⚠️ missing - - - - -

▲ Production (Vercel)

World Framework Workflow Time TTFB Slurp Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Express 5.651s (-13.1% 🟢) 7.576s (-5.4% 🟢) 0.276s (-32.5% 🟢) 8.321s (-5.8% 🟢) 2.670s 8 1.00x
▲ Vercel Nitro 5.768s (-80.4% 🟢) 7.321s (-76.2% 🟢) 0.226s (+101.7% 🔺) 8.075s (-74.6% 🟢) 2.306s 8 1.02x
▲ Vercel Next.js (Turbopack) 13.542s (-20.0% 🟢) 14.863s (-18.5% 🟢) 0.258s (+22.0% 🔺) 16.071s (-15.1% 🟢) 2.529s 4 2.40x

🔍 Observability: Express | Nitro | Next.js (Turbopack)

10 parallel streams (1MB each)

💻 Local Development

World Framework Workflow Time TTFB Slurp Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Express 0.655s (-31.8% 🟢) 1.014s (-20.6% 🟢) 0.000s (-20.7% 🟢) 1.039s (-20.5% 🟢) 0.384s 58 1.00x
🐘 Postgres Nitro 0.686s (-29.2% 🟢) 1.050s (-15.9% 🟢) 0.000s (+26.3% 🔺) 1.061s (-15.7% 🟢) 0.375s 57 1.05x
💻 Local Nitro 1.358s (+11.0% 🔺) 2.015s (~) 0.000s (+233.3% 🔺) 2.017s (~) 0.660s 30 2.07x
💻 Local Express 1.399s (+14.2% 🔺) 2.015s (~) 0.000s (~) 2.017s (~) 0.619s 30 2.13x
💻 Local Next.js (Turbopack) ⚠️ missing - - - - -
🐘 Postgres Next.js (Turbopack) ⚠️ missing - - - - -

▲ Production (Vercel)

World Framework Workflow Time TTFB Slurp Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Express 3.448s (-7.8% 🟢) 5.468s (+7.2% 🔺) 0.000s (-100.0% 🟢) 5.938s (+7.4% 🔺) 2.490s 11 1.00x
▲ Vercel Nitro 3.536s (+15.9% 🔺) 5.018s (+14.2% 🔺) 0.000s (+18.2% 🔺) 5.582s (+16.1% 🔺) 2.046s 11 1.03x
▲ Vercel Next.js (Turbopack) 6.247s (-38.6% 🟢) 7.226s (-37.3% 🟢) 0.000s (+Infinity% 🔺) 8.682s (-27.9% 🟢) 2.435s 8 1.81x

🔍 Observability: Express | Nitro | Next.js (Turbopack)

fan-out fan-in 10 streams (1MB each)

💻 Local Development

World Framework Workflow Time TTFB Slurp Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 1.338s (-25.3% 🟢) 2.032s (-5.1% 🟢) 0.000s (-100.0% 🟢) 2.043s (-6.0% 🟢) 0.706s 30 1.00x
🐘 Postgres Express 1.607s (-9.3% 🟢) 2.257s (+3.6%) 0.000s (NaN%) 2.269s (+3.2%) 0.662s 27 1.20x
💻 Local Nitro 3.176s (-6.2% 🟢) 3.902s (-3.2%) 0.000s (-18.0% 🟢) 3.908s (-3.2%) 0.732s 16 2.37x
💻 Local Express 3.234s (-6.7% 🟢) 3.969s (-1.6%) 0.001s (-21.9% 🟢) 3.972s (-1.6%) 0.738s 16 2.42x
💻 Local Next.js (Turbopack) ⚠️ missing - - - - -
🐘 Postgres Next.js (Turbopack) ⚠️ missing - - - - -

▲ Production (Vercel)

World Framework Workflow Time TTFB Slurp Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Express 5.843s (+27.4% 🔺) 7.349s (+22.0% 🔺) 0.000s (NaN%) 7.881s (+22.1% 🔺) 2.039s 8 1.00x
▲ Vercel Nitro 6.140s (+50.0% 🔺) 7.289s (+35.6% 🔺) 0.000s (-54.2% 🟢) 8.368s (+44.4% 🔺) 2.228s 8 1.05x
▲ Vercel Next.js (Turbopack) 9.992s (+77.9% 🔺) 10.778s (+54.4% 🔺) 0.000s (-100.0% 🟢) 12.503s (+65.8% 🔺) 2.511s 5 1.71x

🔍 Observability: Express | Nitro | Next.js (Turbopack)

Summary

Fastest Framework by World

Winner determined by most benchmark wins

World 🥇 Fastest Framework Wins
💻 Local Express 16/21
🐘 Postgres Express 14/21
▲ Vercel Express 12/21
Fastest World by Framework

Winner determined by most benchmark wins

Framework 🥇 Fastest World Wins
Express 🐘 Postgres 15/21
Next.js (Turbopack) ▲ Vercel 21/21
Nitro 🐘 Postgres 19/21
Column Definitions
  • Workflow Time: Runtime reported by workflow (completedAt - createdAt) - primary metric
  • TTFB: Time to First Byte - time from workflow start until first stream byte received (stream benchmarks only)
  • Slurp: Time from first byte to complete stream consumption (stream benchmarks only)
  • Wall Time: Total testbench time (trigger workflow + poll for result)
  • Overhead: Testbench overhead (Wall Time - Workflow Time)
  • Samples: Number of benchmark iterations run
  • vs Fastest: How much slower compared to the fastest configuration for this benchmark

Worlds:

  • 💻 Local: In-memory filesystem world (local development)
  • 🐘 Postgres: PostgreSQL database world (local development)
  • ▲ Vercel: Vercel production/preview deployment
  • 🌐 Turso: Community world (local development)
  • 🌐 MongoDB: Community world (local development)
  • 🌐 Redis: Community world (local development)
  • 🌐 Jazz: Community world (local development)

📋 View full workflow run

@TooTallNate TooTallNate merged commit 254482e into main May 5, 2026
111 of 114 checks passed
@TooTallNate TooTallNate deleted the backport-signed-commits-via-graphql branch May 5, 2026 08:12
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 5, 2026

No backport to stable for 254482e (AI decision).

This commit only modifies .github/workflows/backport.yml, which is the backport workflow itself. The backport workflow runs on main and pushes to stable, so it doesn't need to exist on stable at all. Backporting changes to the backport workflow would have no effect.

To override, add the backport-stable label to this PR.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the backport.yml workflow to avoid branch ruleset rejections that require verified-signed commits on all refs. Instead of pushing a locally cherry-picked commit (unsigned in CI), it replays the cherry-pick via GitHub’s GraphQL createCommitOnBranch mutation so GitHub produces a verified-signed commit on the backport branch.

Changes:

  • Replace git push with a GitHub API–based branch update using GraphQL createCommitOnBranch (auto-signed commits).
  • Improve robustness of PR creation by reusing an existing open backport PR for the same branch instead of failing.
  • Update manual conflict-resolution instructions to require signed local cherry-picks (git cherry-pick -S) due to repo rulesets.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +549 to +555
const [, mode, type, blobSha] = match;
if (type !== 'blob') {
throw new Error(
`Unsupported tree entry for ${path}: type=${type} mode=${mode}. ` +
`GraphQL createCommitOnBranch only supports regular files.`,
);
}
Comment on lines +522 to +526
const diffOutput = git(
'diff',
'--name-status',
'-z',
parentSha,
pranaygp added a commit that referenced this pull request May 5, 2026
* origin/main:
  feat: serializable AbortController/AbortSignal (#1301)
  Auto-remove workflow packages from serverExternalPackages (#1481)
  Add missing changeset for Zod 4.4.x compatibility fix in @workflow/world (#1939)
  Push backport branch via GraphQL createCommitOnBranch for signed commits (#1937)
  Fix backport workflow opencode permission and surface AI failures (#1936)
  Restructure backport workflow with AI-driven decisions (#1934)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants