@aspruyt/xfg 5.1.3 → 5.1.5
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/README.md +1 -0
- package/dist/cli/lifecycle-report-builder.d.ts +2 -0
- package/dist/cli/lifecycle-report-builder.js +15 -0
- package/dist/cli/program.js +16 -11
- package/dist/cli/settings-report-builder.d.ts +1 -1
- package/dist/cli/settings-report-builder.js +20 -32
- package/dist/cli/sync-command.js +59 -64
- package/dist/cli/types.d.ts +3 -6
- package/dist/config/formatter.js +1 -6
- package/dist/config/index.d.ts +2 -1
- package/dist/config/index.js +2 -0
- package/dist/config/merge.d.ts +0 -6
- package/dist/config/merge.js +0 -13
- package/dist/config/types.d.ts +0 -9
- package/dist/config/validator.d.ts +1 -1
- package/dist/config/validator.js +1 -1
- package/dist/lifecycle/github-lifecycle-provider.js +28 -45
- package/dist/lifecycle/lifecycle-helpers.d.ts +1 -1
- package/dist/lifecycle/repo-lifecycle-manager.d.ts +1 -1
- package/dist/lifecycle/types.d.ts +4 -4
- package/dist/output/github-summary.d.ts +0 -50
- package/dist/output/github-summary.js +0 -201
- package/dist/output/lifecycle-report.d.ts +0 -1
- package/dist/output/lifecycle-report.js +0 -15
- package/dist/output/settings-report.d.ts +1 -1
- package/dist/output/settings-report.js +20 -78
- package/dist/output/sync-report.d.ts +1 -0
- package/dist/output/sync-report.js +19 -1
- package/dist/output/unified-summary.d.ts +1 -2
- package/dist/output/unified-summary.js +1 -19
- package/dist/settings/base-processor.d.ts +8 -0
- package/dist/settings/base-processor.js +7 -0
- package/dist/settings/index.d.ts +2 -2
- package/dist/settings/index.js +3 -1
- package/dist/settings/labels/converter.d.ts +1 -1
- package/dist/settings/labels/diff.d.ts +1 -1
- package/dist/settings/labels/formatter.d.ts +1 -1
- package/dist/settings/repo-settings/processor.js +9 -5
- package/dist/settings/rulesets/formatter.js +97 -85
- package/dist/settings/rulesets/github-ruleset-strategy.d.ts +2 -2
- package/dist/settings/rulesets/github-ruleset-strategy.js +7 -4
- package/dist/settings/rulesets/index.d.ts +1 -1
- package/dist/settings/rulesets/index.js +0 -2
- package/dist/settings/rulesets/processor.js +5 -1
- package/dist/settings/rulesets/types.d.ts +6 -1
- package/dist/shared/gh-api-utils.d.ts +1 -1
- package/dist/shared/logger.d.ts +8 -8
- package/dist/shared/logger.js +9 -8
- package/dist/shared/repo-detector.js +0 -1
- package/dist/sync/branch-manager.js +2 -2
- package/dist/sync/commit-push-manager.js +2 -2
- package/dist/sync/diff-utils.d.ts +0 -9
- package/dist/sync/diff-utils.js +0 -9
- package/dist/sync/file-sync-orchestrator.js +1 -1
- package/dist/sync/file-sync-strategy.d.ts +1 -1
- package/dist/sync/file-writer.d.ts +1 -1
- package/dist/sync/file-writer.js +3 -1
- package/dist/sync/index.d.ts +1 -2
- package/dist/sync/index.js +1 -1
- package/dist/sync/manifest-manager.d.ts +1 -1
- package/dist/sync/manifest-manager.js +1 -1
- package/dist/sync/manifest.js +9 -1
- package/dist/sync/pr-merge-handler.js +2 -2
- package/dist/sync/sync-workflow.d.ts +1 -1
- package/dist/sync/types.d.ts +2 -2
- package/dist/vcs/authenticated-git-ops.d.ts +2 -1
- package/dist/vcs/commit-strategy-selector.d.ts +1 -1
- package/dist/vcs/commit-strategy-selector.js +1 -1
- package/dist/vcs/git-ops.d.ts +0 -1
- package/dist/vcs/git-ops.js +15 -8
- package/dist/vcs/github-pr-strategy.d.ts +0 -3
- package/dist/vcs/github-pr-strategy.js +4 -7
- package/dist/vcs/index.d.ts +3 -3
- package/dist/vcs/index.js +2 -2
- package/dist/vcs/pr-creator.js +9 -9
- package/dist/vcs/pr-strategy-factory.d.ts +1 -1
- package/dist/vcs/pr-strategy-factory.js +1 -1
- package/dist/vcs/pr-strategy.js +6 -11
- package/package.json +1 -1
- package/dist/output/summary-utils.d.ts +0 -20
- package/dist/output/summary-utils.js +0 -79
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type FileContent } from "../config/index.js";
|
|
2
2
|
import type { IFileWriter, FileWriteContext, FileWriterDeps, FileWriteAllResult } from "./types.js";
|
|
3
3
|
/**
|
|
4
4
|
* Determines if a file should be marked as executable.
|
package/dist/sync/file-writer.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { existsSync } from "node:fs";
|
|
2
2
|
import { join } from "node:path";
|
|
3
|
-
import { convertContentToString } from "../config/
|
|
3
|
+
import { convertContentToString, } from "../config/index.js";
|
|
4
4
|
import { interpolateXfgContent } from "../shared/xfg-template.js";
|
|
5
5
|
import { getFileStatus, generateDiff, createDiffStats, incrementDiffStats, computeUnifiedDiff, isBinaryFile, } from "./diff-utils.js";
|
|
6
6
|
/**
|
|
@@ -87,6 +87,8 @@ export class FileWriter {
|
|
|
87
87
|
gitOps.writeFile(file.fileName, fileContent);
|
|
88
88
|
}
|
|
89
89
|
}
|
|
90
|
+
// Separate pass for executable permissions: git add must happen after file
|
|
91
|
+
// content is written, and setExecutable needs the file to already be tracked.
|
|
90
92
|
for (const file of files) {
|
|
91
93
|
const tracked = fileChanges.get(file.fileName);
|
|
92
94
|
if (tracked?.action === "skip") {
|
package/dist/sync/index.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
export
|
|
2
|
-
export { computeUnifiedDiff, isBinaryFile, formatDiffLine, } from "./diff-utils.js";
|
|
1
|
+
export { formatDiffLine } from "./diff-utils.js";
|
|
3
2
|
export type { FileChangeDetail, GitOpsFactory, IAuthOptionsBuilder, IBranchManager, ICommitPushManager, IFileSyncOrchestrator, IPRMergeHandler, IRepositoryProcessor, IRepositorySession, IWorkStrategy, ProcessorResult, SessionContext, WorkResult, } from "./types.js";
|
|
4
3
|
export { RepositoryProcessor } from "./repository-processor.js";
|
package/dist/sync/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { formatDiffLine } from "./diff-utils.js";
|
|
2
2
|
export { RepositoryProcessor } from "./repository-processor.js";
|
|
@@ -9,7 +9,7 @@ export declare class ManifestManager implements IManifestManager {
|
|
|
9
9
|
debug(msg: string): void;
|
|
10
10
|
warn(msg: string): void;
|
|
11
11
|
} | undefined);
|
|
12
|
-
|
|
12
|
+
detectOrphans(workDir: string, configId: string, filesWithDeleteOrphaned: Map<string, boolean | undefined>): OrphanProcessResult;
|
|
13
13
|
deleteOrphans(filesToDelete: string[], options: OrphanDeleteOptions, deps: OrphanDeleteDeps): void;
|
|
14
14
|
saveUpdatedManifest(workDir: string, manifest: XfgManifest, existingManifest: XfgManifest | null, dryRun: boolean, fileChanges: Map<string, FileWriteResult>): void;
|
|
15
15
|
}
|
|
@@ -10,7 +10,7 @@ export class ManifestManager {
|
|
|
10
10
|
constructor(log) {
|
|
11
11
|
this.log = log;
|
|
12
12
|
}
|
|
13
|
-
|
|
13
|
+
detectOrphans(workDir, configId, filesWithDeleteOrphaned) {
|
|
14
14
|
const existingManifest = loadManifest(workDir, this.log);
|
|
15
15
|
const { manifest, filesToDelete } = updateManifest(existingManifest, configId, filesWithDeleteOrphaned);
|
|
16
16
|
return { manifest, existingManifest, filesToDelete };
|
package/dist/sync/manifest.js
CHANGED
|
@@ -110,7 +110,15 @@ export function loadManifest(workDir, log) {
|
|
|
110
110
|
export function parseManifestContent(content, log) {
|
|
111
111
|
try {
|
|
112
112
|
const parsed = JSON.parse(content);
|
|
113
|
-
|
|
113
|
+
const migrated = migrateToV4(parsed);
|
|
114
|
+
if (migrated)
|
|
115
|
+
return migrated;
|
|
116
|
+
if (isV1Manifest(parsed)) {
|
|
117
|
+
log?.debug("V1 manifest detected — treating as empty (no config-ID namespace)");
|
|
118
|
+
return null;
|
|
119
|
+
}
|
|
120
|
+
log?.warn("Unrecognized manifest format in content, ignoring");
|
|
121
|
+
return null;
|
|
114
122
|
}
|
|
115
123
|
catch (error) {
|
|
116
124
|
log?.warn(`Failed to parse manifest content: ${toErrorMessage(error)}`);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createPR, mergePR,
|
|
1
|
+
import { createPR, mergePR, createPRStrategy, } from "../vcs/index.js";
|
|
2
2
|
export class PRMergeHandler {
|
|
3
3
|
log;
|
|
4
4
|
constructor(log) {
|
|
@@ -9,7 +9,7 @@ export class PRMergeHandler {
|
|
|
9
9
|
this.log.info("Creating pull request...");
|
|
10
10
|
const strategy = options.dryRun
|
|
11
11
|
? undefined
|
|
12
|
-
:
|
|
12
|
+
: createPRStrategy(repoInfo, options.executor, this.log);
|
|
13
13
|
const prResult = await createPR({
|
|
14
14
|
repoInfo,
|
|
15
15
|
branchName: options.branchName,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { RepoConfig } from "../config/
|
|
1
|
+
import type { RepoConfig } from "../config/index.js";
|
|
2
2
|
import { RepoInfo } from "../shared/repo-detector.js";
|
|
3
3
|
import type { DebugInfoLog } from "../shared/logger.js";
|
|
4
4
|
import type { ISyncWorkflow, IWorkStrategy, IAuthOptionsBuilder, IRepositorySession, IBranchManager, ICommitPushManager, IPRMergeHandler, ProcessorOptions, ProcessorResult } from "./types.js";
|
package/dist/sync/types.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { FileContent, RepoConfig } from "../config/
|
|
1
|
+
import type { FileContent, RepoConfig } from "../config/index.js";
|
|
2
2
|
import type { RepoInfo } from "../shared/repo-detector.js";
|
|
3
3
|
import type { ILocalGitOps, IGitOps, GitAuthOptions, GitOpsOptions, FileAction } from "../vcs/index.js";
|
|
4
4
|
import type { DiffStats } from "./diff-utils.js";
|
|
@@ -48,7 +48,7 @@ export interface OrphanDeleteDeps {
|
|
|
48
48
|
fileChanges: Map<string, FileWriteResult>;
|
|
49
49
|
}
|
|
50
50
|
export interface IManifestManager {
|
|
51
|
-
|
|
51
|
+
detectOrphans(workDir: string, configId: string, filesWithDeleteOrphaned: Map<string, boolean | undefined>): OrphanProcessResult;
|
|
52
52
|
deleteOrphans(filesToDelete: string[], options: OrphanDeleteOptions, deps: OrphanDeleteDeps): void;
|
|
53
53
|
saveUpdatedManifest(workDir: string, manifest: XfgManifest, existingManifest: XfgManifest | null, dryRun: boolean, fileChanges: Map<string, FileWriteResult>): void;
|
|
54
54
|
}
|
|
@@ -8,7 +8,7 @@ import type { GitAuthOptions, ILocalGitOps, IGitOps } from "./types.js";
|
|
|
8
8
|
* the remote origin. Subsequent operations (fetch, push, getDefaultBranch)
|
|
9
9
|
* reuse that authenticated remote URL — no extra auth setup per operation.
|
|
10
10
|
*/
|
|
11
|
-
|
|
11
|
+
interface AuthenticatedGitOpsOptions {
|
|
12
12
|
localOps: ILocalGitOps;
|
|
13
13
|
executor: ICommandExecutor;
|
|
14
14
|
workDir: string;
|
|
@@ -81,3 +81,4 @@ export declare class AuthenticatedGitOps implements IGitOps {
|
|
|
81
81
|
*/
|
|
82
82
|
fetchBranch(branchName: string): Promise<void>;
|
|
83
83
|
}
|
|
84
|
+
export {};
|
|
@@ -14,5 +14,5 @@ export declare function createTokenManager(credentials?: GitHubAppCredentials):
|
|
|
14
14
|
* Returns GraphQLCommitStrategy for GitHub repos with App credentials (verified commits),
|
|
15
15
|
* or GitCommitStrategy for all other cases.
|
|
16
16
|
*/
|
|
17
|
-
export declare function
|
|
17
|
+
export declare function createCommitStrategy(repoInfo: RepoInfo, executor: ICommandExecutor, hasAppCredentials?: boolean): ICommitStrategy;
|
|
18
18
|
export {};
|
|
@@ -15,7 +15,7 @@ export function createTokenManager(credentials) {
|
|
|
15
15
|
* Returns GraphQLCommitStrategy for GitHub repos with App credentials (verified commits),
|
|
16
16
|
* or GitCommitStrategy for all other cases.
|
|
17
17
|
*/
|
|
18
|
-
export function
|
|
18
|
+
export function createCommitStrategy(repoInfo, executor, hasAppCredentials) {
|
|
19
19
|
if (isGitHubRepo(repoInfo) && hasAppCredentials) {
|
|
20
20
|
return new GraphQLCommitStrategy(executor);
|
|
21
21
|
}
|
package/dist/vcs/git-ops.d.ts
CHANGED
|
@@ -50,7 +50,6 @@ export declare class GitOps implements ILocalGitOps {
|
|
|
50
50
|
/**
|
|
51
51
|
* Get list of files that have changes according to git status.
|
|
52
52
|
* Returns relative file paths for files that are modified, added, or untracked.
|
|
53
|
-
* Uses the same this.exec() pattern as other methods in this class.
|
|
54
53
|
*/
|
|
55
54
|
getChangedFiles(): Promise<string[]>;
|
|
56
55
|
stageAll(): Promise<void>;
|
package/dist/vcs/git-ops.js
CHANGED
|
@@ -109,8 +109,7 @@ export class GitOps {
|
|
|
109
109
|
if (code === "ENOENT" || code === "EACCES") {
|
|
110
110
|
return null;
|
|
111
111
|
}
|
|
112
|
-
|
|
113
|
-
return null;
|
|
112
|
+
throw error;
|
|
114
113
|
}
|
|
115
114
|
}
|
|
116
115
|
/**
|
|
@@ -130,8 +129,12 @@ export class GitOps {
|
|
|
130
129
|
return existingContent !== newContent;
|
|
131
130
|
}
|
|
132
131
|
catch (error) {
|
|
133
|
-
|
|
134
|
-
|
|
132
|
+
const code = error.code;
|
|
133
|
+
if (code === "ENOENT" || code === "EACCES") {
|
|
134
|
+
this.log?.debug(`Failed to read ${fileName} for comparison: ${toErrorMessage(error)}`);
|
|
135
|
+
return true;
|
|
136
|
+
}
|
|
137
|
+
throw error;
|
|
135
138
|
}
|
|
136
139
|
}
|
|
137
140
|
async hasChanges() {
|
|
@@ -141,7 +144,6 @@ export class GitOps {
|
|
|
141
144
|
/**
|
|
142
145
|
* Get list of files that have changes according to git status.
|
|
143
146
|
* Returns relative file paths for files that are modified, added, or untracked.
|
|
144
|
-
* Uses the same this.exec() pattern as other methods in this class.
|
|
145
147
|
*/
|
|
146
148
|
async getChangedFiles() {
|
|
147
149
|
const status = await this.exec("git status --porcelain", this._workDir);
|
|
@@ -169,9 +171,14 @@ export class GitOps {
|
|
|
169
171
|
return true;
|
|
170
172
|
}
|
|
171
173
|
catch (error) {
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
174
|
+
const message = toErrorMessage(error);
|
|
175
|
+
if (message.includes("does not exist") ||
|
|
176
|
+
message.includes("did not match") ||
|
|
177
|
+
message.includes("not found")) {
|
|
178
|
+
this.log?.debug(`fileExistsOnBranch(${fileName}, ${branch}): ${message}`);
|
|
179
|
+
return false;
|
|
180
|
+
}
|
|
181
|
+
throw error;
|
|
175
182
|
}
|
|
176
183
|
}
|
|
177
184
|
fileExists(fileName) {
|
|
@@ -9,9 +9,6 @@ export declare class GitHubPRStrategy extends BasePRStrategy {
|
|
|
9
9
|
* Check if auto-merge is enabled on the repository.
|
|
10
10
|
*/
|
|
11
11
|
private checkAutoMergeEnabled;
|
|
12
|
-
/**
|
|
13
|
-
* Build merge strategy flag for gh pr merge command.
|
|
14
|
-
*/
|
|
15
12
|
private getMergeStrategyFlag;
|
|
16
13
|
merge(options: MergeOptions): Promise<MergeResult>;
|
|
17
14
|
}
|
|
@@ -20,9 +20,6 @@ function getRepoFlag(repoInfo) {
|
|
|
20
20
|
}
|
|
21
21
|
return `${repoInfo.owner}/${repoInfo.repo}`;
|
|
22
22
|
}
|
|
23
|
-
/**
|
|
24
|
-
* Build regex to match PR URLs for the given host.
|
|
25
|
-
*/
|
|
26
23
|
function buildPRUrlRegex(host) {
|
|
27
24
|
const escapedHost = escapeRegExp(host);
|
|
28
25
|
return new RegExp(`https://${escapedHost}/[\\w-]+/[\\w.-]+/pull/\\d+`);
|
|
@@ -136,14 +133,14 @@ export class GitHubPRStrategy extends BasePRStrategy {
|
|
|
136
133
|
return result.trim() === "true";
|
|
137
134
|
}
|
|
138
135
|
catch (error) {
|
|
139
|
-
|
|
136
|
+
if (isPermanentError(error)) {
|
|
137
|
+
throw error;
|
|
138
|
+
}
|
|
139
|
+
// If we can't check due to transient errors, assume auto-merge is not enabled
|
|
140
140
|
this.log?.warn(`Could not check auto-merge status: ${toErrorMessage(error)}`);
|
|
141
141
|
return false;
|
|
142
142
|
}
|
|
143
143
|
}
|
|
144
|
-
/**
|
|
145
|
-
* Build merge strategy flag for gh pr merge command.
|
|
146
|
-
*/
|
|
147
144
|
getMergeStrategyFlag(strategy) {
|
|
148
145
|
switch (strategy) {
|
|
149
146
|
case "squash":
|
package/dist/vcs/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export type { PRMergeConfig, FileChange, FileAction, IGitOps, ILocalGitOps,
|
|
1
|
+
export type { PRMergeConfig, FileChange, FileAction, IGitOps, ILocalGitOps, IPRStrategy, GitAuthOptions, PRResult, ICommitStrategy, } from "./types.js";
|
|
2
2
|
export type { GitOpsOptions } from "./git-ops.js";
|
|
3
|
-
export {
|
|
4
|
-
export {
|
|
3
|
+
export { createCommitStrategy, createTokenManager, } from "./commit-strategy-selector.js";
|
|
4
|
+
export { createPRStrategy } from "./pr-strategy-factory.js";
|
|
5
5
|
export { createPR, mergePR } from "./pr-creator.js";
|
package/dist/vcs/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Commit strategies
|
|
2
|
-
export {
|
|
2
|
+
export { createCommitStrategy, createTokenManager, } from "./commit-strategy-selector.js";
|
|
3
3
|
// PR strategy factory
|
|
4
|
-
export {
|
|
4
|
+
export { createPRStrategy } from "./pr-strategy-factory.js";
|
|
5
5
|
// PR creation and merge
|
|
6
6
|
export { createPR, mergePR } from "./pr-creator.js";
|
package/dist/vcs/pr-creator.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { readFileSync, existsSync } from "node:fs";
|
|
2
2
|
import { join, dirname } from "node:path";
|
|
3
3
|
import { fileURLToPath } from "node:url";
|
|
4
|
-
import {
|
|
4
|
+
import { createPRStrategy } from "./pr-strategy-factory.js";
|
|
5
5
|
import { PRWorkflowExecutor } from "./pr-strategy.js";
|
|
6
6
|
import { interpolateXfgContent } from "../shared/xfg-template.js";
|
|
7
7
|
function loadDefaultTemplate() {
|
|
@@ -95,18 +95,18 @@ export function formatPRTitle(files) {
|
|
|
95
95
|
}
|
|
96
96
|
return `chore: sync ${changedFiles.length} config files`;
|
|
97
97
|
}
|
|
98
|
-
export
|
|
98
|
+
export function createPR(options) {
|
|
99
99
|
const { repoInfo, branchName, baseBranch, files, workDir, dryRun, retries, prTemplate, executor, token, labels, log, } = options;
|
|
100
100
|
const title = formatPRTitle(files);
|
|
101
101
|
const body = formatPRBody(files, repoInfo, prTemplate);
|
|
102
102
|
if (dryRun) {
|
|
103
|
-
return {
|
|
103
|
+
return Promise.resolve({
|
|
104
104
|
success: true,
|
|
105
105
|
message: `[DRY RUN] Would create PR: "${title}"`,
|
|
106
|
-
};
|
|
106
|
+
});
|
|
107
107
|
}
|
|
108
108
|
// Get the appropriate strategy and execute via workflow executor
|
|
109
|
-
const resolvedStrategy = options.strategy ??
|
|
109
|
+
const resolvedStrategy = options.strategy ?? createPRStrategy(repoInfo, executor, log);
|
|
110
110
|
const workflow = new PRWorkflowExecutor(resolvedStrategy);
|
|
111
111
|
return workflow.execute({
|
|
112
112
|
repoInfo,
|
|
@@ -120,7 +120,7 @@ export async function createPR(options) {
|
|
|
120
120
|
labels,
|
|
121
121
|
});
|
|
122
122
|
}
|
|
123
|
-
export
|
|
123
|
+
export function mergePR(options) {
|
|
124
124
|
const { repoInfo, prUrl, mergeConfig, workDir, dryRun, retries, executor, token, log, } = options;
|
|
125
125
|
if (dryRun) {
|
|
126
126
|
const modeText = mergeConfig.mode === "force"
|
|
@@ -128,14 +128,14 @@ export async function mergePR(options) {
|
|
|
128
128
|
: mergeConfig.mode === "auto"
|
|
129
129
|
? "enable auto-merge"
|
|
130
130
|
: "leave open for manual review";
|
|
131
|
-
return {
|
|
131
|
+
return Promise.resolve({
|
|
132
132
|
success: true,
|
|
133
133
|
message: `[DRY RUN] Would ${modeText}`,
|
|
134
134
|
merged: false,
|
|
135
|
-
};
|
|
135
|
+
});
|
|
136
136
|
}
|
|
137
137
|
// Get the appropriate strategy and execute merge
|
|
138
|
-
const resolvedStrategy = options.strategy ??
|
|
138
|
+
const resolvedStrategy = options.strategy ?? createPRStrategy(repoInfo, executor, log);
|
|
139
139
|
return resolvedStrategy.merge({
|
|
140
140
|
prUrl,
|
|
141
141
|
repoInfo,
|
|
@@ -2,4 +2,4 @@ import { RepoInfo } from "../shared/repo-detector.js";
|
|
|
2
2
|
import type { IPRStrategy } from "./types.js";
|
|
3
3
|
import { ICommandExecutor } from "../shared/command-executor.js";
|
|
4
4
|
import type { IPRStrategyLogger } from "./pr-strategy.js";
|
|
5
|
-
export declare function
|
|
5
|
+
export declare function createPRStrategy(repoInfo: RepoInfo, executor: ICommandExecutor, log?: IPRStrategyLogger): IPRStrategy;
|
|
@@ -3,7 +3,7 @@ import { SyncError } from "../shared/errors.js";
|
|
|
3
3
|
import { GitHubPRStrategy } from "./github-pr-strategy.js";
|
|
4
4
|
import { AzurePRStrategy } from "./azure-pr-strategy.js";
|
|
5
5
|
import { GitLabPRStrategy } from "./gitlab-pr-strategy.js";
|
|
6
|
-
export function
|
|
6
|
+
export function createPRStrategy(repoInfo, executor, log) {
|
|
7
7
|
if (isGitHubRepo(repoInfo)) {
|
|
8
8
|
return new GitHubPRStrategy(executor, log);
|
|
9
9
|
}
|
package/dist/vcs/pr-strategy.js
CHANGED
|
@@ -13,17 +13,12 @@ export class BasePRStrategy {
|
|
|
13
13
|
* Shared by all platform strategies to eliminate duplicated try/catch patterns.
|
|
14
14
|
*/
|
|
15
15
|
async executeMergeCommand(execFn, retries, successResult, errorPrefix) {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
success: false,
|
|
23
|
-
message: `${errorPrefix}: ${toErrorMessage(error)}`,
|
|
24
|
-
merged: false,
|
|
25
|
-
};
|
|
26
|
-
}
|
|
16
|
+
const result = await withRetry(execFn, { retries, log: this.log }).then(() => successResult, (error) => {
|
|
17
|
+
const message = `${errorPrefix}: ${toErrorMessage(error)}`;
|
|
18
|
+
this.log?.warn(message);
|
|
19
|
+
return { success: false, message, merged: false };
|
|
20
|
+
});
|
|
21
|
+
return result;
|
|
27
22
|
}
|
|
28
23
|
}
|
|
29
24
|
export class PRWorkflowExecutor {
|
package/package.json
CHANGED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import type { ProcessorResult } from "../sync/index.js";
|
|
2
|
-
import { RepoConfig } from "../config/index.js";
|
|
3
|
-
import { MergeOutcome, FileChanges, RepoResult } from "./github-summary.js";
|
|
4
|
-
import type { DiffStats } from "../sync/index.js";
|
|
5
|
-
/**
|
|
6
|
-
* Determine merge outcome from repo config and processor result
|
|
7
|
-
*/
|
|
8
|
-
export declare function getMergeOutcome(repoConfig: RepoConfig, result: ProcessorResult): MergeOutcome | undefined;
|
|
9
|
-
/**
|
|
10
|
-
* Convert DiffStats to FileChanges for summary output
|
|
11
|
-
*/
|
|
12
|
-
export declare function toFileChanges(diffStats?: DiffStats): FileChanges | undefined;
|
|
13
|
-
/**
|
|
14
|
-
* Build a RepoResult from a ProcessorResult for the summary
|
|
15
|
-
*/
|
|
16
|
-
export declare function buildRepoResult(repoName: string, repoConfig: RepoConfig, result: ProcessorResult): RepoResult;
|
|
17
|
-
/**
|
|
18
|
-
* Build a RepoResult for an error case
|
|
19
|
-
*/
|
|
20
|
-
export declare function buildErrorResult(repoName: string, error: unknown): RepoResult;
|
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
import { toErrorMessage } from "../shared/type-guards.js";
|
|
2
|
-
/**
|
|
3
|
-
* Determine merge outcome from repo config and processor result
|
|
4
|
-
*/
|
|
5
|
-
export function getMergeOutcome(repoConfig, result) {
|
|
6
|
-
if (!result.success || result.skipped)
|
|
7
|
-
return undefined;
|
|
8
|
-
const mergeMode = repoConfig.prOptions?.merge ?? "auto";
|
|
9
|
-
if (mergeMode === "direct")
|
|
10
|
-
return "direct";
|
|
11
|
-
if (result.mergeResult?.merged)
|
|
12
|
-
return "force";
|
|
13
|
-
if (result.mergeResult?.autoMergeEnabled)
|
|
14
|
-
return "auto";
|
|
15
|
-
if (result.prUrl)
|
|
16
|
-
return "manual";
|
|
17
|
-
return undefined;
|
|
18
|
-
}
|
|
19
|
-
/**
|
|
20
|
-
* Convert DiffStats to FileChanges for summary output
|
|
21
|
-
*/
|
|
22
|
-
export function toFileChanges(diffStats) {
|
|
23
|
-
if (!diffStats)
|
|
24
|
-
return undefined;
|
|
25
|
-
return {
|
|
26
|
-
added: diffStats.newCount,
|
|
27
|
-
modified: diffStats.modifiedCount,
|
|
28
|
-
deleted: diffStats.deletedCount,
|
|
29
|
-
unchanged: diffStats.unchangedCount,
|
|
30
|
-
};
|
|
31
|
-
}
|
|
32
|
-
/**
|
|
33
|
-
* Build a RepoResult from a ProcessorResult for the summary
|
|
34
|
-
*/
|
|
35
|
-
export function buildRepoResult(repoName, repoConfig, result) {
|
|
36
|
-
if (result.skipped) {
|
|
37
|
-
return {
|
|
38
|
-
repoName,
|
|
39
|
-
status: "skipped",
|
|
40
|
-
message: result.message,
|
|
41
|
-
fileChanges: toFileChanges(result.diffStats),
|
|
42
|
-
};
|
|
43
|
-
}
|
|
44
|
-
if (result.success) {
|
|
45
|
-
let message = result.prUrl ? `PR: ${result.prUrl}` : result.message;
|
|
46
|
-
if (result.mergeResult) {
|
|
47
|
-
if (result.mergeResult.merged) {
|
|
48
|
-
message += " (merged)";
|
|
49
|
-
}
|
|
50
|
-
else if (result.mergeResult.autoMergeEnabled) {
|
|
51
|
-
message += " (auto-merge enabled)";
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
return {
|
|
55
|
-
repoName,
|
|
56
|
-
status: "succeeded",
|
|
57
|
-
message,
|
|
58
|
-
prUrl: result.prUrl,
|
|
59
|
-
mergeOutcome: getMergeOutcome(repoConfig, result),
|
|
60
|
-
fileChanges: toFileChanges(result.diffStats),
|
|
61
|
-
};
|
|
62
|
-
}
|
|
63
|
-
return {
|
|
64
|
-
repoName,
|
|
65
|
-
status: "failed",
|
|
66
|
-
message: result.message,
|
|
67
|
-
};
|
|
68
|
-
}
|
|
69
|
-
/**
|
|
70
|
-
* Build a RepoResult for an error case
|
|
71
|
-
*/
|
|
72
|
-
export function buildErrorResult(repoName, error) {
|
|
73
|
-
const message = toErrorMessage(error);
|
|
74
|
-
return {
|
|
75
|
-
repoName,
|
|
76
|
-
status: "failed",
|
|
77
|
-
message,
|
|
78
|
-
};
|
|
79
|
-
}
|