@aspruyt/xfg 3.7.7 → 3.8.0
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/cli/settings-command.js +48 -39
- package/dist/cli/settings-report-builder.d.ts +19 -0
- package/dist/cli/settings-report-builder.js +64 -0
- package/dist/cli/sync-command.js +49 -24
- package/dist/cli/sync-report-builder.d.ts +15 -0
- package/dist/cli/sync-report-builder.js +29 -0
- package/dist/output/index.d.ts +2 -2
- package/dist/output/index.js +4 -4
- package/dist/output/settings-report.d.ts +37 -0
- package/dist/output/settings-report.js +300 -0
- package/dist/output/sync-report.d.ts +24 -0
- package/dist/output/sync-report.js +99 -0
- package/dist/settings/index.d.ts +0 -1
- package/dist/settings/index.js +0 -2
- package/dist/settings/repo-settings/formatter.d.ts +2 -0
- package/dist/settings/repo-settings/formatter.js +11 -2
- package/dist/settings/repo-settings/processor.js +8 -2
- package/dist/settings/rulesets/formatter.d.ts +3 -0
- package/dist/settings/rulesets/formatter.js +7 -1
- package/dist/sync/index.d.ts +1 -1
- package/dist/sync/pr-merge-handler.d.ts +2 -2
- package/dist/sync/pr-merge-handler.js +2 -1
- package/dist/sync/repository-processor.js +22 -2
- package/dist/sync/types.d.ts +9 -1
- package/package.json +1 -1
- package/dist/output/plan-formatter.d.ts +0 -39
- package/dist/output/plan-formatter.js +0 -84
- package/dist/output/plan-summary.d.ts +0 -8
- package/dist/output/plan-summary.js +0 -110
- package/dist/settings/resource-converters.d.ts +0 -28
- package/dist/settings/resource-converters.js +0 -107
|
@@ -8,9 +8,8 @@ import { logger } from "../shared/logger.js";
|
|
|
8
8
|
import { generateWorkspaceName } from "../shared/workspace-utils.js";
|
|
9
9
|
import { buildErrorResult } from "../output/summary-utils.js";
|
|
10
10
|
import { getManagedRulesets } from "../sync/manifest.js";
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import { rulesetResultToResources, repoSettingsResultToResources, } from "../settings/resource-converters.js";
|
|
11
|
+
import { formatSettingsReportCLI, writeSettingsReportSummary, } from "../output/settings-report.js";
|
|
12
|
+
import { buildSettingsReport } from "./settings-report-builder.js";
|
|
14
13
|
import { defaultProcessorFactory, defaultRulesetProcessorFactory, defaultRepoSettingsProcessorFactory, } from "./types.js";
|
|
15
14
|
/**
|
|
16
15
|
* Run the settings command - manages GitHub Rulesets and repo settings.
|
|
@@ -51,7 +50,15 @@ export async function runSettings(options, processorFactory = defaultRulesetProc
|
|
|
51
50
|
const processor = processorFactory();
|
|
52
51
|
const repoProcessor = repoProcessorFactory();
|
|
53
52
|
const results = [];
|
|
54
|
-
const
|
|
53
|
+
const processingResults = [];
|
|
54
|
+
function getOrCreateResult(repoName) {
|
|
55
|
+
let result = processingResults.find((r) => r.repoName === repoName);
|
|
56
|
+
if (!result) {
|
|
57
|
+
result = { repoName };
|
|
58
|
+
processingResults.push(result);
|
|
59
|
+
}
|
|
60
|
+
return result;
|
|
61
|
+
}
|
|
55
62
|
for (let i = 0; i < reposWithRulesets.length; i++) {
|
|
56
63
|
const repoConfig = reposWithRulesets[i];
|
|
57
64
|
let repoInfo;
|
|
@@ -63,26 +70,14 @@ export async function runSettings(options, processorFactory = defaultRulesetProc
|
|
|
63
70
|
catch (error) {
|
|
64
71
|
logger.error(i + 1, repoConfig.git, String(error));
|
|
65
72
|
results.push(buildErrorResult(repoConfig.git, error));
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
message: error instanceof Error ? error.message : String(error),
|
|
69
|
-
});
|
|
73
|
+
getOrCreateResult(repoConfig.git).error =
|
|
74
|
+
error instanceof Error ? error.message : String(error);
|
|
70
75
|
continue;
|
|
71
76
|
}
|
|
72
77
|
const repoName = getRepoDisplayName(repoInfo);
|
|
73
78
|
if (!isGitHubRepo(repoInfo)) {
|
|
74
79
|
logger.skip(i + 1, repoName, "GitHub Rulesets only supported for GitHub repos");
|
|
75
|
-
|
|
76
|
-
for (const rulesetName of Object.keys(repoConfig.settings.rulesets)) {
|
|
77
|
-
plan.resources.push({
|
|
78
|
-
type: "ruleset",
|
|
79
|
-
repo: repoName,
|
|
80
|
-
name: rulesetName,
|
|
81
|
-
action: "skipped",
|
|
82
|
-
skipReason: "GitHub Rulesets only supported for GitHub repos",
|
|
83
|
-
});
|
|
84
|
-
}
|
|
85
|
-
}
|
|
80
|
+
// Skipped repos don't appear in the report
|
|
86
81
|
continue;
|
|
87
82
|
}
|
|
88
83
|
const managedRulesets = getManagedRulesets(null, config.id);
|
|
@@ -135,15 +130,22 @@ export async function runSettings(options, processorFactory = defaultRulesetProc
|
|
|
135
130
|
message: result.message,
|
|
136
131
|
rulesetPlanDetails: result.planOutput?.entries,
|
|
137
132
|
});
|
|
138
|
-
|
|
133
|
+
// Collect result for SettingsReport
|
|
134
|
+
if (!result.skipped) {
|
|
135
|
+
getOrCreateResult(repoName).rulesetResult = result;
|
|
136
|
+
}
|
|
139
137
|
}
|
|
140
138
|
catch (error) {
|
|
141
139
|
logger.error(i + 1, repoName, String(error));
|
|
142
140
|
results.push(buildErrorResult(repoName, error));
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
141
|
+
const existingResult = getOrCreateResult(repoName);
|
|
142
|
+
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
143
|
+
if (existingResult.error) {
|
|
144
|
+
existingResult.error += `; ${errorMsg}`;
|
|
145
|
+
}
|
|
146
|
+
else {
|
|
147
|
+
existingResult.error = errorMsg;
|
|
148
|
+
}
|
|
147
149
|
}
|
|
148
150
|
}
|
|
149
151
|
if (reposWithRepoSettings.length > 0) {
|
|
@@ -159,10 +161,8 @@ export async function runSettings(options, processorFactory = defaultRulesetProc
|
|
|
159
161
|
}
|
|
160
162
|
catch (error) {
|
|
161
163
|
console.error(`Failed to parse ${repoConfig.git}: ${error}`);
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
message: error instanceof Error ? error.message : String(error),
|
|
165
|
-
});
|
|
164
|
+
getOrCreateResult(repoConfig.git).error =
|
|
165
|
+
error instanceof Error ? error.message : String(error);
|
|
166
166
|
continue;
|
|
167
167
|
}
|
|
168
168
|
const repoName = getRepoDisplayName(repoInfo);
|
|
@@ -205,24 +205,33 @@ export async function runSettings(options, processorFactory = defaultRulesetProc
|
|
|
205
205
|
});
|
|
206
206
|
}
|
|
207
207
|
}
|
|
208
|
-
|
|
208
|
+
// Collect result for SettingsReport
|
|
209
|
+
if (!result.skipped) {
|
|
210
|
+
getOrCreateResult(repoName).settingsResult = result;
|
|
211
|
+
}
|
|
209
212
|
}
|
|
210
213
|
catch (error) {
|
|
211
214
|
console.error(` ✗ ${repoName}: ${error}`);
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
215
|
+
const existingResult = getOrCreateResult(repoName);
|
|
216
|
+
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
217
|
+
if (existingResult.error) {
|
|
218
|
+
existingResult.error += `; ${errorMsg}`;
|
|
219
|
+
}
|
|
220
|
+
else {
|
|
221
|
+
existingResult.error = errorMsg;
|
|
222
|
+
}
|
|
216
223
|
}
|
|
217
224
|
}
|
|
218
225
|
}
|
|
219
226
|
console.log("");
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
}
|
|
225
|
-
|
|
227
|
+
const report = buildSettingsReport(processingResults);
|
|
228
|
+
const lines = formatSettingsReportCLI(report);
|
|
229
|
+
for (const line of lines) {
|
|
230
|
+
console.log(line);
|
|
231
|
+
}
|
|
232
|
+
writeSettingsReportSummary(report, options.dryRun ?? false);
|
|
233
|
+
const hasErrors = report.repos.some((r) => r.error);
|
|
234
|
+
if (hasErrors) {
|
|
226
235
|
process.exit(1);
|
|
227
236
|
}
|
|
228
237
|
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { SettingsReport } from "../output/settings-report.js";
|
|
2
|
+
import type { RepoSettingsPlanEntry } from "../settings/repo-settings/formatter.js";
|
|
3
|
+
import type { RulesetPlanEntry } from "../settings/rulesets/formatter.js";
|
|
4
|
+
interface ProcessorResults {
|
|
5
|
+
repoName: string;
|
|
6
|
+
settingsResult?: {
|
|
7
|
+
planOutput?: {
|
|
8
|
+
entries?: RepoSettingsPlanEntry[];
|
|
9
|
+
};
|
|
10
|
+
};
|
|
11
|
+
rulesetResult?: {
|
|
12
|
+
planOutput?: {
|
|
13
|
+
entries?: RulesetPlanEntry[];
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
error?: string;
|
|
17
|
+
}
|
|
18
|
+
export declare function buildSettingsReport(results: ProcessorResults[]): SettingsReport;
|
|
19
|
+
export {};
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
export function buildSettingsReport(results) {
|
|
2
|
+
const repos = [];
|
|
3
|
+
const totals = {
|
|
4
|
+
settings: { add: 0, change: 0 },
|
|
5
|
+
rulesets: { create: 0, update: 0, delete: 0 },
|
|
6
|
+
};
|
|
7
|
+
for (const result of results) {
|
|
8
|
+
const repoChanges = {
|
|
9
|
+
repoName: result.repoName,
|
|
10
|
+
settings: [],
|
|
11
|
+
rulesets: [],
|
|
12
|
+
};
|
|
13
|
+
// Convert settings processor output
|
|
14
|
+
if (result.settingsResult?.planOutput?.entries) {
|
|
15
|
+
for (const entry of result.settingsResult.planOutput.entries) {
|
|
16
|
+
// Skip settings where both values are undefined (no actual change)
|
|
17
|
+
if (entry.oldValue === undefined && entry.newValue === undefined) {
|
|
18
|
+
continue;
|
|
19
|
+
}
|
|
20
|
+
const settingChange = {
|
|
21
|
+
name: entry.property,
|
|
22
|
+
action: entry.action,
|
|
23
|
+
oldValue: entry.oldValue,
|
|
24
|
+
newValue: entry.newValue,
|
|
25
|
+
};
|
|
26
|
+
repoChanges.settings.push(settingChange);
|
|
27
|
+
if (entry.action === "add") {
|
|
28
|
+
totals.settings.add++;
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
totals.settings.change++;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
// Convert ruleset processor output
|
|
36
|
+
if (result.rulesetResult?.planOutput?.entries) {
|
|
37
|
+
for (const entry of result.rulesetResult.planOutput.entries) {
|
|
38
|
+
if (entry.action === "unchanged")
|
|
39
|
+
continue;
|
|
40
|
+
const rulesetChange = {
|
|
41
|
+
name: entry.name,
|
|
42
|
+
action: entry.action,
|
|
43
|
+
propertyDiffs: entry.propertyDiffs,
|
|
44
|
+
config: entry.config,
|
|
45
|
+
};
|
|
46
|
+
repoChanges.rulesets.push(rulesetChange);
|
|
47
|
+
if (entry.action === "create") {
|
|
48
|
+
totals.rulesets.create++;
|
|
49
|
+
}
|
|
50
|
+
else if (entry.action === "update") {
|
|
51
|
+
totals.rulesets.update++;
|
|
52
|
+
}
|
|
53
|
+
else if (entry.action === "delete") {
|
|
54
|
+
totals.rulesets.delete++;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
if (result.error) {
|
|
59
|
+
repoChanges.error = result.error;
|
|
60
|
+
}
|
|
61
|
+
repos.push(repoChanges);
|
|
62
|
+
}
|
|
63
|
+
return { repos, totals };
|
|
64
|
+
}
|
package/dist/cli/sync-command.js
CHANGED
|
@@ -6,11 +6,9 @@ import { parseGitUrl, getRepoDisplayName } from "../shared/repo-detector.js";
|
|
|
6
6
|
import { sanitizeBranchName, validateBranchName } from "../vcs/git-ops.js";
|
|
7
7
|
import { logger } from "../shared/logger.js";
|
|
8
8
|
import { generateWorkspaceName } from "../shared/workspace-utils.js";
|
|
9
|
-
import { buildRepoResult, buildErrorResult } from "../output/summary-utils.js";
|
|
10
|
-
import { printPlan } from "../output/plan-formatter.js";
|
|
11
|
-
import { writePlanSummary } from "../output/plan-summary.js";
|
|
12
|
-
import { syncResultToResources } from "../settings/resource-converters.js";
|
|
13
9
|
import { defaultProcessorFactory } from "./types.js";
|
|
10
|
+
import { buildSyncReport } from "./sync-report-builder.js";
|
|
11
|
+
import { formatSyncReportCLI, writeSyncReportSummary, } from "../output/sync-report.js";
|
|
14
12
|
/**
|
|
15
13
|
* Get unique file names from all repos in the config
|
|
16
14
|
*/
|
|
@@ -44,6 +42,20 @@ function formatFileNames(fileNames) {
|
|
|
44
42
|
}
|
|
45
43
|
return `${fileNames.length} files`;
|
|
46
44
|
}
|
|
45
|
+
/**
|
|
46
|
+
* Determine merge outcome from processor result
|
|
47
|
+
*/
|
|
48
|
+
function determineMergeOutcome(result) {
|
|
49
|
+
if (!result.success)
|
|
50
|
+
return undefined;
|
|
51
|
+
if (!result.prUrl)
|
|
52
|
+
return "direct";
|
|
53
|
+
if (result.mergeResult?.merged)
|
|
54
|
+
return "force";
|
|
55
|
+
if (result.mergeResult?.autoMergeEnabled)
|
|
56
|
+
return "auto";
|
|
57
|
+
return "manual";
|
|
58
|
+
}
|
|
47
59
|
/**
|
|
48
60
|
* Run the sync command - synchronizes files across repositories.
|
|
49
61
|
*/
|
|
@@ -80,8 +92,7 @@ export async function runSync(options, processorFactory = defaultProcessorFactor
|
|
|
80
92
|
console.log(`Target files: ${formatFileNames(fileNames)}`);
|
|
81
93
|
console.log(`Branch: ${branchName}\n`);
|
|
82
94
|
const processor = processorFactory();
|
|
83
|
-
const
|
|
84
|
-
const plan = { resources: [], errors: [] };
|
|
95
|
+
const reportResults = [];
|
|
85
96
|
for (let i = 0; i < config.repos.length; i++) {
|
|
86
97
|
const repoConfig = config.repos[i];
|
|
87
98
|
if (options.merge || options.mergeStrategy || options.deleteBranch) {
|
|
@@ -101,10 +112,11 @@ export async function runSync(options, processorFactory = defaultProcessorFactor
|
|
|
101
112
|
}
|
|
102
113
|
catch (error) {
|
|
103
114
|
logger.error(current, repoConfig.git, String(error));
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
115
|
+
reportResults.push({
|
|
116
|
+
repoName: repoConfig.git,
|
|
117
|
+
success: false,
|
|
118
|
+
fileChanges: [],
|
|
119
|
+
error: error instanceof Error ? error.message : String(error),
|
|
108
120
|
});
|
|
109
121
|
continue;
|
|
110
122
|
}
|
|
@@ -121,35 +133,48 @@ export async function runSync(options, processorFactory = defaultProcessorFactor
|
|
|
121
133
|
prTemplate: config.prTemplate,
|
|
122
134
|
noDelete: options.noDelete,
|
|
123
135
|
});
|
|
124
|
-
const
|
|
125
|
-
|
|
136
|
+
const mergeOutcome = determineMergeOutcome(result);
|
|
137
|
+
reportResults.push({
|
|
138
|
+
repoName,
|
|
139
|
+
success: result.success,
|
|
140
|
+
fileChanges: (result.fileChanges ?? []).map((f) => ({
|
|
141
|
+
path: f.path,
|
|
142
|
+
action: f.action,
|
|
143
|
+
})),
|
|
144
|
+
prUrl: result.prUrl,
|
|
145
|
+
mergeOutcome,
|
|
146
|
+
error: result.success ? undefined : result.message,
|
|
147
|
+
});
|
|
126
148
|
if (result.skipped) {
|
|
127
149
|
logger.skip(current, repoName, result.message);
|
|
128
150
|
}
|
|
129
151
|
else if (result.success) {
|
|
130
|
-
logger.success(current, repoName,
|
|
152
|
+
logger.success(current, repoName, result.message);
|
|
131
153
|
}
|
|
132
154
|
else {
|
|
133
155
|
logger.error(current, repoName, result.message);
|
|
134
156
|
}
|
|
135
|
-
plan.resources.push(...syncResultToResources(repoName, repoConfig, result));
|
|
136
157
|
}
|
|
137
158
|
catch (error) {
|
|
138
159
|
logger.error(current, repoName, String(error));
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
160
|
+
reportResults.push({
|
|
161
|
+
repoName,
|
|
162
|
+
success: false,
|
|
163
|
+
fileChanges: [],
|
|
164
|
+
error: error instanceof Error ? error.message : String(error),
|
|
143
165
|
});
|
|
144
166
|
}
|
|
145
167
|
}
|
|
168
|
+
// Build and display report
|
|
169
|
+
const report = buildSyncReport(reportResults);
|
|
146
170
|
console.log("");
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
171
|
+
for (const line of formatSyncReportCLI(report)) {
|
|
172
|
+
console.log(line);
|
|
173
|
+
}
|
|
174
|
+
writeSyncReportSummary(report, options.dryRun ?? false);
|
|
175
|
+
// Exit with error if any failures
|
|
176
|
+
const hasErrors = reportResults.some((r) => r.error);
|
|
177
|
+
if (hasErrors) {
|
|
153
178
|
process.exit(1);
|
|
154
179
|
}
|
|
155
180
|
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { SyncReport } from "../output/sync-report.js";
|
|
2
|
+
interface FileChangeInput {
|
|
3
|
+
path: string;
|
|
4
|
+
action: "create" | "update" | "delete";
|
|
5
|
+
}
|
|
6
|
+
interface SyncResultInput {
|
|
7
|
+
repoName: string;
|
|
8
|
+
success: boolean;
|
|
9
|
+
fileChanges: FileChangeInput[];
|
|
10
|
+
prUrl?: string;
|
|
11
|
+
mergeOutcome?: "manual" | "auto" | "force" | "direct";
|
|
12
|
+
error?: string;
|
|
13
|
+
}
|
|
14
|
+
export declare function buildSyncReport(results: SyncResultInput[]): SyncReport;
|
|
15
|
+
export {};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export function buildSyncReport(results) {
|
|
2
|
+
const repos = [];
|
|
3
|
+
const totals = {
|
|
4
|
+
files: { create: 0, update: 0, delete: 0 },
|
|
5
|
+
};
|
|
6
|
+
for (const result of results) {
|
|
7
|
+
const files = result.fileChanges.map((f) => ({
|
|
8
|
+
path: f.path,
|
|
9
|
+
action: f.action,
|
|
10
|
+
}));
|
|
11
|
+
// Count totals
|
|
12
|
+
for (const file of files) {
|
|
13
|
+
if (file.action === "create")
|
|
14
|
+
totals.files.create++;
|
|
15
|
+
else if (file.action === "update")
|
|
16
|
+
totals.files.update++;
|
|
17
|
+
else if (file.action === "delete")
|
|
18
|
+
totals.files.delete++;
|
|
19
|
+
}
|
|
20
|
+
repos.push({
|
|
21
|
+
repoName: result.repoName,
|
|
22
|
+
files,
|
|
23
|
+
prUrl: result.prUrl,
|
|
24
|
+
mergeOutcome: result.mergeOutcome,
|
|
25
|
+
error: result.error,
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
return { repos, totals };
|
|
29
|
+
}
|
package/dist/output/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export {
|
|
2
|
-
export {
|
|
1
|
+
export { formatSyncReportCLI, formatSyncReportMarkdown, writeSyncReportSummary, type SyncReport, type RepoFileChanges, type FileChange, } from "./sync-report.js";
|
|
2
|
+
export { formatSettingsReportCLI, formatSettingsReportMarkdown, writeSettingsReportSummary, type SettingsReport, type RepoChanges, type RulesetChange, type SettingChange, } from "./settings-report.js";
|
|
3
3
|
export { formatSummary, isGitHubActions, writeSummary, type MergeOutcome, type FileChanges, type RulesetPlanDetail, type RepoSettingsPlanDetail, type RepoResult, type SummaryData, } from "./github-summary.js";
|
|
4
4
|
export { getMergeOutcome, toFileChanges, buildRepoResult, buildErrorResult, } from "./summary-utils.js";
|
package/dist/output/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
//
|
|
2
|
-
export {
|
|
3
|
-
//
|
|
4
|
-
export {
|
|
1
|
+
// Sync report (repo-grouped file changes)
|
|
2
|
+
export { formatSyncReportCLI, formatSyncReportMarkdown, writeSyncReportSummary, } from "./sync-report.js";
|
|
3
|
+
// Settings report (repo-grouped settings changes)
|
|
4
|
+
export { formatSettingsReportCLI, formatSettingsReportMarkdown, writeSettingsReportSummary, } from "./settings-report.js";
|
|
5
5
|
// GitHub Actions summary
|
|
6
6
|
export { formatSummary, isGitHubActions, writeSummary, } from "./github-summary.js";
|
|
7
7
|
// Summary utilities
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { type PropertyDiff } from "../settings/rulesets/formatter.js";
|
|
2
|
+
import type { Ruleset } from "../config/index.js";
|
|
3
|
+
export interface SettingsReport {
|
|
4
|
+
repos: RepoChanges[];
|
|
5
|
+
totals: {
|
|
6
|
+
settings: {
|
|
7
|
+
add: number;
|
|
8
|
+
change: number;
|
|
9
|
+
};
|
|
10
|
+
rulesets: {
|
|
11
|
+
create: number;
|
|
12
|
+
update: number;
|
|
13
|
+
delete: number;
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
export interface RepoChanges {
|
|
18
|
+
repoName: string;
|
|
19
|
+
settings: SettingChange[];
|
|
20
|
+
rulesets: RulesetChange[];
|
|
21
|
+
error?: string;
|
|
22
|
+
}
|
|
23
|
+
export interface SettingChange {
|
|
24
|
+
name: string;
|
|
25
|
+
action: "add" | "change";
|
|
26
|
+
oldValue?: unknown;
|
|
27
|
+
newValue: unknown;
|
|
28
|
+
}
|
|
29
|
+
export interface RulesetChange {
|
|
30
|
+
name: string;
|
|
31
|
+
action: "create" | "update" | "delete";
|
|
32
|
+
propertyDiffs?: PropertyDiff[];
|
|
33
|
+
config?: Ruleset;
|
|
34
|
+
}
|
|
35
|
+
export declare function formatSettingsReportCLI(report: SettingsReport): string[];
|
|
36
|
+
export declare function formatSettingsReportMarkdown(report: SettingsReport, dryRun: boolean): string;
|
|
37
|
+
export declare function writeSettingsReportSummary(report: SettingsReport, dryRun: boolean): void;
|