@aspruyt/xfg 6.1.0 → 6.3.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/lifecycle-report-builder.d.ts +2 -2
- package/dist/cli/lifecycle-report-builder.js +3 -11
- package/dist/cli/program.d.ts +2 -1
- package/dist/cli/program.js +43 -6
- package/dist/cli/repo-sync-runner.d.ts +24 -0
- package/dist/cli/repo-sync-runner.js +156 -0
- package/dist/cli/results-collector.d.ts +1 -1
- package/dist/cli/results-collector.js +2 -2
- package/dist/cli/secrets-command.d.ts +25 -0
- package/dist/cli/secrets-command.js +75 -0
- package/dist/cli/settings-factories.d.ts +8 -0
- package/dist/cli/settings-factories.js +32 -0
- package/dist/cli/settings-report-builder.d.ts +7 -2
- package/dist/cli/settings-report-builder.js +28 -20
- package/dist/cli/settings-runner.d.ts +2 -0
- package/dist/cli/settings-runner.js +94 -0
- package/dist/cli/sync-command.d.ts +1 -1
- package/dist/cli/sync-command.js +31 -372
- package/dist/cli/sync-report-builder.d.ts +1 -1
- package/dist/cli/sync-utils.d.ts +8 -0
- package/dist/cli/sync-utils.js +36 -0
- package/dist/cli/types.d.ts +8 -8
- package/dist/cli/unified-summary.d.ts +1 -3
- package/dist/cli/unified-summary.js +7 -5
- package/dist/cli.js +2 -1
- package/dist/{shared → config}/env.js +2 -2
- package/dist/config/extends-resolver.js +4 -3
- package/dist/config/file-reference-resolver.js +4 -2
- package/dist/config/formatter.js +1 -0
- package/dist/config/index.d.ts +2 -2
- package/dist/config/index.js +1 -1
- package/dist/config/loader.js +30 -6
- package/dist/config/merge.d.ts +11 -1
- package/dist/config/merge.js +78 -6
- package/dist/config/normalizer.js +129 -49
- package/dist/config/types.d.ts +20 -0
- package/dist/config/validator.d.ts +5 -4
- package/dist/config/validator.js +187 -614
- package/dist/config/validators/file-validator.d.ts +2 -1
- package/dist/config/validators/file-validator.js +9 -1
- package/dist/config/validators/group-validator.d.ts +3 -0
- package/dist/config/validators/group-validator.js +167 -0
- package/dist/config/validators/repo-entry-validator.d.ts +2 -0
- package/dist/config/validators/repo-entry-validator.js +165 -0
- package/dist/config/validators/repo-settings-validator.js +18 -7
- package/dist/config/validators/ruleset-validator.js +2 -5
- package/dist/config/validators/shared.d.ts +11 -0
- package/dist/config/validators/shared.js +242 -0
- package/dist/lifecycle/ado-migration-source.js +2 -4
- package/dist/lifecycle/github-lifecycle-provider.d.ts +7 -11
- package/dist/lifecycle/github-lifecycle-provider.js +125 -136
- package/dist/lifecycle/{lifecycle-helpers.d.ts → helpers.d.ts} +5 -1
- package/dist/lifecycle/{lifecycle-helpers.js → helpers.js} +9 -8
- package/dist/lifecycle/index.d.ts +2 -2
- package/dist/lifecycle/index.js +1 -1
- package/dist/lifecycle/repo-lifecycle-factory.d.ts +2 -2
- package/dist/output/github-summary.js +2 -3
- package/dist/output/index.d.ts +4 -0
- package/dist/output/index.js +4 -0
- package/dist/output/lifecycle-report.d.ts +1 -1
- package/dist/output/lifecycle-report.js +5 -0
- package/dist/output/settings-report.d.ts +11 -0
- package/dist/output/settings-report.js +24 -0
- package/dist/output/sync-report.d.ts +25 -3
- package/dist/output/sync-report.js +11 -11
- package/dist/secrets/encryption.d.ts +9 -0
- package/dist/secrets/encryption.js +29 -0
- package/dist/secrets/github-secrets-strategy.d.ts +17 -0
- package/dist/secrets/github-secrets-strategy.js +38 -0
- package/dist/secrets/index.d.ts +5 -0
- package/dist/secrets/index.js +3 -0
- package/dist/secrets/processor.d.ts +31 -0
- package/dist/secrets/processor.js +115 -0
- package/dist/secrets/types.d.ts +21 -0
- package/dist/settings/base-processor.d.ts +18 -7
- package/dist/settings/base-processor.js +26 -5
- package/dist/settings/code-scanning/diff.js +2 -2
- package/dist/settings/code-scanning/formatter.d.ts +2 -6
- package/dist/settings/code-scanning/formatter.js +2 -25
- package/dist/settings/code-scanning/github-code-scanning-strategy.d.ts +3 -7
- package/dist/settings/code-scanning/github-code-scanning-strategy.js +2 -2
- package/dist/settings/code-scanning/processor.js +6 -4
- package/dist/settings/code-scanning/types.d.ts +10 -8
- package/dist/settings/index.d.ts +1 -0
- package/dist/settings/index.js +2 -0
- package/dist/settings/labels/github-labels-strategy.d.ts +3 -11
- package/dist/settings/labels/types.d.ts +12 -10
- package/dist/settings/repo-settings/diff.d.ts +1 -1
- package/dist/settings/repo-settings/diff.js +1 -1
- package/dist/settings/repo-settings/formatter.d.ts +2 -6
- package/dist/settings/repo-settings/formatter.js +4 -23
- package/dist/settings/repo-settings/github-repo-settings-strategy.d.ts +2 -2
- package/dist/settings/repo-settings/github-repo-settings-strategy.js +8 -7
- package/dist/settings/repo-settings/processor.js +11 -11
- package/dist/settings/repo-settings/types.d.ts +2 -2
- package/dist/settings/rulesets/diff-algorithm.js +4 -2
- package/dist/settings/rulesets/diff.js +2 -51
- package/dist/settings/rulesets/formatter.js +4 -0
- package/dist/settings/rulesets/github-ruleset-strategy.d.ts +3 -3
- package/dist/settings/rulesets/github-ruleset-strategy.js +4 -6
- package/dist/settings/rulesets/index.d.ts +1 -1
- package/dist/settings/rulesets/index.js +0 -2
- package/dist/settings/rulesets/processor.js +1 -1
- package/dist/settings/rulesets/types.d.ts +6 -2
- package/dist/settings/variables/diff.d.ts +10 -0
- package/dist/settings/variables/diff.js +39 -0
- package/dist/settings/variables/formatter.d.ts +16 -0
- package/dist/settings/variables/formatter.js +70 -0
- package/dist/settings/variables/github-variables-strategy.d.ts +17 -0
- package/dist/settings/variables/github-variables-strategy.js +40 -0
- package/dist/settings/variables/index.d.ts +4 -0
- package/dist/settings/variables/index.js +2 -0
- package/dist/settings/variables/processor.d.ts +19 -0
- package/dist/settings/variables/processor.js +60 -0
- package/dist/settings/variables/types.d.ts +18 -0
- package/dist/settings/variables/types.js +1 -0
- package/dist/shared/command-executor.d.ts +4 -4
- package/dist/shared/command-executor.js +9 -7
- package/dist/shared/diff-format.d.ts +1 -0
- package/dist/shared/diff-format.js +10 -0
- package/dist/shared/env-resolver.d.ts +16 -0
- package/dist/shared/env-resolver.js +33 -0
- package/dist/shared/errors.d.ts +7 -4
- package/dist/shared/errors.js +8 -8
- package/dist/shared/gh-api-utils.d.ts +3 -34
- package/dist/shared/gh-api-utils.js +23 -53
- package/dist/shared/gh-token-utils.d.ts +26 -0
- package/dist/shared/gh-token-utils.js +32 -0
- package/dist/shared/json-utils.js +1 -1
- package/dist/shared/regex-utils.d.ts +1 -0
- package/dist/shared/regex-utils.js +3 -0
- package/dist/shared/retry-utils.d.ts +1 -0
- package/dist/shared/retry-utils.js +13 -7
- package/dist/sync/auth-options-builder.js +1 -1
- package/dist/sync/branch-manager.js +5 -3
- package/dist/sync/commit-push-manager.js +2 -3
- package/dist/sync/diff-utils.d.ts +0 -1
- package/dist/sync/diff-utils.js +5 -10
- package/dist/sync/file-sync-orchestrator.js +0 -2
- package/dist/sync/file-writer.d.ts +3 -0
- package/dist/sync/file-writer.js +84 -81
- package/dist/sync/index.d.ts +0 -1
- package/dist/sync/index.js +0 -1
- package/dist/sync/manifest.js +1 -1
- package/dist/sync/pr-merge-handler.js +6 -6
- package/dist/sync/sync-workflow.js +1 -1
- package/dist/sync/types.d.ts +2 -2
- package/dist/vcs/ado-pr-strategy.d.ts +3 -5
- package/dist/vcs/ado-pr-strategy.js +131 -33
- package/dist/vcs/authenticated-git-ops.js +45 -23
- package/dist/vcs/git-commit-strategy.js +10 -6
- package/dist/vcs/git-ops.js +30 -24
- package/dist/vcs/github-pr-strategy.d.ts +3 -2
- package/dist/vcs/github-pr-strategy.js +80 -30
- package/dist/vcs/gitlab-pr-strategy.d.ts +2 -5
- package/dist/vcs/gitlab-pr-strategy.js +88 -87
- package/dist/vcs/graphql-commit-strategy.d.ts +1 -5
- package/dist/vcs/graphql-commit-strategy.js +21 -37
- package/dist/vcs/pr-creator.js +9 -2
- package/dist/vcs/pr-strategy.d.ts +2 -3
- package/dist/vcs/pr-strategy.js +0 -1
- package/dist/vcs/types.d.ts +9 -5
- package/package.json +7 -5
- package/dist/config/validators/index.d.ts +0 -3
- package/dist/config/validators/index.js +0 -6
- package/dist/output/types.d.ts +0 -20
- package/dist/shared/shell-utils.d.ts +0 -6
- package/dist/shared/shell-utils.js +0 -17
- /package/dist/{shared → config}/env.d.ts +0 -0
- /package/dist/lifecycle/{lifecycle-formatter.d.ts → formatter.d.ts} +0 -0
- /package/dist/lifecycle/{lifecycle-formatter.js → formatter.js} +0 -0
- /package/dist/{output → secrets}/types.js +0 -0
- /package/dist/{vcs → shared}/sanitize-utils.d.ts +0 -0
- /package/dist/{vcs → shared}/sanitize-utils.js +0 -0
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { isGitHubRepo } from "../repo/index.js";
|
|
2
|
+
import { toErrorMessage } from "../shared/type-guards.js";
|
|
3
|
+
function logSettingsResult(logger, result, label, repoNumber, repoName, settingsCollector) {
|
|
4
|
+
if (result.planOutput?.lines?.length) {
|
|
5
|
+
logger.info("");
|
|
6
|
+
logger.info(`${repoName} - ${label}:`);
|
|
7
|
+
for (const line of result.planOutput.lines) {
|
|
8
|
+
logger.info(line);
|
|
9
|
+
}
|
|
10
|
+
if (result.warnings?.length) {
|
|
11
|
+
for (const warning of result.warnings) {
|
|
12
|
+
logger.warn(warning);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
else if (!result.skipped && result.success) {
|
|
17
|
+
logger.success(repoNumber, repoName, `${label}: ${result.message}`);
|
|
18
|
+
}
|
|
19
|
+
if (!result.success && !result.skipped) {
|
|
20
|
+
logger.error(repoNumber, repoName, `${label}: ${result.message}`);
|
|
21
|
+
settingsCollector.appendError(repoName, result.message);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
async function runAndStoreResult(factory, repoConfig, repoInfo, opts, repoName, settingsCollector, assign) {
|
|
25
|
+
const result = await factory().process(repoConfig, repoInfo, opts);
|
|
26
|
+
if (!result.skipped) {
|
|
27
|
+
assign(settingsCollector.findOrCreate(repoName), result);
|
|
28
|
+
}
|
|
29
|
+
return result;
|
|
30
|
+
}
|
|
31
|
+
function buildSettingsDescriptors(ctx) {
|
|
32
|
+
const { repoConfig, repoInfo, options, token, repoName, settingsCollector } = ctx;
|
|
33
|
+
const { factories } = ctx;
|
|
34
|
+
const sharedOpts = {
|
|
35
|
+
dryRun: options.dryRun,
|
|
36
|
+
noDelete: options.noDelete,
|
|
37
|
+
token,
|
|
38
|
+
};
|
|
39
|
+
return [
|
|
40
|
+
{
|
|
41
|
+
key: "rulesets",
|
|
42
|
+
label: "Rulesets",
|
|
43
|
+
run: () => runAndStoreResult(factories.rulesets, repoConfig, repoInfo, sharedOpts, repoName, settingsCollector, (e, r) => {
|
|
44
|
+
e.rulesetResult = r;
|
|
45
|
+
}),
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
key: "labels",
|
|
49
|
+
label: "Labels",
|
|
50
|
+
run: () => runAndStoreResult(factories.labels, repoConfig, repoInfo, sharedOpts, repoName, settingsCollector, (e, r) => {
|
|
51
|
+
e.labelsResult = r;
|
|
52
|
+
}),
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
key: "repo",
|
|
56
|
+
label: "Repo Settings",
|
|
57
|
+
run: () => runAndStoreResult(factories.repo, repoConfig, repoInfo, { dryRun: options.dryRun, token }, repoName, settingsCollector, (e, r) => {
|
|
58
|
+
e.settingsResult = r;
|
|
59
|
+
}),
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
key: "codeScanning",
|
|
63
|
+
label: "Code Scanning",
|
|
64
|
+
run: () => runAndStoreResult(factories.codeScanning, repoConfig, repoInfo, sharedOpts, repoName, settingsCollector, (e, r) => {
|
|
65
|
+
e.codeScanningResult = r;
|
|
66
|
+
}),
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
key: "variables",
|
|
70
|
+
label: "Variables",
|
|
71
|
+
run: () => runAndStoreResult(factories.variables, repoConfig, repoInfo, sharedOpts, repoName, settingsCollector, (e, r) => {
|
|
72
|
+
e.variablesResult = r;
|
|
73
|
+
}),
|
|
74
|
+
},
|
|
75
|
+
];
|
|
76
|
+
}
|
|
77
|
+
export async function applyRepoSettings(ctx) {
|
|
78
|
+
const { repoConfig, repoInfo, repoName, repoNumber, settingsCollector, logger, } = ctx;
|
|
79
|
+
if (!repoConfig.settings || !isGitHubRepo(repoInfo))
|
|
80
|
+
return;
|
|
81
|
+
for (const desc of buildSettingsDescriptors(ctx)) {
|
|
82
|
+
const settingsValue = repoConfig.settings[desc.key];
|
|
83
|
+
if (!settingsValue || Object.keys(settingsValue).length === 0)
|
|
84
|
+
continue;
|
|
85
|
+
try {
|
|
86
|
+
const result = await desc.run();
|
|
87
|
+
logSettingsResult(logger, result, desc.label, repoNumber, repoName, settingsCollector);
|
|
88
|
+
}
|
|
89
|
+
catch (error) {
|
|
90
|
+
logger.error(repoNumber, repoName, `${desc.label}: ${toErrorMessage(error)}`);
|
|
91
|
+
settingsCollector.appendError(repoName, error);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { SyncDependencies, SyncOptions } from "./types.js";
|
|
2
2
|
export type { SharedOptions, SyncOptions } from "./types.js";
|
|
3
3
|
export declare function runSync(options: SyncOptions, deps?: SyncDependencies): Promise<void>;
|
package/dist/cli/sync-command.js
CHANGED
|
@@ -1,209 +1,47 @@
|
|
|
1
|
-
import { resolve
|
|
1
|
+
import { resolve } from "node:path";
|
|
2
2
|
import { existsSync } from "node:fs";
|
|
3
3
|
import { loadRawConfig, normalizeConfig, validateForSync, } from "../config/index.js";
|
|
4
4
|
import { ValidationError, SyncError } from "../shared/errors.js";
|
|
5
|
-
import {
|
|
6
|
-
import { sanitizeBranchName, validateBranchName } from "./branch-utils.js";
|
|
5
|
+
import { validateBranchName } from "./branch-utils.js";
|
|
7
6
|
import { createTokenManager } from "../vcs/index.js";
|
|
8
7
|
import { RepositoryProcessor } from "../sync/index.js";
|
|
9
|
-
import {
|
|
10
|
-
import { GitHubRepoMetadataProvider } from "../repo/index.js";
|
|
11
|
-
import { ShellCommandExecutor } from "../shared/command-executor.js";
|
|
8
|
+
import { ProcessExecutor } from "../shared/command-executor.js";
|
|
12
9
|
import { Logger } from "../shared/logger.js";
|
|
13
|
-
import { generateWorkspaceName } from "../shared/workspace-utils.js";
|
|
14
|
-
let _defaultExecutor;
|
|
15
|
-
let _logger;
|
|
16
|
-
function getDefaultExecutor() {
|
|
17
|
-
return (_defaultExecutor ??= new ShellCommandExecutor(process.env));
|
|
18
|
-
}
|
|
19
|
-
function getLogger() {
|
|
20
|
-
return (_logger ??= new Logger(!!(process.env.DEBUG || process.env.XFG_DEBUG)));
|
|
21
|
-
}
|
|
22
|
-
function createDefaultRulesetProcessorFactory() {
|
|
23
|
-
const cwd = process.cwd();
|
|
24
|
-
return () => new RulesetProcessor(new GitHubRulesetStrategy(getDefaultExecutor(), { cwd }));
|
|
25
|
-
}
|
|
26
|
-
function createDefaultRepoSettingsProcessorFactory() {
|
|
27
|
-
const cwd = process.cwd();
|
|
28
|
-
const executor = getDefaultExecutor();
|
|
29
|
-
return () => new RepoSettingsProcessor(new GitHubRepoSettingsStrategy(executor, { cwd }), new GitHubRepoMetadataProvider(executor, { cwd }));
|
|
30
|
-
}
|
|
31
|
-
function createDefaultLabelsProcessorFactory() {
|
|
32
|
-
const cwd = process.cwd();
|
|
33
|
-
return () => new LabelsProcessor(new GitHubLabelsStrategy(getDefaultExecutor(), { cwd }));
|
|
34
|
-
}
|
|
35
|
-
function createDefaultCodeScanningProcessorFactory() {
|
|
36
|
-
const cwd = process.cwd();
|
|
37
|
-
const executor = getDefaultExecutor();
|
|
38
|
-
return () => new CodeScanningProcessor(new GitHubCodeScanningStrategy(executor, { cwd }), new GitHubRepoMetadataProvider(executor, { cwd }));
|
|
39
|
-
}
|
|
40
10
|
import { ResultsCollector } from "./results-collector.js";
|
|
41
|
-
import { buildSettingsReport
|
|
42
|
-
import { formatSettingsReportCLI } from "../output/
|
|
11
|
+
import { buildSettingsReport } from "./settings-report-builder.js";
|
|
12
|
+
import { formatSettingsReportCLI, formatSyncReportCLI, formatLifecycleReportCLI, hasLifecycleChanges, } from "../output/index.js";
|
|
43
13
|
import { buildSyncReport } from "./sync-report-builder.js";
|
|
44
|
-
import { formatSyncReportCLI } from "../output/sync-report.js";
|
|
45
14
|
import { buildLifecycleReport } from "./lifecycle-report-builder.js";
|
|
46
|
-
import { formatLifecycleReportCLI, hasLifecycleChanges, } from "../output/lifecycle-report.js";
|
|
47
15
|
import { writeUnifiedSummary } from "./unified-summary.js";
|
|
48
|
-
import {
|
|
49
|
-
import {
|
|
50
|
-
import {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
for (const repo of config.repos) {
|
|
54
|
-
for (const file of repo.files) {
|
|
55
|
-
fileNames.add(file.fileName);
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
return Array.from(fileNames);
|
|
59
|
-
}
|
|
60
|
-
function generateBranchName(fileNames) {
|
|
61
|
-
if (fileNames.length === 1) {
|
|
62
|
-
return `chore/sync-${sanitizeBranchName(fileNames[0])}`;
|
|
63
|
-
}
|
|
64
|
-
return "chore/sync-config";
|
|
65
|
-
}
|
|
66
|
-
function formatFileNames(fileNames) {
|
|
67
|
-
if (fileNames.length === 1) {
|
|
68
|
-
return fileNames[0];
|
|
69
|
-
}
|
|
70
|
-
if (fileNames.length <= 3) {
|
|
71
|
-
return fileNames.join(", ");
|
|
72
|
-
}
|
|
73
|
-
return `${fileNames.length} files`;
|
|
74
|
-
}
|
|
75
|
-
function determineMergeOutcome(result) {
|
|
76
|
-
if (!result.success)
|
|
77
|
-
return undefined;
|
|
78
|
-
if (!result.prUrl)
|
|
79
|
-
return "direct";
|
|
80
|
-
if (result.mergeResult?.merged)
|
|
81
|
-
return "force";
|
|
82
|
-
if (result.mergeResult?.autoMergeEnabled)
|
|
83
|
-
return "auto";
|
|
84
|
-
return "manual";
|
|
85
|
-
}
|
|
86
|
-
function logSettingsResult(result, label, repoNumber, repoName, settingsCollector) {
|
|
87
|
-
if (result.planOutput?.lines?.length) {
|
|
88
|
-
getLogger().info("");
|
|
89
|
-
getLogger().info(`${repoName} - ${label}:`);
|
|
90
|
-
for (const line of result.planOutput.lines) {
|
|
91
|
-
getLogger().info(line);
|
|
92
|
-
}
|
|
93
|
-
if (result.warnings?.length) {
|
|
94
|
-
for (const warning of result.warnings) {
|
|
95
|
-
getLogger().warn(warning);
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
else if (!result.skipped && result.success) {
|
|
100
|
-
getLogger().success(repoNumber, repoName, `${label}: ${result.message}`);
|
|
101
|
-
}
|
|
102
|
-
if (!result.success && !result.skipped) {
|
|
103
|
-
getLogger().error(repoNumber, repoName, `${label}: ${result.message}`);
|
|
104
|
-
settingsCollector.appendError(repoName, result.message);
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
// Each processor returns a subtype of BaseProcessorResult whose planOutput
|
|
108
|
-
// contains both `lines` (for CLI display) and `entries` (for report building).
|
|
109
|
-
// ProcessorResults fields capture only the `entries` slice; the runtime object
|
|
110
|
-
// satisfies both views, so we assign with an explicit per-field cast.
|
|
111
|
-
async function runAndStoreResult(factory, repoConfig, repoInfo, opts, repoName, settingsCollector, assign) {
|
|
112
|
-
const result = await runSettingsProcessor(factory, repoConfig, repoInfo, opts);
|
|
113
|
-
if (!result.skipped) {
|
|
114
|
-
assign(settingsCollector.getOrCreate(repoName), result);
|
|
115
|
-
}
|
|
116
|
-
return result;
|
|
117
|
-
}
|
|
118
|
-
function buildSettingsDescriptors(ctx) {
|
|
119
|
-
const { repoConfig, repoInfo, options, token, repoName, settingsCollector } = ctx;
|
|
120
|
-
const { factories } = ctx;
|
|
121
|
-
const sharedOpts = {
|
|
122
|
-
dryRun: options.dryRun,
|
|
123
|
-
noDelete: options.noDelete,
|
|
124
|
-
token,
|
|
125
|
-
};
|
|
126
|
-
return [
|
|
127
|
-
{
|
|
128
|
-
key: "rulesets",
|
|
129
|
-
label: "Rulesets",
|
|
130
|
-
run: () => runAndStoreResult(factories.rulesets, repoConfig, repoInfo, sharedOpts, repoName, settingsCollector, (e, r) => {
|
|
131
|
-
e.rulesetResult = r;
|
|
132
|
-
}),
|
|
133
|
-
},
|
|
134
|
-
{
|
|
135
|
-
key: "labels",
|
|
136
|
-
label: "Labels",
|
|
137
|
-
run: () => runAndStoreResult(factories.labels, repoConfig, repoInfo, sharedOpts, repoName, settingsCollector, (e, r) => {
|
|
138
|
-
e.labelsResult = r;
|
|
139
|
-
}),
|
|
140
|
-
},
|
|
141
|
-
{
|
|
142
|
-
key: "repo",
|
|
143
|
-
label: "Repo Settings",
|
|
144
|
-
run: () => runAndStoreResult(factories.repo, repoConfig, repoInfo, { dryRun: options.dryRun, token }, repoName, settingsCollector, (e, r) => {
|
|
145
|
-
e.settingsResult = r;
|
|
146
|
-
}),
|
|
147
|
-
},
|
|
148
|
-
{
|
|
149
|
-
key: "codeScanning",
|
|
150
|
-
label: "Code Scanning",
|
|
151
|
-
run: () => runAndStoreResult(factories.codeScanning, repoConfig, repoInfo, sharedOpts, repoName, settingsCollector, (e, r) => {
|
|
152
|
-
e.codeScanningResult = r;
|
|
153
|
-
}),
|
|
154
|
-
},
|
|
155
|
-
];
|
|
156
|
-
}
|
|
157
|
-
function runSettingsProcessor(factory, repoConfig, repoInfo, processOptions) {
|
|
158
|
-
return factory()
|
|
159
|
-
.process(repoConfig, repoInfo, processOptions)
|
|
160
|
-
.then((result) => result);
|
|
161
|
-
}
|
|
162
|
-
async function applyRepoSettings(ctx) {
|
|
163
|
-
const { repoConfig, repoInfo, repoName, repoNumber, settingsCollector } = ctx;
|
|
164
|
-
if (!repoConfig.settings || !isGitHubRepo(repoInfo))
|
|
165
|
-
return;
|
|
166
|
-
for (const desc of buildSettingsDescriptors(ctx)) {
|
|
167
|
-
const settingsValue = repoConfig.settings[desc.key];
|
|
168
|
-
if (!settingsValue || Object.keys(settingsValue).length === 0)
|
|
169
|
-
continue;
|
|
170
|
-
try {
|
|
171
|
-
const result = await desc.run();
|
|
172
|
-
logSettingsResult(result, desc.label, repoNumber, repoName, settingsCollector);
|
|
173
|
-
}
|
|
174
|
-
catch (error) {
|
|
175
|
-
getLogger().error(repoNumber, repoName, `${desc.label}: ${toErrorMessage(error)}`);
|
|
176
|
-
settingsCollector.appendError(repoName, error);
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
function displayReports(reportResults, lifecycleReportInputs, settingsCollector, dryRun) {
|
|
16
|
+
import { RepoLifecycleManager } from "../lifecycle/index.js";
|
|
17
|
+
import { createDefaultFactories } from "./settings-factories.js";
|
|
18
|
+
import { getUniqueFileNames, generateBranchName, formatFileNames, } from "./sync-utils.js";
|
|
19
|
+
import { runSingleRepo, } from "./repo-sync-runner.js";
|
|
20
|
+
function displayReports(logger, reportResults, lifecycleReportInputs, settingsCollector, dryRun) {
|
|
181
21
|
const lifecycleReport = buildLifecycleReport(lifecycleReportInputs);
|
|
182
22
|
if (hasLifecycleChanges(lifecycleReport)) {
|
|
183
|
-
|
|
23
|
+
logger.log("");
|
|
184
24
|
for (const line of formatLifecycleReportCLI(lifecycleReport)) {
|
|
185
|
-
|
|
25
|
+
logger.log(line);
|
|
186
26
|
}
|
|
187
27
|
}
|
|
188
28
|
const report = buildSyncReport(reportResults);
|
|
189
|
-
|
|
29
|
+
logger.log("");
|
|
190
30
|
for (const line of formatSyncReportCLI(report)) {
|
|
191
|
-
|
|
31
|
+
logger.log(line);
|
|
192
32
|
}
|
|
193
|
-
// Build and display settings report (if any settings were processed)
|
|
194
33
|
const settingsResults = settingsCollector.getAll();
|
|
195
34
|
let settingsReport;
|
|
196
35
|
if (settingsResults.length > 0) {
|
|
197
36
|
settingsReport = buildSettingsReport(settingsResults);
|
|
198
37
|
const settingsLines = formatSettingsReportCLI(settingsReport);
|
|
199
38
|
if (settingsLines.length > 0) {
|
|
200
|
-
|
|
39
|
+
logger.log("");
|
|
201
40
|
for (const line of settingsLines) {
|
|
202
|
-
|
|
41
|
+
logger.log(line);
|
|
203
42
|
}
|
|
204
43
|
}
|
|
205
44
|
}
|
|
206
|
-
// Write unified summary to GITHUB_STEP_SUMMARY
|
|
207
45
|
writeUnifiedSummary({
|
|
208
46
|
lifecycle: lifecycleReport,
|
|
209
47
|
sync: report,
|
|
@@ -212,198 +50,18 @@ function displayReports(reportResults, lifecycleReportInputs, settingsCollector,
|
|
|
212
50
|
summaryPath: process.env.GITHUB_STEP_SUMMARY,
|
|
213
51
|
});
|
|
214
52
|
}
|
|
215
|
-
function pushFailure(results, repoName, error) {
|
|
216
|
-
results.push({
|
|
217
|
-
repoName,
|
|
218
|
-
success: false,
|
|
219
|
-
fileChanges: [],
|
|
220
|
-
error: toErrorMessage(error),
|
|
221
|
-
});
|
|
222
|
-
}
|
|
223
|
-
/**
|
|
224
|
-
* Process a single repository: resolve URL, run lifecycle check, sync files, apply settings.
|
|
225
|
-
* Pushes results into ctx.reportResults, ctx.lifecycleReportInputs, and ctx.settingsCollector.
|
|
226
|
-
*/
|
|
227
|
-
async function processSingleRepo(repoConfig, index, ctx) {
|
|
228
|
-
const { config, options } = ctx;
|
|
229
|
-
const repoNumber = index + 1;
|
|
230
|
-
// Apply CLI-level PR option overrides
|
|
231
|
-
if (options.merge || options.mergeStrategy || options.deleteBranch) {
|
|
232
|
-
repoConfig.prOptions = {
|
|
233
|
-
...repoConfig.prOptions,
|
|
234
|
-
merge: options.merge ?? repoConfig.prOptions?.merge,
|
|
235
|
-
mergeStrategy: options.mergeStrategy ?? repoConfig.prOptions?.mergeStrategy,
|
|
236
|
-
deleteBranch: options.deleteBranch ?? repoConfig.prOptions?.deleteBranch,
|
|
237
|
-
};
|
|
238
|
-
}
|
|
239
|
-
const mergeMode = repoConfig.prOptions?.merge ?? "auto";
|
|
240
|
-
if (mergeMode === "direct" && repoConfig.prOptions?.mergeStrategy) {
|
|
241
|
-
getLogger().warn(`mergeStrategy '${repoConfig.prOptions.mergeStrategy}' is ignored in direct mode for ${repoConfig.git}`);
|
|
242
|
-
}
|
|
243
|
-
let repoInfo;
|
|
244
|
-
try {
|
|
245
|
-
repoInfo = parseGitUrl(repoConfig.git, {
|
|
246
|
-
githubHosts: config.githubHosts,
|
|
247
|
-
});
|
|
248
|
-
}
|
|
249
|
-
catch (error) {
|
|
250
|
-
getLogger().error(repoNumber, repoConfig.git, toErrorMessage(error));
|
|
251
|
-
pushFailure(ctx.reportResults, repoConfig.git, error);
|
|
252
|
-
return;
|
|
253
|
-
}
|
|
254
|
-
const repoName = getRepoDisplayName(repoInfo);
|
|
255
|
-
const workDir = resolve(join(options.workDir ?? "./tmp", generateWorkspaceName(index)));
|
|
256
|
-
const repoToken = isGitHubRepo(repoInfo)
|
|
257
|
-
? (await resolveGitHubToken({
|
|
258
|
-
repoInfo: repoInfo,
|
|
259
|
-
tokenManager: ctx.tokenManager,
|
|
260
|
-
context: repoName,
|
|
261
|
-
log: getLogger(),
|
|
262
|
-
envToken: process.env.GH_TOKEN,
|
|
263
|
-
})).token
|
|
264
|
-
: undefined;
|
|
265
|
-
const repo = {
|
|
266
|
-
repoConfig,
|
|
267
|
-
repoInfo,
|
|
268
|
-
repoName,
|
|
269
|
-
index,
|
|
270
|
-
workDir,
|
|
271
|
-
token: repoToken,
|
|
272
|
-
};
|
|
273
|
-
const skipFileSync = await runLifecyclePhase(repo, ctx);
|
|
274
|
-
if (skipFileSync)
|
|
275
|
-
return;
|
|
276
|
-
// Sync files via processor
|
|
277
|
-
await runFileSyncPhase(repo, ctx);
|
|
278
|
-
// Apply settings via API (GitHub-only — ADO and GitLab repos are skipped)
|
|
279
|
-
await applyRepoSettings({
|
|
280
|
-
repoConfig,
|
|
281
|
-
repoInfo,
|
|
282
|
-
repoName,
|
|
283
|
-
repoNumber,
|
|
284
|
-
options,
|
|
285
|
-
token: repoToken,
|
|
286
|
-
settingsCollector: ctx.settingsCollector,
|
|
287
|
-
factories: ctx.factories,
|
|
288
|
-
});
|
|
289
|
-
}
|
|
290
|
-
/**
|
|
291
|
-
* Run lifecycle check (repo existence, creation, forking).
|
|
292
|
-
* Returns true if the main loop should skip file sync for this repo.
|
|
293
|
-
*/
|
|
294
|
-
async function runLifecyclePhase(repo, ctx) {
|
|
295
|
-
const repoNumber = repo.index + 1;
|
|
296
|
-
try {
|
|
297
|
-
const { outputLines, lifecycleResult, createSettings } = await runLifecycleCheck(repo.repoConfig, repo.repoInfo, {
|
|
298
|
-
dryRun: ctx.options.dryRun ?? false,
|
|
299
|
-
resolvedWorkDir: repo.workDir,
|
|
300
|
-
githubHosts: ctx.config.githubHosts,
|
|
301
|
-
token: repo.token,
|
|
302
|
-
repoIndex: repo.index,
|
|
303
|
-
lifecycleManager: ctx.lifecycleManager,
|
|
304
|
-
repoSettings: ctx.config.settings?.repo,
|
|
305
|
-
});
|
|
306
|
-
for (const line of outputLines) {
|
|
307
|
-
getLogger().info(line);
|
|
308
|
-
}
|
|
309
|
-
ctx.lifecycleReportInputs.push({
|
|
310
|
-
repoName: repo.repoName,
|
|
311
|
-
action: lifecycleResult.action,
|
|
312
|
-
upstream: repo.repoConfig.upstream,
|
|
313
|
-
source: repo.repoConfig.source,
|
|
314
|
-
settings: createSettings
|
|
315
|
-
? {
|
|
316
|
-
visibility: createSettings.visibility,
|
|
317
|
-
description: createSettings.description,
|
|
318
|
-
}
|
|
319
|
-
: undefined,
|
|
320
|
-
});
|
|
321
|
-
// In dry-run, skip processing repos that don't exist yet
|
|
322
|
-
if (ctx.options.dryRun && lifecycleResult.action !== "existed") {
|
|
323
|
-
ctx.reportResults.push({
|
|
324
|
-
repoName: repo.repoName,
|
|
325
|
-
success: true,
|
|
326
|
-
fileChanges: [],
|
|
327
|
-
});
|
|
328
|
-
return true;
|
|
329
|
-
}
|
|
330
|
-
return false;
|
|
331
|
-
}
|
|
332
|
-
catch (error) {
|
|
333
|
-
getLogger().error(repoNumber, repo.repoName, `Lifecycle error: ${toErrorMessage(error)}`);
|
|
334
|
-
pushFailure(ctx.reportResults, repo.repoName, error);
|
|
335
|
-
return true;
|
|
336
|
-
}
|
|
337
|
-
}
|
|
338
|
-
/**
|
|
339
|
-
* Run the file sync processor for a single repo and collect results.
|
|
340
|
-
*/
|
|
341
|
-
async function runFileSyncPhase(repo, ctx) {
|
|
342
|
-
const repoNumber = repo.index + 1;
|
|
343
|
-
try {
|
|
344
|
-
getLogger().progress(repoNumber, repo.repoName, "Processing...");
|
|
345
|
-
const result = await ctx.processor.process(repo.repoConfig, repo.repoInfo, {
|
|
346
|
-
branchName: ctx.branchName,
|
|
347
|
-
workDir: repo.workDir,
|
|
348
|
-
configId: ctx.config.id,
|
|
349
|
-
dryRun: ctx.options.dryRun,
|
|
350
|
-
retries: ctx.options.retries,
|
|
351
|
-
executor: getDefaultExecutor(),
|
|
352
|
-
prTemplate: ctx.config.prTemplate,
|
|
353
|
-
noDelete: ctx.options.noDelete,
|
|
354
|
-
token: repo.token,
|
|
355
|
-
hasAppCredentials: isGitHubRepo(repo.repoInfo) && ctx.tokenManager !== null,
|
|
356
|
-
});
|
|
357
|
-
const mergeOutcome = determineMergeOutcome(result);
|
|
358
|
-
ctx.reportResults.push({
|
|
359
|
-
repoName: repo.repoName,
|
|
360
|
-
success: result.success,
|
|
361
|
-
fileChanges: (result.fileChanges ?? []).map((f) => ({
|
|
362
|
-
path: f.path,
|
|
363
|
-
action: f.action,
|
|
364
|
-
...(f.diffLines ? { diffLines: f.diffLines } : {}),
|
|
365
|
-
})),
|
|
366
|
-
prUrl: result.prUrl,
|
|
367
|
-
mergeOutcome,
|
|
368
|
-
error: result.success ? undefined : result.message,
|
|
369
|
-
});
|
|
370
|
-
if (result.skipped) {
|
|
371
|
-
getLogger().skip(repoNumber, repo.repoName, result.message);
|
|
372
|
-
}
|
|
373
|
-
else if (result.success) {
|
|
374
|
-
getLogger().success(repoNumber, repo.repoName, result.message);
|
|
375
|
-
}
|
|
376
|
-
else {
|
|
377
|
-
getLogger().error(repoNumber, repo.repoName, result.message);
|
|
378
|
-
}
|
|
379
|
-
}
|
|
380
|
-
catch (error) {
|
|
381
|
-
getLogger().error(repoNumber, repo.repoName, toErrorMessage(error));
|
|
382
|
-
pushFailure(ctx.reportResults, repo.repoName, error);
|
|
383
|
-
}
|
|
384
|
-
}
|
|
385
53
|
export async function runSync(options, deps = {}) {
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
_logger = undefined;
|
|
54
|
+
const executor = new ProcessExecutor(process.env);
|
|
55
|
+
const logger = new Logger(!!(process.env.DEBUG || process.env.XFG_DEBUG));
|
|
389
56
|
const { lifecycleManager, settingsProcessorFactories } = deps;
|
|
390
|
-
const factories =
|
|
391
|
-
rulesets: settingsProcessorFactories?.rulesets ??
|
|
392
|
-
createDefaultRulesetProcessorFactory(),
|
|
393
|
-
labels: settingsProcessorFactories?.labels ??
|
|
394
|
-
createDefaultLabelsProcessorFactory(),
|
|
395
|
-
repo: settingsProcessorFactories?.repo ??
|
|
396
|
-
createDefaultRepoSettingsProcessorFactory(),
|
|
397
|
-
codeScanning: settingsProcessorFactories?.codeScanning ??
|
|
398
|
-
createDefaultCodeScanningProcessorFactory(),
|
|
399
|
-
};
|
|
57
|
+
const factories = createDefaultFactories(executor, settingsProcessorFactories);
|
|
400
58
|
const configPath = resolve(options.config);
|
|
401
59
|
if (!existsSync(configPath)) {
|
|
402
60
|
throw new ValidationError(`Config path not found: ${configPath}`);
|
|
403
61
|
}
|
|
404
|
-
|
|
62
|
+
logger.log(`Loading config from: ${configPath}`);
|
|
405
63
|
if (options.dryRun) {
|
|
406
|
-
|
|
64
|
+
logger.log("Running in DRY RUN mode - no changes will be made\n");
|
|
407
65
|
}
|
|
408
66
|
const rawConfig = loadRawConfig(configPath);
|
|
409
67
|
validateForSync(rawConfig);
|
|
@@ -417,10 +75,10 @@ export async function runSync(options, deps = {}) {
|
|
|
417
75
|
else {
|
|
418
76
|
branchName = generateBranchName(fileNames);
|
|
419
77
|
}
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
78
|
+
logger.setTotal(config.repos.length);
|
|
79
|
+
logger.log(`Found ${config.repos.length} repositories to process`);
|
|
80
|
+
logger.log(`Target files: ${formatFileNames(fileNames)}`);
|
|
81
|
+
logger.log(`Branch: ${branchName}\n`);
|
|
424
82
|
const tokenManager = createTokenManager(process.env.XFG_GITHUB_CLIENT_ID && process.env.XFG_GITHUB_APP_PRIVATE_KEY
|
|
425
83
|
? {
|
|
426
84
|
clientId: process.env.XFG_GITHUB_CLIENT_ID,
|
|
@@ -429,7 +87,7 @@ export async function runSync(options, deps = {}) {
|
|
|
429
87
|
: undefined);
|
|
430
88
|
const processor = deps.processorFactory
|
|
431
89
|
? deps.processorFactory()
|
|
432
|
-
: new RepositoryProcessor(undefined,
|
|
90
|
+
: new RepositoryProcessor(undefined, logger, {
|
|
433
91
|
tokenManager,
|
|
434
92
|
envToken: process.env.GH_TOKEN,
|
|
435
93
|
});
|
|
@@ -439,18 +97,19 @@ export async function runSync(options, deps = {}) {
|
|
|
439
97
|
branchName,
|
|
440
98
|
processor,
|
|
441
99
|
lifecycleManager: lifecycleManager ??
|
|
442
|
-
new RepoLifecycleManager(undefined,
|
|
100
|
+
new RepoLifecycleManager(undefined, executor, options.retries, process.cwd(), logger),
|
|
443
101
|
tokenManager,
|
|
444
102
|
reportResults: [],
|
|
445
103
|
lifecycleReportInputs: [],
|
|
446
104
|
settingsCollector: new ResultsCollector(),
|
|
447
105
|
factories,
|
|
106
|
+
logger,
|
|
107
|
+
executor,
|
|
448
108
|
};
|
|
449
109
|
for (let i = 0; i < config.repos.length; i++) {
|
|
450
|
-
await
|
|
110
|
+
await runSingleRepo(config.repos[i], i, ctx);
|
|
451
111
|
}
|
|
452
|
-
displayReports(ctx.reportResults, ctx.lifecycleReportInputs, ctx.settingsCollector, options.dryRun ?? false);
|
|
453
|
-
// Propagate failures to caller (CLI entry handles process.exit)
|
|
112
|
+
displayReports(logger, ctx.reportResults, ctx.lifecycleReportInputs, ctx.settingsCollector, options.dryRun ?? false);
|
|
454
113
|
const settingsResults = ctx.settingsCollector.getAll();
|
|
455
114
|
const hasErrors = ctx.reportResults.some((r) => r.error);
|
|
456
115
|
const hasSettingsErrors = settingsResults.some((r) => r.error);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { MergeMode } from "../config/index.js";
|
|
2
|
-
import type { SyncReport, ReportFileChange } from "../output/
|
|
2
|
+
import type { SyncReport, ReportFileChange } from "../output/index.js";
|
|
3
3
|
interface SyncResultInput {
|
|
4
4
|
repoName: string;
|
|
5
5
|
success: boolean;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { RepoConfig, MergeMode } from "../config/index.js";
|
|
2
|
+
import type { ProcessorResult } from "../sync/index.js";
|
|
3
|
+
export declare function getUniqueFileNames(config: {
|
|
4
|
+
repos: RepoConfig[];
|
|
5
|
+
}): string[];
|
|
6
|
+
export declare function generateBranchName(fileNames: string[]): string;
|
|
7
|
+
export declare function formatFileNames(fileNames: string[]): string;
|
|
8
|
+
export declare function determineMergeOutcome(result: ProcessorResult): MergeMode | undefined;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { sanitizeBranchName } from "./branch-utils.js";
|
|
2
|
+
export function getUniqueFileNames(config) {
|
|
3
|
+
const fileNames = new Set();
|
|
4
|
+
for (const repo of config.repos) {
|
|
5
|
+
for (const file of repo.files) {
|
|
6
|
+
fileNames.add(file.fileName);
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
return Array.from(fileNames);
|
|
10
|
+
}
|
|
11
|
+
export function generateBranchName(fileNames) {
|
|
12
|
+
if (fileNames.length === 1) {
|
|
13
|
+
return `chore/sync-${sanitizeBranchName(fileNames[0])}`;
|
|
14
|
+
}
|
|
15
|
+
return "chore/sync-config";
|
|
16
|
+
}
|
|
17
|
+
export function formatFileNames(fileNames) {
|
|
18
|
+
if (fileNames.length === 1) {
|
|
19
|
+
return fileNames[0];
|
|
20
|
+
}
|
|
21
|
+
if (fileNames.length <= 3) {
|
|
22
|
+
return fileNames.join(", ");
|
|
23
|
+
}
|
|
24
|
+
return `${fileNames.length} files`;
|
|
25
|
+
}
|
|
26
|
+
export function determineMergeOutcome(result) {
|
|
27
|
+
if (!result.success)
|
|
28
|
+
return undefined;
|
|
29
|
+
if (!result.prUrl)
|
|
30
|
+
return "direct";
|
|
31
|
+
if (result.mergeResult?.merged)
|
|
32
|
+
return "force";
|
|
33
|
+
if (result.mergeResult?.autoMergeEnabled)
|
|
34
|
+
return "auto";
|
|
35
|
+
return "manual";
|
|
36
|
+
}
|
package/dist/cli/types.d.ts
CHANGED
|
@@ -1,21 +1,24 @@
|
|
|
1
1
|
import type { MergeMode, MergeStrategy, RepoConfig } from "../config/index.js";
|
|
2
2
|
import type { IRepoLifecycleManager } from "../lifecycle/index.js";
|
|
3
|
-
import type { IRepositoryProcessor } from "../sync/index.js";
|
|
4
|
-
import type { ISettingsProcessor, IRulesetProcessor, IRepoSettingsProcessor, ILabelsProcessor, ICodeScanningProcessor,
|
|
3
|
+
import type { IRepositoryProcessor, FileChangeDetail } from "../sync/index.js";
|
|
4
|
+
import type { ISettingsProcessor, IRulesetProcessor, IRepoSettingsProcessor, ILabelsProcessor, ICodeScanningProcessor, IVariablesProcessor, BaseProcessorResult } from "../settings/index.js";
|
|
5
5
|
import type { RepoInfo } from "../repo/index.js";
|
|
6
6
|
import type { ResultsCollector } from "./results-collector.js";
|
|
7
|
+
import type { Logger } from "../shared/logger.js";
|
|
7
8
|
export type ProcessorFactory = () => IRepositoryProcessor;
|
|
8
9
|
export type SettingsProcessorFactory<T extends ISettingsProcessor> = () => T;
|
|
9
10
|
export type RulesetProcessorFactory = SettingsProcessorFactory<IRulesetProcessor>;
|
|
10
11
|
export type RepoSettingsProcessorFactory = SettingsProcessorFactory<IRepoSettingsProcessor>;
|
|
11
12
|
export type LabelsProcessorFactory = SettingsProcessorFactory<ILabelsProcessor>;
|
|
12
13
|
export type CodeScanningProcessorFactory = SettingsProcessorFactory<ICodeScanningProcessor>;
|
|
13
|
-
export type
|
|
14
|
+
export type VariablesProcessorFactory = SettingsProcessorFactory<IVariablesProcessor>;
|
|
15
|
+
export type SettingsKind = "rulesets" | "labels" | "repo" | "codeScanning" | "variables";
|
|
14
16
|
export interface SettingsProcessorFactories {
|
|
15
17
|
rulesets: RulesetProcessorFactory;
|
|
16
18
|
labels: LabelsProcessorFactory;
|
|
17
19
|
repo: RepoSettingsProcessorFactory;
|
|
18
20
|
codeScanning: CodeScanningProcessorFactory;
|
|
21
|
+
variables: VariablesProcessorFactory;
|
|
19
22
|
}
|
|
20
23
|
/**
|
|
21
24
|
* Dependencies for the sync command (dependency injection).
|
|
@@ -41,11 +44,7 @@ export interface SyncOptions extends SharedOptions {
|
|
|
41
44
|
export interface SyncResultEntry {
|
|
42
45
|
repoName: string;
|
|
43
46
|
success: boolean;
|
|
44
|
-
fileChanges:
|
|
45
|
-
path: string;
|
|
46
|
-
action: ActiveAction;
|
|
47
|
-
diffLines?: string[];
|
|
48
|
-
}>;
|
|
47
|
+
fileChanges: FileChangeDetail[];
|
|
49
48
|
prUrl?: string;
|
|
50
49
|
mergeOutcome?: MergeMode;
|
|
51
50
|
error?: string;
|
|
@@ -69,4 +68,5 @@ export interface ApplyRepoSettingsContext {
|
|
|
69
68
|
token: string | undefined;
|
|
70
69
|
settingsCollector: ResultsCollector;
|
|
71
70
|
factories: SettingsProcessorFactories;
|
|
71
|
+
logger: Logger;
|
|
72
72
|
}
|