@aspruyt/xfg 3.2.0 → 3.3.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.
- package/dist/command-executor.js +11 -2
- package/dist/index.js +3 -7
- package/dist/retry-utils.js +2 -1
- package/dist/sanitize-utils.d.ts +8 -0
- package/dist/sanitize-utils.js +20 -0
- package/dist/strategies/azure-pr-strategy.js +2 -1
- package/dist/strategies/github-pr-strategy.js +2 -1
- package/dist/strategies/gitlab-pr-strategy.js +2 -1
- package/package.json +1 -1
package/dist/command-executor.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { execSync } from "node:child_process";
|
|
2
|
+
import { sanitizeCredentials } from "./sanitize-utils.js";
|
|
2
3
|
/**
|
|
3
4
|
* Default implementation that uses Node.js child_process.execSync.
|
|
4
5
|
* Note: Commands are escaped using escapeShellArg before being passed here.
|
|
@@ -18,9 +19,17 @@ export class ShellCommandExecutor {
|
|
|
18
19
|
if (execError.stderr && typeof execError.stderr !== "string") {
|
|
19
20
|
execError.stderr = execError.stderr.toString();
|
|
20
21
|
}
|
|
21
|
-
//
|
|
22
|
+
// Sanitize credentials from stderr before including in error
|
|
23
|
+
if (execError.stderr) {
|
|
24
|
+
execError.stderr = sanitizeCredentials(execError.stderr);
|
|
25
|
+
}
|
|
26
|
+
// Include sanitized stderr in error message for better debugging
|
|
22
27
|
if (execError.stderr && execError.message) {
|
|
23
|
-
execError.message =
|
|
28
|
+
execError.message =
|
|
29
|
+
sanitizeCredentials(execError.message) + "\n" + execError.stderr;
|
|
30
|
+
}
|
|
31
|
+
else if (execError.message) {
|
|
32
|
+
execError.message = sanitizeCredentials(execError.message);
|
|
24
33
|
}
|
|
25
34
|
throw error;
|
|
26
35
|
}
|
package/dist/index.js
CHANGED
|
@@ -208,19 +208,15 @@ export async function runSettings(options, processorFactory = defaultRulesetProc
|
|
|
208
208
|
return;
|
|
209
209
|
}
|
|
210
210
|
console.log(`Found ${reposWithRulesets.length} repositories with rulesets\n`);
|
|
211
|
+
logger.setTotal(reposWithRulesets.length);
|
|
211
212
|
const processor = processorFactory();
|
|
212
213
|
const repoProcessor = repoProcessorFactory();
|
|
213
214
|
const results = [];
|
|
214
215
|
let successCount = 0;
|
|
215
216
|
let failCount = 0;
|
|
216
217
|
let skipCount = 0;
|
|
217
|
-
for (let i = 0; i <
|
|
218
|
-
const repoConfig =
|
|
219
|
-
// Skip repos without rulesets
|
|
220
|
-
if (!repoConfig.settings?.rulesets ||
|
|
221
|
-
Object.keys(repoConfig.settings.rulesets).length === 0) {
|
|
222
|
-
continue;
|
|
223
|
-
}
|
|
218
|
+
for (let i = 0; i < reposWithRulesets.length; i++) {
|
|
219
|
+
const repoConfig = reposWithRulesets[i];
|
|
224
220
|
let repoInfo;
|
|
225
221
|
try {
|
|
226
222
|
repoInfo = parseGitUrl(repoConfig.git, {
|
package/dist/retry-utils.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import pRetry, { AbortError } from "p-retry";
|
|
2
2
|
import { logger } from "./logger.js";
|
|
3
|
+
import { sanitizeCredentials } from "./sanitize-utils.js";
|
|
3
4
|
/**
|
|
4
5
|
* Default patterns indicating permanent errors that should NOT be retried.
|
|
5
6
|
* These typically indicate configuration issues, auth failures, or invalid resources.
|
|
@@ -121,7 +122,7 @@ export async function withRetry(fn, options) {
|
|
|
121
122
|
onFailedAttempt: (context) => {
|
|
122
123
|
// Only log if this isn't the last attempt
|
|
123
124
|
if (context.retriesLeft > 0) {
|
|
124
|
-
const msg = context.error.message || "Unknown error";
|
|
125
|
+
const msg = sanitizeCredentials(context.error.message) || "Unknown error";
|
|
125
126
|
logger.info(`Attempt ${context.attemptNumber}/${retries + 1} failed: ${msg}. Retrying...`);
|
|
126
127
|
options?.onRetry?.(context.error, context.attemptNumber);
|
|
127
128
|
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sanitizes credentials from error messages and logs.
|
|
3
|
+
* Replaces sensitive tokens/passwords with '***' to prevent leakage.
|
|
4
|
+
*
|
|
5
|
+
* @param message The message that may contain credentials
|
|
6
|
+
* @returns The sanitized message with credentials replaced by '***'
|
|
7
|
+
*/
|
|
8
|
+
export declare function sanitizeCredentials(message: string | undefined | null): string;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sanitizes credentials from error messages and logs.
|
|
3
|
+
* Replaces sensitive tokens/passwords with '***' to prevent leakage.
|
|
4
|
+
*
|
|
5
|
+
* @param message The message that may contain credentials
|
|
6
|
+
* @returns The sanitized message with credentials replaced by '***'
|
|
7
|
+
*/
|
|
8
|
+
export function sanitizeCredentials(message) {
|
|
9
|
+
if (!message) {
|
|
10
|
+
return "";
|
|
11
|
+
}
|
|
12
|
+
let result = message;
|
|
13
|
+
// Handle URL credentials (most common case)
|
|
14
|
+
// Replace password portion in https://user:password@host patterns
|
|
15
|
+
result = result.replace(/(https:\/\/[^:]+:)([^@]+)(@)/g, "$1***$3");
|
|
16
|
+
// Handle Authorization headers
|
|
17
|
+
result = result.replace(/(Authorization:\s*Bearer\s+)(\S+)/gi, "$1***");
|
|
18
|
+
result = result.replace(/(Authorization:\s*Basic\s+)(\S+)/gi, "$1***");
|
|
19
|
+
return result;
|
|
20
|
+
}
|
|
@@ -5,6 +5,7 @@ import { isAzureDevOpsRepo } from "../repo-detector.js";
|
|
|
5
5
|
import { BasePRStrategy, } from "./pr-strategy.js";
|
|
6
6
|
import { logger } from "../logger.js";
|
|
7
7
|
import { withRetry, isPermanentError } from "../retry-utils.js";
|
|
8
|
+
import { sanitizeCredentials } from "../sanitize-utils.js";
|
|
8
9
|
export class AzurePRStrategy extends BasePRStrategy {
|
|
9
10
|
constructor(executor) {
|
|
10
11
|
super(executor);
|
|
@@ -35,7 +36,7 @@ export class AzurePRStrategy extends BasePRStrategy {
|
|
|
35
36
|
}
|
|
36
37
|
const stderr = error.stderr ?? "";
|
|
37
38
|
if (stderr && !stderr.includes("does not exist")) {
|
|
38
|
-
logger.info(`Debug: Azure PR check failed - ${stderr.trim()}`);
|
|
39
|
+
logger.info(`Debug: Azure PR check failed - ${sanitizeCredentials(stderr).trim()}`);
|
|
39
40
|
}
|
|
40
41
|
}
|
|
41
42
|
return null;
|
|
@@ -5,6 +5,7 @@ import { isGitHubRepo } from "../repo-detector.js";
|
|
|
5
5
|
import { BasePRStrategy, } from "./pr-strategy.js";
|
|
6
6
|
import { logger } from "../logger.js";
|
|
7
7
|
import { withRetry, isPermanentError } from "../retry-utils.js";
|
|
8
|
+
import { sanitizeCredentials } from "../sanitize-utils.js";
|
|
8
9
|
/**
|
|
9
10
|
* Get the repo flag value for gh CLI commands.
|
|
10
11
|
* Returns HOST/OWNER/REPO for GHE, OWNER/REPO for github.com.
|
|
@@ -66,7 +67,7 @@ export class GitHubPRStrategy extends BasePRStrategy {
|
|
|
66
67
|
// Log unexpected errors for debugging (expected: empty result means no PR)
|
|
67
68
|
const stderr = error.stderr ?? "";
|
|
68
69
|
if (stderr && !stderr.includes("no pull requests match")) {
|
|
69
|
-
logger.info(`Debug: GitHub PR check failed - ${stderr.trim()}`);
|
|
70
|
+
logger.info(`Debug: GitHub PR check failed - ${sanitizeCredentials(stderr).trim()}`);
|
|
70
71
|
}
|
|
71
72
|
}
|
|
72
73
|
return null;
|
|
@@ -5,6 +5,7 @@ import { isGitLabRepo } from "../repo-detector.js";
|
|
|
5
5
|
import { BasePRStrategy, } from "./pr-strategy.js";
|
|
6
6
|
import { logger } from "../logger.js";
|
|
7
7
|
import { withRetry, isPermanentError } from "../retry-utils.js";
|
|
8
|
+
import { sanitizeCredentials } from "../sanitize-utils.js";
|
|
8
9
|
export class GitLabPRStrategy extends BasePRStrategy {
|
|
9
10
|
constructor(executor) {
|
|
10
11
|
super(executor);
|
|
@@ -89,7 +90,7 @@ export class GitLabPRStrategy extends BasePRStrategy {
|
|
|
89
90
|
// Log unexpected errors for debugging
|
|
90
91
|
const stderr = error.stderr ?? "";
|
|
91
92
|
if (stderr && !stderr.includes("no merge requests")) {
|
|
92
|
-
logger.info(`Debug: GitLab MR check failed - ${stderr.trim()}`);
|
|
93
|
+
logger.info(`Debug: GitLab MR check failed - ${sanitizeCredentials(stderr).trim()}`);
|
|
93
94
|
}
|
|
94
95
|
}
|
|
95
96
|
return null;
|