1- import { getRepositoryMetadata } from "./github/graphql/queries.js" ;
2- import type { GetRepositoryMetadataQuery } from "./github/graphql/generated/operations.js" ;
1+ import {
2+ createCommitOnBranchQuery ,
3+ createRefMutation ,
4+ getRepositoryMetadata ,
5+ updateRefMutation ,
6+ } from "./github/graphql/queries.js" ;
7+ import type {
8+ CreateCommitOnBranchMutationVariables ,
9+ GetRepositoryMetadataQuery ,
10+ } from "./github/graphql/generated/operations.js" ;
311import {
412 CommitFilesFromBase64Args ,
513 CommitFilesResult ,
@@ -41,15 +49,12 @@ const getOidFromRef = (
4149
4250const createCommit = async ( {
4351 octokit,
44- owner,
45- repo,
52+ refId,
4653 baseOid,
4754 message,
4855 fileChanges,
49- } : Pick <
50- CommitFilesFromBase64Args ,
51- "octokit" | "owner" | "repo" | "message" | "fileChanges"
52- > & {
56+ } : Pick < CommitFilesFromBase64Args , "octokit" | "message" | "fileChanges" > & {
57+ refId : string ;
5358 baseOid : string ;
5459} ) => {
5560 const normalizedMessage : CommitMessage =
@@ -60,52 +65,15 @@ const createCommit = async ({
6065 }
6166 : message ;
6267
63- const additions = await Promise . all (
64- ( fileChanges . additions ?? [ ] ) . map ( async ( { path, contents } ) => {
65- const blob = await octokit . rest . git . createBlob ( {
66- owner,
67- repo,
68- content : contents ,
69- encoding : "base64" ,
70- } ) ;
71-
72- return {
73- path,
74- mode : "100644" as const ,
75- type : "blob" as const ,
76- sha : blob . data . sha ,
77- } ;
78- } ) ,
79- ) ;
80-
81- const deletions = ( fileChanges . deletions ?? [ ] ) . map ( ( { path } ) => ( {
82- path,
83- mode : "100644" as const ,
84- type : "blob" as const ,
85- sha : null ,
86- } ) ) ;
87-
88- const baseCommit = await octokit . rest . git . getCommit ( {
89- owner,
90- repo,
91- commit_sha : baseOid ,
92- } ) ;
93-
94- const tree = await octokit . rest . git . createTree ( {
95- owner,
96- repo,
97- base_tree : baseCommit . data . tree . sha ,
98- tree : [ ...additions , ...deletions ] ,
99- } ) ;
100-
101- return octokit . rest . git . createCommit ( {
102- owner,
103- repo,
104- message : normalizedMessage . body ?. trim ( )
105- ? `${ normalizedMessage . headline } \n\n${ normalizedMessage . body . trim ( ) } `
106- : normalizedMessage . headline ,
107- tree : tree . data . sha ,
108- parents : [ baseOid ] ,
68+ return createCommitOnBranchQuery ( octokit , {
69+ input : {
70+ branch : {
71+ id : refId ,
72+ } ,
73+ expectedHeadOid : baseOid ,
74+ message : normalizedMessage ,
75+ fileChanges,
76+ } ,
10977 } ) ;
11078} ;
11179
@@ -142,6 +110,8 @@ export const commitFilesFromBase64 = async ({
142110 throw new Error ( `Ref ${ JSON . stringify ( baseRef ) } not found` ) ;
143111 }
144112
113+ const resolvedBaseRef = info . baseRef ;
114+
145115 /**
146116 * The commit oid to base the new commit on.
147117 *
@@ -151,6 +121,7 @@ export const commitFilesFromBase64 = async ({
151121 const baseOid = getOidFromRef ( base , info . baseRef ) ;
152122 const targetOid = info . targetBranch ?. target ?. oid ?? null ;
153123 const sameBranchBase = "branch" in base && base . branch === branch ;
124+ const repositoryId = info . id ;
154125
155126 let mode : "create" | "update" | "force-update" ;
156127
@@ -169,38 +140,54 @@ export const commitFilesFromBase64 = async ({
169140 ) ;
170141 }
171142
143+ let refId : string ;
144+
145+ if ( mode === "create" ) {
146+ const createdRef = await createRefMutation ( octokit , {
147+ input : {
148+ repositoryId,
149+ name : `refs/heads/${ branch } ` ,
150+ oid : baseOid ,
151+ } ,
152+ } ) ;
153+
154+ const refIdStr = createdRef . createRef ?. ref ?. id ;
155+
156+ if ( ! refIdStr ) {
157+ throw new Error ( `Failed to create branch ${ branch } ` ) ;
158+ }
159+
160+ refId = refIdStr ;
161+ } else if ( mode === "force-update" ) {
162+ const updatedRef = await updateRefMutation ( octokit , {
163+ input : {
164+ refId : sameBranchBase ? resolvedBaseRef ! . id : info . targetBranch ! . id ,
165+ oid : baseOid ,
166+ force : true ,
167+ } ,
168+ } ) ;
169+
170+ const refIdStr = updatedRef . updateRef ?. ref ?. id ;
171+
172+ if ( ! refIdStr ) {
173+ throw new Error ( `Failed to update branch ${ branch } ` ) ;
174+ }
175+
176+ refId = refIdStr ;
177+ } else {
178+ refId = sameBranchBase ? resolvedBaseRef ! . id : info . targetBranch ! . id ;
179+ }
180+
172181 await log ?. debug ( `Creating commit on branch ${ branch } ` ) ;
173182 const newCommit = await createCommit ( {
174183 octokit,
175- owner,
176- repo,
184+ refId,
177185 baseOid,
178186 message,
179187 fileChanges,
180188 } ) ;
181189
182- if ( mode !== "create" ) {
183- const updatedRef = await octokit . rest . git . updateRef ( {
184- owner,
185- repo,
186- ref : `heads/${ branch } ` ,
187- sha : newCommit . data . sha ,
188- force : mode === "force-update" ,
189- } ) ;
190-
191- return {
192- refId : updatedRef . data . node_id ?? null ,
193- } ;
194- }
195-
196- const createdRef = await octokit . rest . git . createRef ( {
197- owner,
198- repo,
199- ref : `refs/heads/${ branch } ` ,
200- sha : newCommit . data . sha ,
201- } ) ;
202-
203190 return {
204- refId : createdRef . data . node_id ?? null ,
191+ refId : newCommit . createCommitOnBranch ?. ref ?. id ?? null ,
205192 } ;
206193} ;
0 commit comments