diff --git a/.changeset/update-pr-draft-only.md b/.changeset/update-pr-draft-only.md new file mode 100644 index 0000000..666f2d3 --- /dev/null +++ b/.changeset/update-pr-draft-only.md @@ -0,0 +1,5 @@ +--- +'@github-tools/sdk': patch +--- + +Skip the REST update when `updatePullRequest` is called with only `draft`. Octokit was sending an empty PATCH body (`''`), which GitHub rejects with 400 before the GraphQL draft mutation could run. diff --git a/packages/github-tools/src/core/pull-requests.ts b/packages/github-tools/src/core/pull-requests.ts index f7b5efe..8bcb1f6 100644 --- a/packages/github-tools/src/core/pull-requests.ts +++ b/packages/github-tools/src/core/pull-requests.ts @@ -128,7 +128,10 @@ export const updatePullRequestDescription = 'Update a pull request — title, bo /** Not idempotent — each call applies a new revision. */ export async function updatePullRequestCore({ token, owner, repo, pullNumber, title, body, state, base, draft }: { token: string, owner: string, repo: string, pullNumber: number, title?: string, body?: string, state?: 'open' | 'closed', base?: string, draft?: boolean }) { const octokit = createOctokit(token) - const { data } = await octokit.rest.pulls.update({ owner, repo, pull_number: pullNumber, title, body, state, base }) + const hasRestUpdate = title !== undefined || body !== undefined || state !== undefined || base !== undefined + const { data } = hasRestUpdate + ? await octokit.rest.pulls.update({ owner, repo, pull_number: pullNumber, title, body, state, base }) + : await octokit.rest.pulls.get({ owner, repo, pull_number: pullNumber }) if (draft !== undefined && draft !== data.draft) { await octokit.graphql(draft ? CONVERT_TO_DRAFT_MUTATION : MARK_READY_FOR_REVIEW_MUTATION, { pullRequestId: data.node_id }) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9075f2a..4830854 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -7,6 +7,7 @@ settings: overrides: '@ai-sdk/vue>ai': 7.0.70 '@ai-sdk/workflow>ai': 7.0.70 + undici@5: 6.28.0 importers: @@ -1589,10 +1590,6 @@ packages: '@fastify/accept-negotiator@2.0.1': resolution: {integrity: sha512-/c/TW2bO/v9JeEgoD/g1G5GxGeCF1Hafdf79WPmUlgYiBXummY0oX3VVq4yFkKKVBKDNlaDUYoab7g38RpPqCQ==} - '@fastify/busboy@2.1.1': - resolution: {integrity: sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==} - engines: {node: '>=14'} - '@fingerprintjs/botd@2.0.0': resolution: {integrity: sha512-yhuz23NKEcBDTHmGz/ULrXlGnbHenO+xZmVwuBkuqHUkqvaZ5TAA0kAgcRy4Wyo5dIBdkIf57UXX8/c9UlMLJg==} @@ -11110,10 +11107,6 @@ packages: undici-types@8.3.0: resolution: {integrity: sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ==} - undici@5.29.0: - resolution: {integrity: sha512-raqeBD6NQK4SkWhQzeYKd1KmIG6dllBOTt55Rmkt4HtI9mwdWtJljnrXjAFUBLTSN67HWrOIZ3EPF4kjUw80Bg==} - engines: {node: '>=14.0'} - undici@6.28.0: resolution: {integrity: sha512-LIY910g9TI13YS95lrMFrs8Rm/u/irgHeTWoKCoteeJ04CUJ92eEfj0rVn+7VKMPBpUPiUoBKfhNyLI23EE/KA==} engines: {node: '>=18.17'} @@ -12131,7 +12124,7 @@ snapshots: '@ai-sdk/provider': 3.0.14 '@standard-schema/spec': 1.1.0 eventsource-parser: 3.1.0 - undici: 5.29.0 + undici: 6.28.0 zod: 4.3.6 optional: true @@ -12140,7 +12133,7 @@ snapshots: '@ai-sdk/provider': 3.0.14 '@standard-schema/spec': 1.1.0 eventsource-parser: 3.1.0 - undici: 5.29.0 + undici: 6.28.0 zod: 4.4.3 '@ai-sdk/provider-utils@5.0.21(zod@4.4.3)': @@ -13289,8 +13282,6 @@ snapshots: '@fastify/accept-negotiator@2.0.1': optional: true - '@fastify/busboy@2.1.1': {} - '@fingerprintjs/botd@2.0.0': {} '@floating-ui/core@1.8.0': @@ -26278,10 +26269,6 @@ snapshots: undici-types@8.3.0: {} - undici@5.29.0: - dependencies: - '@fastify/busboy': 2.1.1 - undici@6.28.0: {} undici@7.26.0: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 5e25354..0ef5e01 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -35,4 +35,5 @@ minimumReleaseAgeExclude: overrides: '@ai-sdk/vue>ai': 7.0.70 '@ai-sdk/workflow>ai': 7.0.70 + 'undici@5': 6.28.0