@aspruyt/xfg 3.1.1 → 3.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -52,6 +52,9 @@ export declare class GraphQLCommitStrategy implements CommitStrategy {
|
|
|
52
52
|
* This is critical for GitHub App authentication where the global git config
|
|
53
53
|
* may have a PAT token embedded, but we need to use the GitHub App installation token.
|
|
54
54
|
*
|
|
55
|
+
* Uses a repo-specific URL pattern (including owner/repo) so it has a LONGER
|
|
56
|
+
* prefix match than the global config and takes precedence.
|
|
57
|
+
*
|
|
55
58
|
* Applies to all remote operations: push, fetch, ls-remote, etc.
|
|
56
59
|
*/
|
|
57
60
|
private buildAuthenticatedGitCommand;
|
|
@@ -72,7 +72,7 @@ export class GraphQLCommitStrategy {
|
|
|
72
72
|
// Ensure the branch exists on remote and is up-to-date with local HEAD
|
|
73
73
|
// createCommitOnBranch requires the branch to already exist
|
|
74
74
|
// For PR branches (force=true), we force-update to ensure fresh start from main
|
|
75
|
-
await this.ensureBranchExistsOnRemote(branchName, workDir, options.force, token, githubInfo.host);
|
|
75
|
+
await this.ensureBranchExistsOnRemote(branchName, workDir, options.force, token, githubInfo.host, githubInfo.owner, githubInfo.repo);
|
|
76
76
|
// Retry loop for expectedHeadOid mismatch
|
|
77
77
|
let lastError = null;
|
|
78
78
|
for (let attempt = 0; attempt <= retries; attempt++) {
|
|
@@ -80,7 +80,7 @@ export class GraphQLCommitStrategy {
|
|
|
80
80
|
// Fetch from remote to ensure we have the latest HEAD
|
|
81
81
|
// This is critical for expectedHeadOid to match
|
|
82
82
|
const safeBranch = escapeShellArg(branchName);
|
|
83
|
-
await this.executor.exec(this.buildAuthenticatedGitCommand(`fetch origin ${safeBranch}:refs/remotes/origin/${safeBranch}`, token, githubInfo.host), workDir);
|
|
83
|
+
await this.executor.exec(this.buildAuthenticatedGitCommand(`fetch origin ${safeBranch}:refs/remotes/origin/${safeBranch}`, token, githubInfo.host, githubInfo.owner, githubInfo.repo), workDir);
|
|
84
84
|
// Get the remote HEAD SHA for this branch (not local HEAD)
|
|
85
85
|
const headSha = await this.executor.exec(`git rev-parse origin/${safeBranch}`, workDir);
|
|
86
86
|
// Build and execute the GraphQL mutation
|
|
@@ -179,14 +179,21 @@ export class GraphQLCommitStrategy {
|
|
|
179
179
|
* This is critical for GitHub App authentication where the global git config
|
|
180
180
|
* may have a PAT token embedded, but we need to use the GitHub App installation token.
|
|
181
181
|
*
|
|
182
|
+
* Uses a repo-specific URL pattern (including owner/repo) so it has a LONGER
|
|
183
|
+
* prefix match than the global config and takes precedence.
|
|
184
|
+
*
|
|
182
185
|
* Applies to all remote operations: push, fetch, ls-remote, etc.
|
|
183
186
|
*/
|
|
184
|
-
buildAuthenticatedGitCommand(gitArgs, token, host = "github.com") {
|
|
187
|
+
buildAuthenticatedGitCommand(gitArgs, token, host = "github.com", owner, repo) {
|
|
185
188
|
if (!token) {
|
|
186
189
|
return `git ${gitArgs}`;
|
|
187
190
|
}
|
|
188
|
-
//
|
|
189
|
-
|
|
191
|
+
// Use repo-specific URL pattern for LONGER prefix match to override global config
|
|
192
|
+
// Global config: url."https://x-access-token:PAT@github.com/".insteadOf = "https://github.com/"
|
|
193
|
+
// Our config: url."https://x-access-token:APP@github.com/owner/repo".insteadOf = "https://github.com/owner/repo"
|
|
194
|
+
// The longer prefix (owner/repo) takes precedence in git's URL matching
|
|
195
|
+
const repoPath = owner && repo ? `${owner}/${repo}` : "";
|
|
196
|
+
const urlOverride = `url."https://x-access-token:${token}@${host}/${repoPath}".insteadOf="https://${host}/${repoPath}"`;
|
|
190
197
|
return `git -c ${escapeShellArg(urlOverride)} ${gitArgs}`;
|
|
191
198
|
}
|
|
192
199
|
/**
|
|
@@ -198,23 +205,23 @@ export class GraphQLCommitStrategy {
|
|
|
198
205
|
*
|
|
199
206
|
* For direct mode (force=false): just ensure branch exists.
|
|
200
207
|
*/
|
|
201
|
-
async ensureBranchExistsOnRemote(branchName, workDir, force, token, host) {
|
|
208
|
+
async ensureBranchExistsOnRemote(branchName, workDir, force, token, host, owner, repo) {
|
|
202
209
|
// Branch name was validated in commit(), safe for shell use
|
|
203
210
|
try {
|
|
204
211
|
// Check if the branch exists on remote
|
|
205
|
-
await this.executor.exec(this.buildAuthenticatedGitCommand(`ls-remote --exit-code --heads origin ${escapeShellArg(branchName)}`, token, host), workDir);
|
|
212
|
+
await this.executor.exec(this.buildAuthenticatedGitCommand(`ls-remote --exit-code --heads origin ${escapeShellArg(branchName)}`, token, host, owner, repo), workDir);
|
|
206
213
|
// Branch exists - for PR branches, delete and recreate to ensure fresh from main
|
|
207
214
|
if (force) {
|
|
208
|
-
await this.executor.exec(this.buildAuthenticatedGitCommand(`push origin --delete ${escapeShellArg(branchName)}`, token, host), workDir);
|
|
215
|
+
await this.executor.exec(this.buildAuthenticatedGitCommand(`push origin --delete ${escapeShellArg(branchName)}`, token, host, owner, repo), workDir);
|
|
209
216
|
// Now push fresh branch from local HEAD
|
|
210
|
-
await this.executor.exec(this.buildAuthenticatedGitCommand(`push -u origin HEAD:${escapeShellArg(branchName)}`, token, host), workDir);
|
|
217
|
+
await this.executor.exec(this.buildAuthenticatedGitCommand(`push -u origin HEAD:${escapeShellArg(branchName)}`, token, host, owner, repo), workDir);
|
|
211
218
|
}
|
|
212
219
|
// For direct mode (force=false), leave existing branch as-is
|
|
213
220
|
}
|
|
214
221
|
catch {
|
|
215
222
|
// Branch doesn't exist on remote, push it
|
|
216
223
|
// This pushes the current local branch to create it on remote
|
|
217
|
-
await this.executor.exec(this.buildAuthenticatedGitCommand(`push -u origin HEAD:${escapeShellArg(branchName)}`, token, host), workDir);
|
|
224
|
+
await this.executor.exec(this.buildAuthenticatedGitCommand(`push -u origin HEAD:${escapeShellArg(branchName)}`, token, host, owner, repo), workDir);
|
|
218
225
|
}
|
|
219
226
|
}
|
|
220
227
|
/**
|