@aspruyt/xfg 3.1.0 → 3.1.1
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.
|
@@ -44,6 +44,17 @@ export declare class GraphQLCommitStrategy implements CommitStrategy {
|
|
|
44
44
|
* Execute the createCommitOnBranch GraphQL mutation.
|
|
45
45
|
*/
|
|
46
46
|
private executeGraphQLMutation;
|
|
47
|
+
/**
|
|
48
|
+
* Build a git command with optional token authentication override.
|
|
49
|
+
* When a token is provided, uses -c url.insteadOf to override the global
|
|
50
|
+
* git config and authenticate with the provided token instead.
|
|
51
|
+
*
|
|
52
|
+
* This is critical for GitHub App authentication where the global git config
|
|
53
|
+
* may have a PAT token embedded, but we need to use the GitHub App installation token.
|
|
54
|
+
*
|
|
55
|
+
* Applies to all remote operations: push, fetch, ls-remote, etc.
|
|
56
|
+
*/
|
|
57
|
+
private buildAuthenticatedGitCommand;
|
|
47
58
|
/**
|
|
48
59
|
* Ensure the branch exists on the remote and matches local HEAD.
|
|
49
60
|
* createCommitOnBranch requires the branch to already exist.
|
|
@@ -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);
|
|
75
|
+
await this.ensureBranchExistsOnRemote(branchName, workDir, options.force, token, githubInfo.host);
|
|
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(`
|
|
83
|
+
await this.executor.exec(this.buildAuthenticatedGitCommand(`fetch origin ${safeBranch}:refs/remotes/origin/${safeBranch}`, token, githubInfo.host), 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
|
|
@@ -171,6 +171,24 @@ export class GraphQLCommitStrategy {
|
|
|
171
171
|
pushed: true, // GraphQL commits are pushed directly
|
|
172
172
|
};
|
|
173
173
|
}
|
|
174
|
+
/**
|
|
175
|
+
* Build a git command with optional token authentication override.
|
|
176
|
+
* When a token is provided, uses -c url.insteadOf to override the global
|
|
177
|
+
* git config and authenticate with the provided token instead.
|
|
178
|
+
*
|
|
179
|
+
* This is critical for GitHub App authentication where the global git config
|
|
180
|
+
* may have a PAT token embedded, but we need to use the GitHub App installation token.
|
|
181
|
+
*
|
|
182
|
+
* Applies to all remote operations: push, fetch, ls-remote, etc.
|
|
183
|
+
*/
|
|
184
|
+
buildAuthenticatedGitCommand(gitArgs, token, host = "github.com") {
|
|
185
|
+
if (!token) {
|
|
186
|
+
return `git ${gitArgs}`;
|
|
187
|
+
}
|
|
188
|
+
// Override URL rewrite to use the provided token
|
|
189
|
+
const urlOverride = `url."https://x-access-token:${token}@${host}/".insteadOf="https://${host}/"`;
|
|
190
|
+
return `git -c ${escapeShellArg(urlOverride)} ${gitArgs}`;
|
|
191
|
+
}
|
|
174
192
|
/**
|
|
175
193
|
* Ensure the branch exists on the remote and matches local HEAD.
|
|
176
194
|
* createCommitOnBranch requires the branch to already exist.
|
|
@@ -180,23 +198,23 @@ export class GraphQLCommitStrategy {
|
|
|
180
198
|
*
|
|
181
199
|
* For direct mode (force=false): just ensure branch exists.
|
|
182
200
|
*/
|
|
183
|
-
async ensureBranchExistsOnRemote(branchName, workDir, force) {
|
|
201
|
+
async ensureBranchExistsOnRemote(branchName, workDir, force, token, host) {
|
|
184
202
|
// Branch name was validated in commit(), safe for shell use
|
|
185
203
|
try {
|
|
186
204
|
// Check if the branch exists on remote
|
|
187
|
-
await this.executor.exec(`
|
|
205
|
+
await this.executor.exec(this.buildAuthenticatedGitCommand(`ls-remote --exit-code --heads origin ${escapeShellArg(branchName)}`, token, host), workDir);
|
|
188
206
|
// Branch exists - for PR branches, delete and recreate to ensure fresh from main
|
|
189
207
|
if (force) {
|
|
190
|
-
await this.executor.exec(`
|
|
208
|
+
await this.executor.exec(this.buildAuthenticatedGitCommand(`push origin --delete ${escapeShellArg(branchName)}`, token, host), workDir);
|
|
191
209
|
// Now push fresh branch from local HEAD
|
|
192
|
-
await this.executor.exec(`
|
|
210
|
+
await this.executor.exec(this.buildAuthenticatedGitCommand(`push -u origin HEAD:${escapeShellArg(branchName)}`, token, host), workDir);
|
|
193
211
|
}
|
|
194
212
|
// For direct mode (force=false), leave existing branch as-is
|
|
195
213
|
}
|
|
196
214
|
catch {
|
|
197
215
|
// Branch doesn't exist on remote, push it
|
|
198
216
|
// This pushes the current local branch to create it on remote
|
|
199
|
-
await this.executor.exec(`
|
|
217
|
+
await this.executor.exec(this.buildAuthenticatedGitCommand(`push -u origin HEAD:${escapeShellArg(branchName)}`, token, host), workDir);
|
|
200
218
|
}
|
|
201
219
|
}
|
|
202
220
|
/**
|