/
index.js
13183 lines (11589 loc) · 688 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/******/ (() => { // webpackBootstrap
/******/ var __webpack_modules__ = ({
/***/ 8363:
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.createOrUpdateBranch = exports.tryFetch = exports.getWorkingBaseAndType = exports.WorkingBaseType = void 0;
const core = __importStar(__nccwpck_require__(2186));
const uuid_1 = __nccwpck_require__(5840);
const CHERRYPICK_EMPTY = 'The previous cherry-pick is now empty, possibly due to conflict resolution.';
var WorkingBaseType;
(function (WorkingBaseType) {
WorkingBaseType["Branch"] = "branch";
WorkingBaseType["Commit"] = "commit";
})(WorkingBaseType = exports.WorkingBaseType || (exports.WorkingBaseType = {}));
function getWorkingBaseAndType(git) {
return __awaiter(this, void 0, void 0, function* () {
const symbolicRefResult = yield git.exec(['symbolic-ref', 'HEAD', '--short'], true);
if (symbolicRefResult.exitCode == 0) {
// A ref is checked out
return [symbolicRefResult.stdout.trim(), WorkingBaseType.Branch];
}
else {
// A commit is checked out (detached HEAD)
const headSha = yield git.revParse('HEAD');
return [headSha, WorkingBaseType.Commit];
}
});
}
exports.getWorkingBaseAndType = getWorkingBaseAndType;
function tryFetch(git, remote, branch) {
return __awaiter(this, void 0, void 0, function* () {
try {
yield git.fetch([`${branch}:refs/remotes/${remote}/${branch}`], remote);
return true;
}
catch (_a) {
return false;
}
});
}
exports.tryFetch = tryFetch;
// Return true if branch2 is ahead of branch1
function isAhead(git, branch1, branch2) {
return __awaiter(this, void 0, void 0, function* () {
const result = yield git.revList([`${branch1}...${branch2}`], ['--right-only', '--count']);
return Number(result) > 0;
});
}
// Return true if branch2 is behind branch1
function isBehind(git, branch1, branch2) {
return __awaiter(this, void 0, void 0, function* () {
const result = yield git.revList([`${branch1}...${branch2}`], ['--left-only', '--count']);
return Number(result) > 0;
});
}
// Return true if branch2 is even with branch1
function isEven(git, branch1, branch2) {
return __awaiter(this, void 0, void 0, function* () {
return (!(yield isAhead(git, branch1, branch2)) &&
!(yield isBehind(git, branch1, branch2)));
});
}
function splitLines(multilineString) {
return multilineString
.split('\n')
.map(s => s.trim())
.filter(x => x !== '');
}
function createOrUpdateBranch(git, commitMessage, base, branch, branchRemoteName, signoff, addPaths) {
return __awaiter(this, void 0, void 0, function* () {
// Get the working base.
// When a ref, it may or may not be the actual base.
// When a commit, we must rebase onto the actual base.
const [workingBase, workingBaseType] = yield getWorkingBaseAndType(git);
core.info(`Working base is ${workingBaseType} '${workingBase}'`);
if (workingBaseType == WorkingBaseType.Commit && !base) {
throw new Error(`When in 'detached HEAD' state, 'base' must be supplied.`);
}
// If the base is not specified it is assumed to be the working base.
base = base ? base : workingBase;
const baseRemote = 'origin';
// Set the default return values
const result = {
action: 'none',
base: base,
hasDiffWithBase: false,
headSha: ''
};
// Save the working base changes to a temporary branch
const tempBranch = (0, uuid_1.v4)();
yield git.checkout(tempBranch, 'HEAD');
// Commit any uncommitted changes
if (yield git.isDirty(true, addPaths)) {
core.info('Uncommitted changes found. Adding a commit.');
const aopts = ['add'];
if (addPaths.length > 0) {
aopts.push(...['--', ...addPaths]);
}
else {
aopts.push('-A');
}
yield git.exec(aopts, true);
const popts = ['-m', commitMessage];
if (signoff) {
popts.push('--signoff');
}
yield git.commit(popts);
}
// Remove uncommitted tracked and untracked changes
yield git.exec(['reset', '--hard']);
yield git.exec(['clean', '-f', '-d']);
// Perform fetch and reset the working base
// Commits made during the workflow will be removed
if (workingBaseType == WorkingBaseType.Branch) {
core.info(`Resetting working base branch '${workingBase}'`);
if (branchRemoteName == 'fork') {
// If pushing to a fork we must fetch with 'unshallow' to avoid the following error on git push
// ! [remote rejected] HEAD -> tests/push-branch-to-fork (shallow update not allowed)
yield git.fetch([`${workingBase}:${workingBase}`], baseRemote, [
'--force'
]);
}
else {
// If the remote is 'origin' we can git reset
yield git.checkout(workingBase);
yield git.exec(['reset', '--hard', `${baseRemote}/${workingBase}`]);
}
}
// If the working base is not the base, rebase the temp branch commits
// This will also be true if the working base type is a commit
if (workingBase != base) {
core.info(`Rebasing commits made to ${workingBaseType} '${workingBase}' on to base branch '${base}'`);
// Checkout the actual base
yield git.fetch([`${base}:${base}`], baseRemote, ['--force']);
yield git.checkout(base);
// Cherrypick commits from the temporary branch starting from the working base
const commits = yield git.revList([`${workingBase}..${tempBranch}`, '.'], ['--reverse']);
for (const commit of splitLines(commits)) {
const result = yield git.cherryPick(['--strategy=recursive', '--strategy-option=theirs', commit], true);
if (result.exitCode != 0 && !result.stderr.includes(CHERRYPICK_EMPTY)) {
throw new Error(`Unexpected error: ${result.stderr}`);
}
}
// Reset the temp branch to the working index
yield git.checkout(tempBranch, 'HEAD');
// Reset the base
yield git.fetch([`${base}:${base}`], baseRemote, ['--force']);
}
// Try to fetch the pull request branch
if (!(yield tryFetch(git, branchRemoteName, branch))) {
// The pull request branch does not exist
core.info(`Pull request branch '${branch}' does not exist yet.`);
// Create the pull request branch
yield git.checkout(branch, tempBranch);
// Check if the pull request branch is ahead of the base
result.hasDiffWithBase = yield isAhead(git, base, branch);
if (result.hasDiffWithBase) {
result.action = 'created';
core.info(`Created branch '${branch}'`);
}
else {
core.info(`Branch '${branch}' is not ahead of base '${base}' and will not be created`);
}
}
else {
// The pull request branch exists
core.info(`Pull request branch '${branch}' already exists as remote branch '${branchRemoteName}/${branch}'`);
// Checkout the pull request branch
yield git.checkout(branch);
// Reset the branch if one of the following conditions is true.
// - If the branch differs from the recreated temp branch.
// - If the recreated temp branch is not ahead of the base. This means there will be
// no pull request diff after the branch is reset. This will reset any undeleted
// branches after merging. In particular, it catches a case where the branch was
// squash merged but not deleted. We need to reset to make sure it doesn't appear
// to have a diff with the base due to different commits for the same changes.
// For changes on base this reset is equivalent to a rebase of the pull request branch.
if ((yield git.hasDiff([`${branch}..${tempBranch}`])) ||
!(yield isAhead(git, base, tempBranch))) {
core.info(`Resetting '${branch}'`);
// Alternatively, git switch -C branch tempBranch
yield git.checkout(branch, tempBranch);
}
// Check if the pull request branch has been updated
// If the branch was reset or updated it will be ahead
// It may be behind if a reset now results in no diff with the base
if (!(yield isEven(git, `${branchRemoteName}/${branch}`, branch))) {
result.action = 'updated';
core.info(`Updated branch '${branch}'`);
}
else {
result.action = 'not-updated';
core.info(`Branch '${branch}' is even with its remote and will not be updated`);
}
// Check if the pull request branch is ahead of the base
result.hasDiffWithBase = yield isAhead(git, base, branch);
}
// Get the pull request branch SHA
result.headSha = yield git.revParse('HEAD');
// Delete the temporary branch
yield git.exec(['branch', '--delete', '--force', tempBranch]);
return result;
});
}
exports.createOrUpdateBranch = createOrUpdateBranch;
/***/ }),
/***/ 3780:
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.createPullRequest = void 0;
const core = __importStar(__nccwpck_require__(2186));
const create_or_update_branch_1 = __nccwpck_require__(8363);
const github_helper_1 = __nccwpck_require__(446);
const git_command_manager_1 = __nccwpck_require__(738);
const git_auth_helper_1 = __nccwpck_require__(2565);
const utils = __importStar(__nccwpck_require__(918));
function createPullRequest(inputs) {
return __awaiter(this, void 0, void 0, function* () {
let gitAuthHelper;
try {
// Get the repository path
const repoPath = utils.getRepoPath(inputs.path);
// Create a git command manager
const git = yield git_command_manager_1.GitCommandManager.create(repoPath);
// Save and unset the extraheader auth config if it exists
core.startGroup('Save persisted git credentials');
gitAuthHelper = new git_auth_helper_1.GitAuthHelper(git);
yield gitAuthHelper.savePersistedAuth();
core.endGroup();
// Init the GitHub client
const githubHelper = new github_helper_1.GitHubHelper(inputs.token);
core.startGroup('Determining the base and head repositories');
// Determine the base repository from git config
const remoteUrl = yield git.tryGetRemoteUrl();
const baseRemote = utils.getRemoteDetail(remoteUrl);
// Determine the head repository; the target for the pull request branch
const branchRemoteName = inputs.pushToFork ? 'fork' : 'origin';
const branchRepository = inputs.pushToFork
? inputs.pushToFork
: baseRemote.repository;
if (inputs.pushToFork) {
// Check if the supplied fork is really a fork of the base
const parentRepository = yield githubHelper.getRepositoryParent(branchRepository);
if (parentRepository != baseRemote.repository) {
throw new Error(`Repository '${branchRepository}' is not a fork of '${baseRemote.repository}'. Unable to continue.`);
}
// Add a remote for the fork
const remoteUrl = utils.getRemoteUrl(baseRemote.protocol, branchRepository);
yield git.exec(['remote', 'add', 'fork', remoteUrl]);
}
core.endGroup();
core.info(`Pull request branch target repository set to ${branchRepository}`);
// Configure auth
if (baseRemote.protocol == 'HTTPS') {
core.startGroup('Configuring credential for HTTPS authentication');
yield gitAuthHelper.configureToken(inputs.token);
core.endGroup();
}
core.startGroup('Checking the base repository state');
const [workingBase, workingBaseType] = yield (0, create_or_update_branch_1.getWorkingBaseAndType)(git);
core.info(`Working base is ${workingBaseType} '${workingBase}'`);
// When in detached HEAD state (checked out on a commit), we need to
// know the 'base' branch in order to rebase changes.
if (workingBaseType == create_or_update_branch_1.WorkingBaseType.Commit && !inputs.base) {
throw new Error(`When the repository is checked out on a commit instead of a branch, the 'base' input must be supplied.`);
}
// If the base is not specified it is assumed to be the working base.
const base = inputs.base ? inputs.base : workingBase;
// Throw an error if the base and branch are not different branches
// of the 'origin' remote. An identically named branch in the `fork`
// remote is perfectly fine.
if (branchRemoteName == 'origin' && base == inputs.branch) {
throw new Error(`The 'base' and 'branch' for a pull request must be different branches. Unable to continue.`);
}
// For self-hosted runners the repository state persists between runs.
// This command prunes the stale remote ref when the pull request branch was
// deleted after being merged or closed. Without this the push using
// '--force-with-lease' fails due to "stale info."
// https://github.com/peter-evans/create-pull-request/issues/633
yield git.exec(['remote', 'prune', branchRemoteName]);
core.endGroup();
// Apply the branch suffix if set
if (inputs.branchSuffix) {
switch (inputs.branchSuffix) {
case 'short-commit-hash':
// Suffix with the short SHA1 hash
inputs.branch = `${inputs.branch}-${yield git.revParse('HEAD', [
'--short'
])}`;
break;
case 'timestamp':
// Suffix with the current timestamp
inputs.branch = `${inputs.branch}-${utils.secondsSinceEpoch()}`;
break;
case 'random':
// Suffix with a 7 character random string
inputs.branch = `${inputs.branch}-${utils.randomString()}`;
break;
default:
throw new Error(`Branch suffix '${inputs.branchSuffix}' is not a valid value. Unable to continue.`);
}
}
// Output head branch
core.info(`Pull request branch to create or update set to '${inputs.branch}'`);
// Configure the committer and author
core.startGroup('Configuring the committer and author');
const parsedAuthor = utils.parseDisplayNameEmail(inputs.author);
const parsedCommitter = utils.parseDisplayNameEmail(inputs.committer);
git.setIdentityGitOptions([
'-c',
`author.name=${parsedAuthor.name}`,
'-c',
`author.email=${parsedAuthor.email}`,
'-c',
`committer.name=${parsedCommitter.name}`,
'-c',
`committer.email=${parsedCommitter.email}`
]);
core.info(`Configured git committer as '${parsedCommitter.name} <${parsedCommitter.email}>'`);
core.info(`Configured git author as '${parsedAuthor.name} <${parsedAuthor.email}>'`);
core.endGroup();
// Create or update the pull request branch
core.startGroup('Create or update the pull request branch');
const result = yield (0, create_or_update_branch_1.createOrUpdateBranch)(git, inputs.commitMessage, inputs.base, inputs.branch, branchRemoteName, inputs.signoff, inputs.addPaths);
core.endGroup();
if (['created', 'updated'].includes(result.action)) {
// The branch was created or updated
core.startGroup(`Pushing pull request branch to '${branchRemoteName}/${inputs.branch}'`);
yield git.push([
'--force-with-lease',
branchRemoteName,
`HEAD:refs/heads/${inputs.branch}`
]);
core.endGroup();
}
// Set the base. It would have been '' if not specified as an input
inputs.base = result.base;
if (result.hasDiffWithBase) {
// Create or update the pull request
core.startGroup('Create or update the pull request');
const pull = yield githubHelper.createOrUpdatePullRequest(inputs, baseRemote.repository, branchRepository);
core.endGroup();
// Set outputs
core.startGroup('Setting outputs');
core.setOutput('pull-request-number', pull.number);
core.setOutput('pull-request-url', pull.html_url);
if (pull.created) {
core.setOutput('pull-request-operation', 'created');
}
else if (result.action == 'updated') {
core.setOutput('pull-request-operation', 'updated');
}
core.setOutput('pull-request-head-sha', result.headSha);
// Deprecated
core.exportVariable('PULL_REQUEST_NUMBER', pull.number);
core.endGroup();
}
else {
// There is no longer a diff with the base
// Check we are in a state where a branch exists
if (['updated', 'not-updated'].includes(result.action)) {
core.info(`Branch '${inputs.branch}' no longer differs from base branch '${inputs.base}'`);
if (inputs.deleteBranch) {
core.info(`Deleting branch '${inputs.branch}'`);
yield git.push([
'--delete',
'--force',
branchRemoteName,
`refs/heads/${inputs.branch}`
]);
// Set outputs
core.startGroup('Setting outputs');
core.setOutput('pull-request-operation', 'closed');
core.endGroup();
}
}
}
}
catch (error) {
core.setFailed(error.message);
}
finally {
// Remove auth and restore persisted auth config if it existed
core.startGroup('Restore persisted git credentials');
yield gitAuthHelper.removeAuth();
yield gitAuthHelper.restorePersistedAuth();
core.endGroup();
}
});
}
exports.createPullRequest = createPullRequest;
/***/ }),
/***/ 2565:
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.GitAuthHelper = void 0;
const core = __importStar(__nccwpck_require__(2186));
const fs = __importStar(__nccwpck_require__(7147));
const path = __importStar(__nccwpck_require__(1017));
const url_1 = __nccwpck_require__(7310);
class GitAuthHelper {
constructor(git) {
this.extraheaderConfigPlaceholderValue = 'AUTHORIZATION: basic ***';
this.extraheaderConfigValueRegex = '^AUTHORIZATION:';
this.persistedExtraheaderConfigValue = '';
this.git = git;
this.gitConfigPath = path.join(this.git.getWorkingDirectory(), '.git', 'config');
const serverUrl = this.getServerUrl();
this.extraheaderConfigKey = `http.${serverUrl.origin}/.extraheader`;
}
savePersistedAuth() {
return __awaiter(this, void 0, void 0, function* () {
// Save and unset persisted extraheader credential in git config if it exists
this.persistedExtraheaderConfigValue = yield this.getAndUnset();
});
}
restorePersistedAuth() {
return __awaiter(this, void 0, void 0, function* () {
if (this.persistedExtraheaderConfigValue) {
try {
yield this.setExtraheaderConfig(this.persistedExtraheaderConfigValue);
core.info('Persisted git credentials restored');
}
catch (e) {
core.warning(e);
}
}
});
}
configureToken(token) {
return __awaiter(this, void 0, void 0, function* () {
// Encode and configure the basic credential for HTTPS access
const basicCredential = Buffer.from(`x-access-token:${token}`, 'utf8').toString('base64');
core.setSecret(basicCredential);
const extraheaderConfigValue = `AUTHORIZATION: basic ${basicCredential}`;
yield this.setExtraheaderConfig(extraheaderConfigValue);
});
}
removeAuth() {
return __awaiter(this, void 0, void 0, function* () {
yield this.getAndUnset();
});
}
setExtraheaderConfig(extraheaderConfigValue) {
return __awaiter(this, void 0, void 0, function* () {
// Configure a placeholder value. This approach avoids the credential being captured
// by process creation audit events, which are commonly logged. For more information,
// refer to https://docs.microsoft.com/en-us/windows-server/identity/ad-ds/manage/component-updates/command-line-process-auditing
// See https://github.com/actions/checkout/blob/main/src/git-auth-helper.ts#L267-L274
yield this.git.config(this.extraheaderConfigKey, this.extraheaderConfigPlaceholderValue);
// Replace the placeholder
yield this.gitConfigStringReplace(this.extraheaderConfigPlaceholderValue, extraheaderConfigValue);
});
}
getAndUnset() {
return __awaiter(this, void 0, void 0, function* () {
let configValue = '';
// Save and unset persisted extraheader credential in git config if it exists
if (yield this.git.configExists(this.extraheaderConfigKey, this.extraheaderConfigValueRegex)) {
configValue = yield this.git.getConfigValue(this.extraheaderConfigKey, this.extraheaderConfigValueRegex);
if (yield this.git.tryConfigUnset(this.extraheaderConfigKey, this.extraheaderConfigValueRegex)) {
core.info(`Unset config key '${this.extraheaderConfigKey}'`);
}
else {
core.warning(`Failed to unset config key '${this.extraheaderConfigKey}'`);
}
}
return configValue;
});
}
gitConfigStringReplace(find, replace) {
return __awaiter(this, void 0, void 0, function* () {
let content = (yield fs.promises.readFile(this.gitConfigPath)).toString();
const index = content.indexOf(find);
if (index < 0 || index != content.lastIndexOf(find)) {
throw new Error(`Unable to replace '${find}' in ${this.gitConfigPath}`);
}
content = content.replace(find, replace);
yield fs.promises.writeFile(this.gitConfigPath, content);
});
}
getServerUrl() {
// todo: remove GITHUB_URL after support for GHES Alpha is no longer needed
// See https://github.com/actions/checkout/blob/main/src/url-helper.ts#L22-L29
return new url_1.URL(process.env['GITHUB_SERVER_URL'] ||
process.env['GITHUB_URL'] ||
'https://github.com');
}
}
exports.GitAuthHelper = GitAuthHelper;
/***/ }),
/***/ 738:
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.GitCommandManager = void 0;
const exec = __importStar(__nccwpck_require__(1514));
const io = __importStar(__nccwpck_require__(7436));
const utils = __importStar(__nccwpck_require__(918));
const path = __importStar(__nccwpck_require__(1017));
const tagsRefSpec = '+refs/tags/*:refs/tags/*';
class GitCommandManager {
constructor(workingDirectory, gitPath) {
this.workingDirectory = workingDirectory;
this.gitPath = gitPath;
}
static create(workingDirectory) {
return __awaiter(this, void 0, void 0, function* () {
const gitPath = yield io.which('git', true);
return new GitCommandManager(workingDirectory, gitPath);
});
}
setIdentityGitOptions(identityGitOptions) {
this.identityGitOptions = identityGitOptions;
}
checkout(ref, startPoint) {
return __awaiter(this, void 0, void 0, function* () {
const args = ['checkout', '--progress'];
if (startPoint) {
args.push('-B', ref, startPoint);
}
else {
args.push(ref);
}
// https://github.com/git/git/commit/a047fafc7866cc4087201e284dc1f53e8f9a32d5
args.push('--');
yield this.exec(args);
});
}
cherryPick(options, allowAllExitCodes = false) {
return __awaiter(this, void 0, void 0, function* () {
const args = ['cherry-pick'];
if (this.identityGitOptions) {
args.unshift(...this.identityGitOptions);
}
if (options) {
args.push(...options);
}
return yield this.exec(args, allowAllExitCodes);
});
}
commit(options) {
return __awaiter(this, void 0, void 0, function* () {
const args = ['commit'];
if (this.identityGitOptions) {
args.unshift(...this.identityGitOptions);
}
if (options) {
args.push(...options);
}
yield this.exec(args);
});
}
config(configKey, configValue, globalConfig) {
return __awaiter(this, void 0, void 0, function* () {
yield this.exec([
'config',
globalConfig ? '--global' : '--local',
configKey,
configValue
]);
});
}
configExists(configKey, configValue = '.', globalConfig) {
return __awaiter(this, void 0, void 0, function* () {
const output = yield this.exec([
'config',
globalConfig ? '--global' : '--local',
'--name-only',
'--get-regexp',
configKey,
configValue
], true);
return output.exitCode === 0;
});
}
fetch(refSpec, remoteName, options) {
return __awaiter(this, void 0, void 0, function* () {
const args = ['-c', 'protocol.version=2', 'fetch'];
if (!refSpec.some(x => x === tagsRefSpec)) {
args.push('--no-tags');
}
args.push('--progress', '--no-recurse-submodules');
if (utils.fileExistsSync(path.join(this.workingDirectory, '.git', 'shallow'))) {
args.push('--unshallow');
}
if (options) {
args.push(...options);
}
if (remoteName) {
args.push(remoteName);
}
else {
args.push('origin');
}
for (const arg of refSpec) {
args.push(arg);
}
yield this.exec(args);
});
}
getConfigValue(configKey, configValue = '.') {
return __awaiter(this, void 0, void 0, function* () {
const output = yield this.exec([
'config',
'--local',
'--get-regexp',
configKey,
configValue
]);
return output.stdout.trim().split(`${configKey} `)[1];
});
}
getWorkingDirectory() {
return this.workingDirectory;
}
hasDiff(options) {
return __awaiter(this, void 0, void 0, function* () {
const args = ['diff', '--quiet'];
if (options) {
args.push(...options);
}
const output = yield this.exec(args, true);
return output.exitCode === 1;
});
}
isDirty(untracked, pathspec) {
return __awaiter(this, void 0, void 0, function* () {
const pathspecArgs = pathspec ? ['--', ...pathspec] : [];
// Check untracked changes
const sargs = ['--porcelain', '-unormal'];
sargs.push(...pathspecArgs);
if (untracked && (yield this.status(sargs))) {
return true;
}
// Check working index changes
if (yield this.hasDiff(pathspecArgs)) {
return true;
}
// Check staged changes
const dargs = ['--staged'];
dargs.push(...pathspecArgs);
if (yield this.hasDiff(dargs)) {
return true;
}
return false;
});
}
push(options) {
return __awaiter(this, void 0, void 0, function* () {
const args = ['push'];
if (options) {
args.push(...options);
}
yield this.exec(args);
});
}
revList(commitExpression, options) {
return __awaiter(this, void 0, void 0, function* () {
const args = ['rev-list'];
if (options) {
args.push(...options);
}
args.push(...commitExpression);
const output = yield this.exec(args);
return output.stdout.trim();
});
}
revParse(ref, options) {
return __awaiter(this, void 0, void 0, function* () {
const args = ['rev-parse'];
if (options) {
args.push(...options);
}
args.push(ref);
const output = yield this.exec(args);
return output.stdout.trim();
});
}
status(options) {
return __awaiter(this, void 0, void 0, function* () {
const args = ['status'];
if (options) {
args.push(...options);
}
const output = yield this.exec(args);
return output.stdout.trim();
});
}
symbolicRef(ref, options) {
return __awaiter(this, void 0, void 0, function* () {
const args = ['symbolic-ref', ref];
if (options) {
args.push(...options);
}
const output = yield this.exec(args);
return output.stdout.trim();
});
}
tryConfigUnset(configKey, configValue = '.', globalConfig) {
return __awaiter(this, void 0, void 0, function* () {
const output = yield this.exec([
'config',
globalConfig ? '--global' : '--local',
'--unset',
configKey,
configValue
], true);
return output.exitCode === 0;
});
}
tryGetRemoteUrl() {
return __awaiter(this, void 0, void 0, function* () {
const output = yield this.exec(['config', '--local', '--get', 'remote.origin.url'], true);
if (output.exitCode !== 0) {
return '';
}
const stdout = output.stdout.trim();
if (stdout.includes('\n')) {
return '';
}
return stdout;
});
}
exec(args, allowAllExitCodes = false) {
return __awaiter(this, void 0, void 0, function* () {
const result = new GitOutput();
const env = {};
for (const key of Object.keys(process.env)) {
env[key] = process.env[key];
}
const stdout = [];
const stderr = [];
const options = {
cwd: this.workingDirectory,
env,
ignoreReturnCode: allowAllExitCodes,
listeners: {
stdout: (data) => {
stdout.push(data.toString());
},
stderr: (data) => {
stderr.push(data.toString());
}
}
};
result.exitCode = yield exec.exec(`"${this.gitPath}"`, args, options);
result.stdout = stdout.join('');
result.stderr = stderr.join('');
return result;
});
}
}
exports.GitCommandManager = GitCommandManager;
class GitOutput {
constructor() {
this.stdout = '';
this.stderr = '';
this.exitCode = 0;
}
}
/***/ }),
/***/ 446:
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.GitHubHelper = void 0;
const core = __importStar(__nccwpck_require__(2186));
const octokit_client_1 = __nccwpck_require__(5040);
const ERROR_PR_REVIEW_FROM_AUTHOR = 'Review cannot be requested from pull request author';
class GitHubHelper {
constructor(token) {
const options = {};
if (token) {
options.auth = `${token}`;
}
options.baseUrl = process.env['GITHUB_API_URL'] || 'https://api.github.com';
this.octokit = new octokit_client_1.Octokit(options);
}
parseRepository(repository) {
const [owner, repo] = repository.split('/');
return {
owner: owner,
repo: repo
};
}
createOrUpdate(inputs, baseRepository, headBranch) {
return __awaiter(this, void 0, void 0, function* () {
// Try to create the pull request
try {
core.info(`Attempting creation of pull request`);
const { data: pull } = yield this.octokit.rest.pulls.create(Object.assign(Object.assign({}, this.parseRepository(baseRepository)), { title: inputs.title, head: headBranch, base: inputs.base, body: inputs.body, draft: inputs.draft }));
core.info(`Created pull request #${pull.number} (${headBranch} => ${inputs.base})`);
return {
number: pull.number,
html_url: pull.html_url,
created: true
};
}
catch (e) {
if (e.message &&
e.message.includes(`A pull request already exists for ${headBranch}`)) {
core.info(`A pull request already exists for ${headBranch}`);
}
else {
throw e;
}
}
// Update the pull request that exists for this branch and base
core.info(`Fetching existing pull request`);
const { data: pulls } = yield this.octokit.rest.pulls.list(Object.assign(Object.assign({}, this.parseRepository(baseRepository)), { state: 'open', head: headBranch, base: inputs.base }));
core.info(`Attempting update of pull request`);
const { data: pull } = yield this.octokit.rest.pulls.update(Object.assign(Object.assign({}, this.parseRepository(baseRepository)), { pull_number: pulls[0].number, title: inputs.title, body: inputs.body }));
core.info(`Updated pull request #${pull.number} (${headBranch} => ${inputs.base})`);
return {
number: pull.number,
html_url: pull.html_url,
created: false
};
});
}
getRepositoryParent(headRepository) {
return __awaiter(this, void 0, void 0, function* () {
const { data: headRepo } = yield this.octokit.rest.repos.get(Object.assign({}, this.parseRepository(headRepository)));
if (!headRepo.parent) {
throw new Error(`Repository '${headRepository}' is not a fork. Unable to continue.`);
}
return headRepo.parent.full_name;
});
}
createOrUpdatePullRequest(inputs, baseRepository, headRepository) {
return __awaiter(this, void 0, void 0, function* () {
const [headOwner] = headRepository.split('/');
const headBranch = `${headOwner}:${inputs.branch}`;