gitops-ai 1.0.0 → 1.2.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.
Files changed (49) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +74 -41
  3. package/dist/commands/bootstrap.js +641 -117
  4. package/dist/commands/bootstrap.js.map +1 -1
  5. package/dist/commands/template-sync-wizard.d.ts +1 -0
  6. package/dist/commands/template-sync-wizard.js +169 -0
  7. package/dist/commands/template-sync-wizard.js.map +1 -0
  8. package/dist/commands/template-sync.d.ts +8 -0
  9. package/dist/commands/template-sync.js +41 -0
  10. package/dist/commands/template-sync.js.map +1 -0
  11. package/dist/core/bootstrap-runner.js +28 -11
  12. package/dist/core/bootstrap-runner.js.map +1 -1
  13. package/dist/core/cloudflare-oauth.d.ts +1 -0
  14. package/dist/core/cloudflare-oauth.js +311 -0
  15. package/dist/core/cloudflare-oauth.js.map +1 -0
  16. package/dist/core/dependencies.js +0 -12
  17. package/dist/core/dependencies.js.map +1 -1
  18. package/dist/core/encryption.js +1 -1
  19. package/dist/core/encryption.js.map +1 -1
  20. package/dist/core/flux.d.ts +1 -1
  21. package/dist/core/flux.js +57 -8
  22. package/dist/core/flux.js.map +1 -1
  23. package/dist/core/git-provider.d.ts +38 -0
  24. package/dist/core/git-provider.js +30 -0
  25. package/dist/core/git-provider.js.map +1 -0
  26. package/dist/core/github-oauth.d.ts +1 -0
  27. package/dist/core/github-oauth.js +110 -0
  28. package/dist/core/github-oauth.js.map +1 -0
  29. package/dist/core/github.d.ts +12 -0
  30. package/dist/core/github.js +188 -0
  31. package/dist/core/github.js.map +1 -0
  32. package/dist/core/gitlab-oauth.d.ts +1 -0
  33. package/dist/core/gitlab-oauth.js +194 -0
  34. package/dist/core/gitlab-oauth.js.map +1 -0
  35. package/dist/core/gitlab.d.ts +4 -9
  36. package/dist/core/gitlab.js +127 -56
  37. package/dist/core/gitlab.js.map +1 -1
  38. package/dist/core/kubernetes.d.ts +9 -0
  39. package/dist/core/kubernetes.js +51 -1
  40. package/dist/core/kubernetes.js.map +1 -1
  41. package/dist/core/template-sync.d.ts +46 -0
  42. package/dist/core/template-sync.js +249 -0
  43. package/dist/core/template-sync.js.map +1 -0
  44. package/dist/index.js +5 -2
  45. package/dist/index.js.map +1 -1
  46. package/dist/schemas.d.ts +17 -4
  47. package/dist/schemas.js +17 -3
  48. package/dist/schemas.js.map +1 -1
  49. package/package.json +32 -2
@@ -1,65 +1,136 @@
1
- import { exec, execAsync, execSafe } from "../utils/shell.js";
1
+ import { exec, execSafe } from "../utils/shell.js";
2
2
  import { log } from "../utils/log.js";
3
- export async function authenticate(pat, host) {
4
- await execAsync(`echo "${pat}" | glab auth login --hostname "${host}" --stdin`);
5
- const username = await execAsync(`glab api "user" --hostname "${host}" | jq -r '.username'`);
6
- log.success(`Authenticated as: ${username}`);
7
- return username;
8
- }
9
- export async function resolveNamespaceId(namespace, host) {
10
- const result = execSafe(`glab api --hostname "${host}" "namespaces/${namespace}" 2>/dev/null | jq -r '.id'`);
11
- if (result.exitCode !== 0 || !result.stdout || result.stdout === "null") {
12
- throw new Error(`Namespace '${namespace}' not found. Check the group or username.`);
3
+ import { loginWithBrowser } from "./gitlab-oauth.js";
4
+ // ---------------------------------------------------------------------------
5
+ // REST helpers
6
+ // ---------------------------------------------------------------------------
7
+ async function apiFetch(path, token, host) {
8
+ const url = `https://${host}/api/v4${path}`;
9
+ let res = await fetch(url, {
10
+ headers: { Authorization: `Bearer ${token}` },
11
+ });
12
+ // Fall back to PRIVATE-TOKEN header (PATs on older GitLab versions)
13
+ if (res.status === 401) {
14
+ res = await fetch(url, {
15
+ headers: { "PRIVATE-TOKEN": token },
16
+ });
13
17
  }
14
- log.success(`Namespace ID: ${result.stdout}`);
15
- return result.stdout;
16
- }
17
- export async function getProject(namespace, name, host) {
18
- const encoded = `${namespace}/${name}`.replace(/\//g, "%2F");
19
- const { stdout, exitCode } = execSafe(`glab api --hostname "${host}" "projects/${encoded}" 2>/dev/null`);
20
- if (exitCode !== 0 || !stdout)
21
- return null;
22
- try {
23
- const data = JSON.parse(stdout);
24
- if (!data.id)
25
- return null;
26
- return {
27
- id: String(data.id),
28
- httpUrl: data.http_url_to_repo,
29
- pathWithNamespace: data.path_with_namespace,
30
- };
18
+ if (!res.ok) {
19
+ throw new Error(`GitLab API ${path}: ${res.status} ${res.statusText}`);
31
20
  }
32
- catch {
33
- return null;
21
+ return res.json();
22
+ }
23
+ async function apiPost(path, token, host, body) {
24
+ const url = `https://${host}/api/v4${path}`;
25
+ const res = await fetch(url, {
26
+ method: "POST",
27
+ headers: {
28
+ Authorization: `Bearer ${token}`,
29
+ "Content-Type": "application/json",
30
+ },
31
+ body: JSON.stringify(body),
32
+ });
33
+ if (!res.ok) {
34
+ const text = await res.text();
35
+ throw new Error(`GitLab API POST ${path}: ${res.status} ${text}`);
34
36
  }
37
+ return res.json();
35
38
  }
36
- export async function createProject(name, namespaceId, host) {
37
- const result = await execAsync([
38
- "glab api --method POST",
39
- `--hostname "${host}"`,
40
- '"projects"',
41
- `-f "name=${name}"`,
42
- `-f "path=${name}"`,
43
- `-f "namespace_id=${namespaceId}"`,
44
- '-f "visibility=private"',
45
- '-f "initialize_with_readme=false"',
46
- ].join(" "));
47
- const data = JSON.parse(result);
39
+ export function createGitLabProvider() {
48
40
  return {
49
- id: String(data.id),
50
- httpUrl: data.http_url_to_repo,
51
- pathWithNamespace: data.path_with_namespace,
41
+ type: "gitlab",
42
+ defaultHost: "gitlab.com",
43
+ cliTool: "glab",
44
+ tokenLabel: "GitLab Personal Access Token (api, read_repository, write_repository)",
45
+ async fetchCurrentUser(token, host) {
46
+ const u = await apiFetch("/user", token, host);
47
+ return { username: u.username, name: u.name };
48
+ },
49
+ async fetchOrganizations(token, host) {
50
+ const groups = await apiFetch("/groups?per_page=100&min_access_level=30&top_level_only=true&order_by=name&sort=asc", token, host);
51
+ return groups.map((g) => ({
52
+ name: g.name,
53
+ path: g.path,
54
+ fullPath: g.full_path,
55
+ }));
56
+ },
57
+ async fetchNamespaceProjects(token, host, namespace) {
58
+ const encoded = encodeURIComponent(namespace);
59
+ let projects;
60
+ try {
61
+ projects = await apiFetch(`/groups/${encoded}/projects?per_page=100&order_by=updated_at&sort=desc&include_subgroups=false`, token, host);
62
+ }
63
+ catch {
64
+ projects = await apiFetch(`/users/${encoded}/projects?per_page=100&order_by=updated_at&sort=desc`, token, host);
65
+ }
66
+ return projects.map((p) => ({
67
+ name: p.name,
68
+ description: p.description,
69
+ pathWithNamespace: p.path_with_namespace,
70
+ httpUrl: p.http_url_to_repo,
71
+ }));
72
+ },
73
+ async authenticate(token, host) {
74
+ const user = await this.fetchCurrentUser(token, host);
75
+ log.success(`Authenticated as: ${user.username}`);
76
+ return user.username;
77
+ },
78
+ async resolveNamespaceId(namespace, host, token) {
79
+ const encoded = encodeURIComponent(namespace);
80
+ try {
81
+ const ns = await apiFetch(`/namespaces/${encoded}`, token, host);
82
+ log.success(`Namespace ID: ${ns.id}`);
83
+ return String(ns.id);
84
+ }
85
+ catch {
86
+ throw new Error(`Namespace '${namespace}' not found. Check the group or username.`);
87
+ }
88
+ },
89
+ async getProject(namespace, name, host, token) {
90
+ const encoded = encodeURIComponent(`${namespace}/${name}`);
91
+ try {
92
+ const p = await apiFetch(`/projects/${encoded}`, token, host);
93
+ return {
94
+ id: String(p.id),
95
+ httpUrl: p.http_url_to_repo,
96
+ pathWithNamespace: p.path_with_namespace,
97
+ };
98
+ }
99
+ catch {
100
+ return null;
101
+ }
102
+ },
103
+ async createProject(name, namespaceId, host, token) {
104
+ const p = await apiPost("/projects", token, host, {
105
+ name,
106
+ path: name,
107
+ namespace_id: Number(namespaceId),
108
+ visibility: "private",
109
+ initialize_with_readme: false,
110
+ });
111
+ return {
112
+ id: String(p.id),
113
+ httpUrl: p.http_url_to_repo,
114
+ pathWithNamespace: p.path_with_namespace,
115
+ };
116
+ },
117
+ configureGitCredentials(token, cwd) {
118
+ const { exitCode, stdout } = execSafe("git remote get-url origin 2>/dev/null");
119
+ let host = "gitlab.com";
120
+ if (exitCode === 0 && stdout) {
121
+ const match = stdout.match(/https:\/\/([^/]+)\//);
122
+ if (match)
123
+ host = match[1];
124
+ }
125
+ exec(`git config --local --replace-all credential.helper '!f() { echo "username=oauth2"; echo "password=${token}"; }; f'`, { cwd });
126
+ log.success(`git credentials configured for ${host}`);
127
+ },
128
+ getAuthRemoteUrl(host, pathWithNamespace, token) {
129
+ return `https://oauth2:${token}@${host}/${pathWithNamespace}.git`;
130
+ },
131
+ async loginWithBrowser(host) {
132
+ return loginWithBrowser(host);
133
+ },
52
134
  };
53
135
  }
54
- export function configureGitCredentials(pat, cwd) {
55
- const { exitCode, stdout } = execSafe("git remote get-url origin 2>/dev/null");
56
- let host = "gitlab.com";
57
- if (exitCode === 0 && stdout) {
58
- const match = stdout.match(/https:\/\/([^/]+)\//);
59
- if (match)
60
- host = match[1];
61
- }
62
- exec(`git config --local --replace-all credential.helper '!f() { echo "username=oauth2"; echo "password=${pat}"; }; f'`, { cwd });
63
- log.success(`git credentials configured for ${host}`);
64
- }
65
136
  //# sourceMappingURL=gitlab.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"gitlab.js","sourceRoot":"","sources":["../../src/core/gitlab.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"gitlab.js","sourceRoot":"","sources":["../../src/core/gitlab.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,12 @@
1
1
  export declare function isClusterReachable(): boolean;
2
+ export interface ExistingCluster {
3
+ type: "k3d" | "k3s";
4
+ names: string[];
5
+ }
6
+ export declare function detectExistingClusters(): ExistingCluster | null;
7
+ export declare function listK3dClusters(): string[];
8
+ export declare function k3dClusterExists(clusterName: string): boolean;
9
+ export declare function k3sInstalled(): boolean;
2
10
  export declare function createK3dCluster(clusterName: string): Promise<void>;
3
11
  export declare function installK3s(): Promise<void>;
4
12
  export declare function setupKubeconfig(clusterName: string): string;
@@ -8,3 +16,4 @@ export declare function createSecret(name: string, namespace: string, data: Reco
8
16
  export declare function secretExists(name: string, namespace: string): boolean;
9
17
  export declare function deleteSecret(name: string, namespace: string): Promise<void>;
10
18
  export declare function createSecretFromFile(name: string, namespace: string, key: string, filePath: string): Promise<void>;
19
+ export declare function createSshSecret(name: string, namespace: string, privateKey: string, publicKey: string, knownHosts: string): Promise<void>;
@@ -1,4 +1,4 @@
1
- import { mkdirSync, writeFileSync } from "node:fs";
1
+ import { mkdirSync, writeFileSync, rmSync } from "node:fs";
2
2
  import { exec, execAsync, execSafe } from "../utils/shell.js";
3
3
  import { isMacOS, isCI } from "../utils/platform.js";
4
4
  import { log, withSpinner } from "../utils/log.js";
@@ -7,6 +7,35 @@ export function isClusterReachable() {
7
7
  const { exitCode } = execSafe("kubectl cluster-info 2>/dev/null");
8
8
  return exitCode === 0;
9
9
  }
10
+ export function detectExistingClusters() {
11
+ if (isMacOS() || isCI()) {
12
+ const names = listK3dClusters();
13
+ if (names.length > 0)
14
+ return { type: "k3d", names };
15
+ return null;
16
+ }
17
+ if (k3sInstalled()) {
18
+ return { type: "k3s", names: ["k3s"] };
19
+ }
20
+ return null;
21
+ }
22
+ export function listK3dClusters() {
23
+ const { stdout, exitCode } = execSafe("k3d cluster list --no-headers 2>/dev/null");
24
+ if (exitCode !== 0 || !stdout.trim())
25
+ return [];
26
+ return stdout
27
+ .trim()
28
+ .split("\n")
29
+ .map((line) => line.split(/\s+/)[0])
30
+ .filter(Boolean);
31
+ }
32
+ export function k3dClusterExists(clusterName) {
33
+ return listK3dClusters().includes(clusterName);
34
+ }
35
+ export function k3sInstalled() {
36
+ const { exitCode } = execSafe("command -v k3s");
37
+ return exitCode === 0;
38
+ }
10
39
  export async function createK3dCluster(clusterName) {
11
40
  const { stdout } = execSafe("k3d cluster list 2>/dev/null");
12
41
  if (stdout.includes(clusterName)) {
@@ -78,4 +107,25 @@ export async function createSecretFromFile(name, namespace, key, filePath) {
78
107
  log.detail(`kubectl create secret generic ${name} --namespace=${namespace} --from-file=${key}`);
79
108
  await execAsync(cmd);
80
109
  }
110
+ export async function createSshSecret(name, namespace, privateKey, publicKey, knownHosts) {
111
+ const tmpDir = "/tmp/flux-ssh-secret";
112
+ mkdirSync(tmpDir, { recursive: true });
113
+ try {
114
+ writeFileSync(`${tmpDir}/identity`, privateKey, { mode: 0o600 });
115
+ writeFileSync(`${tmpDir}/identity.pub`, publicKey);
116
+ writeFileSync(`${tmpDir}/known_hosts`, knownHosts);
117
+ const cmd = [
118
+ `kubectl create secret generic ${name}`,
119
+ `--namespace=${namespace}`,
120
+ `--from-file=identity="${tmpDir}/identity"`,
121
+ `--from-file=identity.pub="${tmpDir}/identity.pub"`,
122
+ `--from-file=known_hosts="${tmpDir}/known_hosts"`,
123
+ ].join(" ");
124
+ log.detail(`kubectl create secret generic ${name} --namespace=${namespace} (SSH)`);
125
+ await execAsync(cmd);
126
+ }
127
+ finally {
128
+ rmSync(tmpDir, { recursive: true, force: true });
129
+ }
130
+ }
81
131
  //# sourceMappingURL=kubernetes.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"kubernetes.js","sourceRoot":"","sources":["../../src/core/kubernetes.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"kubernetes.js","sourceRoot":"","sources":["../../src/core/kubernetes.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ /** HTTPS URL for the canonical GitOps template (GitLab). */
2
+ export declare const UPSTREAM_GIT_URL = "https://gitlab.com/everythings-gonna-be-alright/fluxcd_ai_template.git";
3
+ export declare function readPackageVersion(): string;
4
+ /**
5
+ * Read `version:` from repo-root template-sync-metadata.yaml if present (template semver).
6
+ */
7
+ export declare function readMetadataVersion(repoRoot: string): string | undefined;
8
+ export declare function looksLikeGitopsTemplateLayout(repoRoot: string): boolean;
9
+ export declare function fetchTemplateTags(): Promise<string[]>;
10
+ export declare function assertGitRepo(repoRoot: string): void;
11
+ export declare function currentBranch(repoRoot: string): string;
12
+ export declare function ensureUpstreamRemote(repoRoot: string, remoteName: string): Promise<void>;
13
+ export declare function fetchUpstream(repoRoot: string, remoteName: string, ref: string): Promise<void>;
14
+ export type RiskTier = "routine" | "high_touch" | "cluster_overlay" | "other";
15
+ export interface DiffFileEntry {
16
+ path: string;
17
+ risk: RiskTier;
18
+ }
19
+ export interface UpstreamDiffResult {
20
+ raw: string;
21
+ files: DiffFileEntry[];
22
+ totalFiles: number;
23
+ routineCount: number;
24
+ highTouchCount: number;
25
+ clusterOverlayCount: number;
26
+ otherCount: number;
27
+ empty: boolean;
28
+ error?: string;
29
+ }
30
+ export declare function classifyFile(path: string): RiskTier;
31
+ export declare function diffUpstream(repoRoot: string): UpstreamDiffResult;
32
+ export declare function hasCommonAncestor(repoRoot: string): boolean;
33
+ export interface MergeResult {
34
+ success: boolean;
35
+ conflictCount: number;
36
+ error?: string;
37
+ }
38
+ export declare function mergeUpstream(repoRoot: string, ref: string, remoteName: string, allowUnrelatedHistories?: boolean): Promise<MergeResult>;
39
+ export interface TemplateSyncOptions {
40
+ repoRoot: string;
41
+ ref: string;
42
+ dryRun: boolean;
43
+ remoteName: string;
44
+ allowUnrelatedHistories?: boolean;
45
+ }
46
+ export declare function mergeUpstreamTemplate(options: TemplateSyncOptions): Promise<void>;
@@ -0,0 +1,249 @@
1
+ import { existsSync, readFileSync, readdirSync } from "node:fs";
2
+ import { dirname, join } from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ import { log, withSpinner } from "../utils/log.js";
5
+ import { execAsync, execSafe } from "../utils/shell.js";
6
+ import { SOURCE_GITLAB_HOST, SOURCE_PROJECT_PATH, } from "../schemas.js";
7
+ const __dirname = dirname(fileURLToPath(import.meta.url));
8
+ /** HTTPS URL for the canonical GitOps template (GitLab). */
9
+ export const UPSTREAM_GIT_URL = `https://${SOURCE_GITLAB_HOST}/${SOURCE_PROJECT_PATH}.git`;
10
+ export function readPackageVersion() {
11
+ try {
12
+ const pkgPath = join(__dirname, "..", "..", "package.json");
13
+ const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
14
+ return pkg.version ?? "unknown";
15
+ }
16
+ catch {
17
+ return "unknown";
18
+ }
19
+ }
20
+ /**
21
+ * Read `version:` from repo-root template-sync-metadata.yaml if present (template semver).
22
+ */
23
+ export function readMetadataVersion(repoRoot) {
24
+ const metaPath = join(repoRoot, "template-sync-metadata.yaml");
25
+ if (!existsSync(metaPath))
26
+ return undefined;
27
+ try {
28
+ const text = readFileSync(metaPath, "utf-8");
29
+ const m = /^version:\s*["']?([^'"\n]+)/m.exec(text);
30
+ return m?.[1]?.trim();
31
+ }
32
+ catch {
33
+ return undefined;
34
+ }
35
+ }
36
+ /**
37
+ * Shared Helm / component bases live under `templates/` (category dirs such as
38
+ * `templates/system/`, `templates/ai/`, …).
39
+ */
40
+ function hasSharedTemplatesTree(repoRoot) {
41
+ const templatesRoot = join(repoRoot, "templates");
42
+ if (!existsSync(templatesRoot))
43
+ return false;
44
+ try {
45
+ const entries = readdirSync(templatesRoot, { withFileTypes: true });
46
+ return entries.some((e) => e.isDirectory());
47
+ }
48
+ catch {
49
+ return false;
50
+ }
51
+ }
52
+ export function looksLikeGitopsTemplateLayout(repoRoot) {
53
+ return (hasSharedTemplatesTree(repoRoot) &&
54
+ existsSync(join(repoRoot, "clusters", "_template")));
55
+ }
56
+ function unrelatedHistoryHint(repoRoot) {
57
+ if (!looksLikeGitopsTemplateLayout(repoRoot)) {
58
+ return ("This directory does not look like a fork of the GitOps template (missing `templates/` shared bases or `clusters/_template/`). " +
59
+ "Use the repository created by `gitops-ai bootstrap`, or pass `--cwd` to that repo's root.");
60
+ }
61
+ return ("Run `template sync` from the GitOps repository you created with `gitops-ai bootstrap` (or use `--cwd /path/to/that/repo`). " +
62
+ "If you truly need to combine unrelated histories, run again with `--allow-unrelated-histories` (expect many conflicts).");
63
+ }
64
+ // ---------------------------------------------------------------------------
65
+ // Fetch upstream tags (shared between bootstrap wizard and sync TUI)
66
+ // ---------------------------------------------------------------------------
67
+ export async function fetchTemplateTags() {
68
+ const encoded = encodeURIComponent(SOURCE_PROJECT_PATH);
69
+ const url = `https://${SOURCE_GITLAB_HOST}/api/v4/projects/${encoded}/repository/tags?per_page=50&order_by=version&sort=desc`;
70
+ try {
71
+ const res = await fetch(url);
72
+ if (!res.ok)
73
+ return [];
74
+ const tags = (await res.json());
75
+ return tags.map((t) => t.name);
76
+ }
77
+ catch {
78
+ return [];
79
+ }
80
+ }
81
+ // ---------------------------------------------------------------------------
82
+ // Composable sync primitives (used by both non-interactive and TUI paths)
83
+ // ---------------------------------------------------------------------------
84
+ export function assertGitRepo(repoRoot) {
85
+ const { exitCode } = execSafe("git rev-parse --is-inside-work-tree", {
86
+ cwd: repoRoot,
87
+ });
88
+ if (exitCode !== 0) {
89
+ throw new Error(`Not a git repository: ${repoRoot}`);
90
+ }
91
+ }
92
+ export function currentBranch(repoRoot) {
93
+ const { stdout } = execSafe("git branch --show-current", { cwd: repoRoot });
94
+ return stdout || "(detached HEAD)";
95
+ }
96
+ export async function ensureUpstreamRemote(repoRoot, remoteName) {
97
+ const { stdout: remotes } = execSafe("git remote", { cwd: repoRoot });
98
+ const remoteList = remotes.split(/\s+/).filter(Boolean);
99
+ if (!remoteList.includes(remoteName)) {
100
+ log.step(`Adding remote '${remoteName}' → ${UPSTREAM_GIT_URL}`);
101
+ await execAsync(`git remote add "${remoteName}" "${UPSTREAM_GIT_URL}"`, {
102
+ cwd: repoRoot,
103
+ });
104
+ }
105
+ }
106
+ export async function fetchUpstream(repoRoot, remoteName, ref) {
107
+ await withSpinner(`Fetching ${remoteName} ${ref}`, async () => {
108
+ await execAsync(`git fetch "${remoteName}" "${ref}"`, { cwd: repoRoot });
109
+ });
110
+ }
111
+ const HIGH_TOUCH_PATTERNS = [
112
+ /^flux-instance-values\.yaml$/,
113
+ /^\.sops\.yaml$/,
114
+ /secret-.*\.yaml$/,
115
+ /cluster-sync\.yaml$/,
116
+ ];
117
+ export function classifyFile(path) {
118
+ if (HIGH_TOUCH_PATTERNS.some((re) => re.test(path)))
119
+ return "high_touch";
120
+ if (path.startsWith("clusters/"))
121
+ return "cluster_overlay";
122
+ if (path.startsWith("templates/"))
123
+ return "routine";
124
+ return "other";
125
+ }
126
+ export function diffUpstream(repoRoot) {
127
+ // Three-dot shows only what changed on upstream since the common ancestor,
128
+ // excluding local-only files (e.g. clusters/homelab/).
129
+ // Falls back to two-dot when there is no merge-base (unrelated histories).
130
+ let diffCmd = "git diff --stat HEAD...FETCH_HEAD";
131
+ let nameCmd = "git diff --name-only HEAD...FETCH_HEAD";
132
+ const { exitCode: hasMergeBase } = execSafe("git merge-base HEAD FETCH_HEAD", { cwd: repoRoot });
133
+ if (hasMergeBase !== 0) {
134
+ diffCmd = "git diff --stat HEAD FETCH_HEAD";
135
+ nameCmd = "git diff --name-only HEAD FETCH_HEAD";
136
+ }
137
+ const result = execSafe(diffCmd, { cwd: repoRoot });
138
+ if (result.exitCode !== 0) {
139
+ return {
140
+ raw: "",
141
+ files: [],
142
+ totalFiles: 0,
143
+ routineCount: 0,
144
+ highTouchCount: 0,
145
+ clusterOverlayCount: 0,
146
+ otherCount: 0,
147
+ empty: true,
148
+ error: result.stderr || "git diff failed",
149
+ };
150
+ }
151
+ const raw = result.stdout.trim();
152
+ if (!raw) {
153
+ return {
154
+ raw: "",
155
+ files: [],
156
+ totalFiles: 0,
157
+ routineCount: 0,
158
+ highTouchCount: 0,
159
+ clusterOverlayCount: 0,
160
+ otherCount: 0,
161
+ empty: true,
162
+ };
163
+ }
164
+ const nameResult = execSafe(nameCmd, { cwd: repoRoot });
165
+ const filePaths = nameResult.stdout.trim().split("\n").filter(Boolean);
166
+ const files = filePaths.map((p) => ({
167
+ path: p,
168
+ risk: classifyFile(p),
169
+ }));
170
+ return {
171
+ raw,
172
+ files,
173
+ totalFiles: files.length,
174
+ routineCount: files.filter((f) => f.risk === "routine").length,
175
+ highTouchCount: files.filter((f) => f.risk === "high_touch").length,
176
+ clusterOverlayCount: files.filter((f) => f.risk === "cluster_overlay").length,
177
+ otherCount: files.filter((f) => f.risk === "other").length,
178
+ empty: false,
179
+ };
180
+ }
181
+ // ---------------------------------------------------------------------------
182
+ // Merge
183
+ // ---------------------------------------------------------------------------
184
+ export function hasCommonAncestor(repoRoot) {
185
+ const { exitCode } = execSafe("git merge-base HEAD FETCH_HEAD", {
186
+ cwd: repoRoot,
187
+ });
188
+ return exitCode === 0;
189
+ }
190
+ export async function mergeUpstream(repoRoot, ref, remoteName, allowUnrelatedHistories = false) {
191
+ const unrelatedFlag = allowUnrelatedHistories
192
+ ? " --allow-unrelated-histories"
193
+ : "";
194
+ try {
195
+ await withSpinner(`Merging ${remoteName}/${ref}`, async () => {
196
+ await execAsync(`git merge${unrelatedFlag} FETCH_HEAD -m "chore: sync template from upstream ${ref}"`, { cwd: repoRoot });
197
+ });
198
+ return { success: true, conflictCount: 0 };
199
+ }
200
+ catch (err) {
201
+ const conflictResult = execSafe("git diff --name-only --diff-filter=U", { cwd: repoRoot });
202
+ const conflictFiles = conflictResult.stdout.trim().split("\n").filter(Boolean);
203
+ if (conflictFiles.length > 0) {
204
+ return {
205
+ success: false,
206
+ conflictCount: conflictFiles.length,
207
+ error: `Merge produced ${conflictFiles.length} conflict(s). Resolve them, then commit and push.`,
208
+ };
209
+ }
210
+ return {
211
+ success: false,
212
+ conflictCount: 0,
213
+ error: err.message,
214
+ };
215
+ }
216
+ }
217
+ export async function mergeUpstreamTemplate(options) {
218
+ const { repoRoot, ref, dryRun, remoteName, allowUnrelatedHistories } = options;
219
+ assertGitRepo(repoRoot);
220
+ await ensureUpstreamRemote(repoRoot, remoteName);
221
+ await fetchUpstream(repoRoot, remoteName, ref);
222
+ const diff = diffUpstream(repoRoot);
223
+ if (diff.error) {
224
+ log.detail(`(could not diff HEAD vs FETCH_HEAD: ${diff.error})`);
225
+ }
226
+ else if (!diff.empty) {
227
+ log.detail(diff.raw);
228
+ }
229
+ else {
230
+ log.detail("(no file differences between HEAD and FETCH_HEAD)");
231
+ }
232
+ if (dryRun) {
233
+ log.success("Dry-run: fetch complete; no merge performed. Review diff above, then run without --dry-run.");
234
+ return;
235
+ }
236
+ if (!hasCommonAncestor(repoRoot) && !allowUnrelatedHistories) {
237
+ throw new Error("No common Git ancestor with the upstream template on GitLab. " +
238
+ unrelatedHistoryHint(repoRoot) +
239
+ " `--ref` is the branch/tag on upstream; `--remote` is only the local remote name (default: upstream).");
240
+ }
241
+ const result = await mergeUpstream(repoRoot, ref, remoteName, allowUnrelatedHistories);
242
+ if (result.success) {
243
+ log.success("Merge complete. Resolve conflicts if any, run validation (flux build / kubeconform), then push.");
244
+ }
245
+ else {
246
+ throw new Error(result.error ?? "Merge failed");
247
+ }
248
+ }
249
+ //# sourceMappingURL=template-sync.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"template-sync.js","sourceRoot":"","sources":["../../src/core/template-sync.ts"],"names":[],"mappings":"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"}