Skip to content

Commit 6a1638a

Browse files
feat: ✨ Use GraphQL API for signed empty commits (#787)
1 parent aa0070f commit 6a1638a

File tree

2 files changed

+43
-47
lines changed

2 files changed

+43
-47
lines changed

src/github.js

Lines changed: 24 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -225,33 +225,6 @@ async function getBranchHeadSha (ctx, branch) {
225225
}
226226
}
227227

228-
async function getCommitTreeSha (ctx, commitSha) {
229-
const owner = context.getRepoOwnerLogin(ctx)
230-
const repo = context.getRepoName(ctx)
231-
const res = await ctx.octokit.git.getCommit({ owner, repo, commit_sha: commitSha })
232-
return res.data.tree.sha
233-
}
234-
235-
async function createCommit (ctx, commitSha, treeSha, username, message) {
236-
const owner = context.getRepoOwnerLogin(ctx)
237-
const repo = context.getRepoName(ctx)
238-
const res = await ctx.octokit.git.createCommit({
239-
owner,
240-
repo,
241-
message,
242-
tree: treeSha,
243-
parents: [commitSha],
244-
author: { name: username, email: `${username}@users.noreply.github.com` }
245-
})
246-
return res.data.sha
247-
}
248-
249-
async function updateReference (ctx, branchName, sha) {
250-
const owner = context.getRepoOwnerLogin(ctx)
251-
const repo = context.getRepoName(ctx)
252-
await ctx.octokit.git.updateRef({ owner, repo, ref: `heads/${branchName}`, sha })
253-
}
254-
255228
async function createBranch (ctx, config, branchName, sha, log) {
256229
const owner = context.getRepoOwnerLogin(ctx)
257230
const repo = context.getRepoName(ctx)
@@ -289,9 +262,7 @@ async function createPr (app, ctx, config, username, branchName) {
289262
const branchHeadSha = await getBranchHeadSha(ctx, branchName)
290263
if (branchHeadSha === baseHeadSha) {
291264
app.log('Branch and base heads are equal, creating empty commit for PR')
292-
const treeSha = await getCommitTreeSha(ctx, branchHeadSha)
293-
const emptyCommitSha = await createCommit(ctx, branchHeadSha, treeSha, username, getCommitText(ctx, config))
294-
await updateReference(ctx, branchName, emptyCommitSha)
265+
await createEmptyCommit(ctx, branchName, getCommitText(ctx, config), branchHeadSha)
295266
}
296267
const { data: pr } = await ctx.octokit.pulls.create(
297268
{ owner, repo, head: branchName, base, title, body: getPrBody(app, ctx, config), draft: draft })
@@ -303,6 +274,29 @@ async function createPr (app, ctx, config, username, branchName) {
303274
}
304275
}
305276

277+
async function createEmptyCommit (ctx, branchName, message, headSha) {
278+
const owner = context.getRepoOwnerLogin(ctx)
279+
const repo = context.getRepoName(ctx)
280+
const createEptyCommitMutation = `
281+
mutation($repositoryNameWithOwner: String!, $branchName: String!, $message: String!, $headSha: GitObjectID!) {
282+
createCommitOnBranch(
283+
input: {
284+
branch: {repositoryNameWithOwner: $repositoryNameWithOwner, branchName: $branchName},
285+
message: {headline: $message},
286+
fileChanges: {},
287+
expectedHeadOid: $headSha
288+
}
289+
) {
290+
commit {
291+
url
292+
}
293+
}
294+
}`
295+
await ctx.octokit.graphql(createEptyCommitMutation, {
296+
repositoryNameWithOwner: `${owner}/${repo}`, branchName: branchName, message: message, headSha: headSha
297+
})
298+
}
299+
306300
function getCommitText (ctx, config) {
307301
const draft = Config.shouldOpenDraftPR(config)
308302
const draftText = draft ? 'draft ' : ''

tests/github.test.js

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -203,13 +203,11 @@ test('Retry create comment when it fails', async () => {
203203
test('create (draft) PR', async () => {
204204
const createPR = jest.fn()
205205
let capturedCommitMessage = ''
206-
const createCommit = ({ message }) => {
207-
capturedCommitMessage = message
208-
return ({ data: { sha: 'abcd1234' } })
209-
}
210206
const ctx = helpers.getDefaultContext()
211207
ctx.octokit.pulls.create = createPR
212-
ctx.octokit.git.createCommit = createCommit
208+
ctx.octokit.graphql = (_, { message }) => {
209+
capturedCommitMessage = message
210+
}
213211

214212
await github.createPr({ log: () => { } }, ctx, { silent: false }, 'robvanderleek', 'issue-1')
215213
expect(createPR).toHaveBeenCalledWith({
@@ -237,11 +235,10 @@ test('create (draft) PR', async () => {
237235

238236
test('copy Issue description into PR', async () => {
239237
const createPR = jest.fn()
240-
const createCommit = () => ({ data: { sha: 'abcd1234' } })
241238
const ctx = helpers.getDefaultContext()
242239
ctx.octokit.pulls.create = createPR
243-
ctx.octokit.git.createCommit = createCommit
244240
ctx.payload.issue.body = 'This is the description'
241+
ctx.octokit.graphql = jest.fn()
245242

246243
await github.createPr({ log: () => { } }, ctx, { copyIssueDescriptionToPR: true, silent: false }, 'robvanderleek',
247244
'issue-1')
@@ -259,11 +256,10 @@ test('copy Issue description into PR', async () => {
259256

260257
test('Do not copy undefined Issue description into PR', async () => {
261258
const createPR = jest.fn()
262-
const createCommit = () => ({ data: { sha: 'abcd1234' } })
263259
const ctx = helpers.getDefaultContext()
264260
ctx.octokit.pulls.create = createPR
265-
ctx.octokit.git.createCommit = createCommit
266261
ctx.payload.issue.body = null
262+
ctx.octokit.graphql = jest.fn()
267263

268264
await github.createPr({ log: () => { } }, ctx, { copyIssueDescriptionToPR: true, silent: false }, 'robvanderleek',
269265
'issue-1')
@@ -282,6 +278,7 @@ test('use correct source branch', async () => {
282278
const createPR = jest.fn()
283279
const ctx = helpers.getDefaultContext()
284280
ctx.octokit.pulls.create = createPR
281+
ctx.octokit.graphql = jest.fn()
285282
ctx.payload.issue.labels = [{ name: 'enhancement' }]
286283
const config = { branches: [{ label: 'enhancement', name: 'develop' }] }
287284

@@ -301,6 +298,7 @@ test('use configured target branch', async () => {
301298
const createPR = jest.fn()
302299
const ctx = helpers.getDefaultContext()
303300
ctx.octokit.pulls.create = createPR
301+
ctx.octokit.graphql = jest.fn()
304302
ctx.payload.issue.labels = [{ name: 'enhancement' }]
305303
const config = { branches: [{ label: 'enhancement', prTarget: 'develop' }] }
306304

@@ -320,6 +318,7 @@ test('configured source and target branch', async () => {
320318
const createPR = jest.fn()
321319
const ctx = helpers.getDefaultContext()
322320
ctx.octokit.pulls.create = createPR
321+
ctx.octokit.graphql = jest.fn()
323322
ctx.payload.issue.labels = [{ name: 'hotfix' }]
324323
const config = { branches: [{ label: 'hotfix', name: 'develop', prTarget: 'hotfix' }] }
325324

@@ -337,11 +336,10 @@ test('configured source and target branch', async () => {
337336

338337
test('copy Issue milestone into PR', async () => {
339338
const updateIssue = jest.fn()
340-
const createCommit = () => ({ data: { sha: 'abcd1234' } })
341339
const ctx = helpers.getDefaultContext()
342340
ctx.octokit.pulls.create = () => ({ data: { number: 123 } })
343341
ctx.octokit.issues.update = updateIssue
344-
ctx.octokit.git.createCommit = createCommit
342+
ctx.octokit.graphql = jest.fn()
345343
ctx.payload.issue.body = 'This is the description'
346344
ctx.payload.issue.milestone = { number: 456 }
347345

@@ -353,27 +351,31 @@ test('copy Issue milestone into PR', async () => {
353351
})
354352

355353
test('empty commit text', async () => {
356-
const createCommit = jest.fn()
357354
const ctx = helpers.getDefaultContext()
358355
ctx.octokit.pulls.create = () => ({ data: { number: 123 } })
359-
ctx.octokit.git.createCommit = createCommit
356+
let capturedCommitMessage = ''
357+
ctx.octokit.graphql = (_, { message }) => {
358+
capturedCommitMessage = message
359+
}
360360
ctx.payload.issue.body = 'This is the description'
361361
ctx.payload.issue.milestone = { number: 456 }
362362

363363
await github.createPr({ log: () => { } }, ctx, {}, 'robvanderleek', 'issue-1')
364364

365-
expect(createCommit.mock.calls[0][0].message).toBe('Create PR for #1')
365+
expect(capturedCommitMessage).toBe('Create PR for #1')
366366
})
367367

368368
test('empty commit with skip CI text', async () => {
369-
const createCommit = jest.fn()
370369
const ctx = helpers.getDefaultContext()
371370
ctx.octokit.pulls.create = () => ({ data: { number: 123 } })
372-
ctx.octokit.git.createCommit = createCommit
371+
let capturedCommitMessage = ''
372+
ctx.octokit.graphql = (_, { message }) => {
373+
capturedCommitMessage = message
374+
}
373375
ctx.payload.issue.body = 'This is the description'
374376
ctx.payload.issue.milestone = { number: 456 }
375377

376378
await github.createPr({ log: () => { } }, ctx, { prSkipCI: true }, 'robvanderleek', 'issue-1')
377379

378-
expect(createCommit.mock.calls[0][0].message).toBe('Create PR for #1\n[skip ci]')
380+
expect(capturedCommitMessage).toBe('Create PR for #1\n[skip ci]')
379381
})

0 commit comments

Comments
 (0)