@@ -11,6 +11,7 @@ import { CodeJSON, BasicRepoInfo } from "./model.js";
1111const execAsync = promisify ( exec ) ;
1212
1313const TOKEN = core . getInput ( "GITHUB_TOKEN" , { required : true } ) ;
14+ const ADMIN_TOKEN = core . getInput ( "ADMIN_TOKEN" , { required : false } ) ;
1415
1516const MyOctoKit = ActionKit . plugin ( createPullRequest ) ;
1617const octokit = new MyOctoKit ( {
@@ -23,6 +24,18 @@ const octokit = new MyOctoKit({
2324 } ,
2425} ) ;
2526
27+ const adminOctokit = ADMIN_TOKEN
28+ ? new MyOctoKit ( {
29+ auth : ADMIN_TOKEN ,
30+ log : {
31+ debug : core . debug ,
32+ info : core . info ,
33+ warn : core . warning ,
34+ error : core . error ,
35+ } ,
36+ } )
37+ : null ;
38+
2639const owner = process . env . GITHUB_REPOSITORY_OWNER ?? "" ;
2740const repo = process . env . GITHUB_REPOSITORY ?. split ( "/" ) [ 1 ] ?? "" ;
2841
@@ -170,6 +183,7 @@ export async function sendPR(
170183
171184 core . setOutput ( "updated" , true ) ;
172185 core . setOutput ( "pr_url" , PR . data . html_url ) ;
186+ core . setOutput ( "method_used" , "pull_request" ) ;
173187 } else {
174188 core . error ( `Failed to create PR because of PR object` ) ;
175189 core . setOutput ( "updated" , false ) ;
@@ -179,6 +193,85 @@ export async function sendPR(
179193 }
180194}
181195
196+ async function pushDirectlyWithPAT (
197+ updatedCodeJSON : CodeJSON ,
198+ baseBranchName : string ,
199+ ) : Promise < boolean > {
200+ if ( ! adminOctokit ) {
201+ core . error ( "Admin token not provided for direct push" ) ;
202+ return false ;
203+ }
204+
205+ try {
206+ const formattedContent = JSON . stringify ( updatedCodeJSON , null , 2 ) ;
207+
208+ let currentFileSha : string | undefined ;
209+ try {
210+ const currentFile = await adminOctokit . rest . repos . getContent ( {
211+ owner,
212+ repo,
213+ path : "code.json" ,
214+ ref : baseBranchName ,
215+ } ) ;
216+
217+ if ( "sha" in currentFile . data ) {
218+ currentFileSha = currentFile . data . sha ;
219+ }
220+ } catch ( error ) {
221+ core . info ( "code.json doesn't exist yet, will create new file" ) ;
222+ }
223+
224+ const result = await adminOctokit . rest . repos . createOrUpdateFileContents ( {
225+ owner,
226+ repo,
227+ path : "code.json" ,
228+ message : "Update code.json metadata" ,
229+ content : Buffer . from ( formattedContent ) . toString ( "base64" ) ,
230+ branch : baseBranchName ,
231+ sha : currentFileSha ,
232+ } ) ;
233+
234+ core . info ( `Successfully pushed commit with PAT: ${ result . data . commit . sha } ` ) ;
235+
236+ core . setOutput ( "updated" , true ) ;
237+ core . setOutput ( "commit_sha" , result . data . commit . sha ) ;
238+ core . setOutput ( "method_used" , "direct_push" ) ;
239+ return true ;
240+ } catch ( error ) {
241+ core . error ( `Failed to push directly with PAT: ${ error } ` ) ;
242+ return false ;
243+ }
244+ }
245+
246+ export async function pushDirectlyWithFallback (
247+ updatedCodeJSON : CodeJSON ,
248+ baseBranchName : string ,
249+ ) {
250+ if ( ! ADMIN_TOKEN ) {
251+ core . error (
252+ "SKIP_PR is enabled but ADMIN_TOKEN is not provided. Direct push requires an admin PAT." ,
253+ ) ;
254+ core . info ( "Falling back to creating a pull request" ) ;
255+
256+ await sendPR ( updatedCodeJSON , baseBranchName ) ;
257+ return ;
258+ }
259+
260+ core . info ( "Attempting direct push with admin PAT!" ) ;
261+
262+ const directPushSuccess = await pushDirectlyWithPAT (
263+ updatedCodeJSON ,
264+ baseBranchName ,
265+ ) ;
266+
267+ if ( ! directPushSuccess ) {
268+ core . info (
269+ "Direct push with PAT failed, falling back to creating a pull request" ,
270+ ) ;
271+ await sendPR ( updatedCodeJSON , baseBranchName ) ;
272+ }
273+ }
274+
182275function bodyOfPR ( ) : string {
183276 return `
184277 ## Welcome to the Federal Open Source Community!
0 commit comments