kubiy-paas-cli 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.js +1 -1
- package/package.json +1 -1
- package/src/commands/deploy.js +80 -41
- package/src/ssh-config.js +5 -11
package/index.js
CHANGED
package/package.json
CHANGED
package/src/commands/deploy.js
CHANGED
|
@@ -1,27 +1,27 @@
|
|
|
1
1
|
// src/commands/deploy.js
|
|
2
2
|
const { execSync } = require("child_process");
|
|
3
3
|
const fs = require("fs");
|
|
4
|
+
const path = require("path");
|
|
4
5
|
const { logInfo, logSuccess, logError } = require("../logger");
|
|
6
|
+
const { SSH_PRIV } = require("../ssh"); // ya lo usas en git:connect
|
|
5
7
|
|
|
6
|
-
function runGit(command,
|
|
8
|
+
function runGit(command, extraOptions = {}) {
|
|
7
9
|
const full = `git ${command}`;
|
|
8
10
|
try {
|
|
9
|
-
|
|
10
|
-
stdio: ["pipe", "pipe", "
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
const out = execSync(full, {
|
|
12
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
13
|
+
encoding: "utf8",
|
|
14
|
+
...extraOptions,
|
|
15
|
+
});
|
|
16
|
+
return out.trim();
|
|
13
17
|
} catch (err) {
|
|
14
|
-
|
|
18
|
+
const stderr = err.stderr ? String(err.stderr) : "";
|
|
19
|
+
throw new Error(`Error al ejecutar: ${full}\n${stderr || err.message}`);
|
|
15
20
|
}
|
|
16
21
|
}
|
|
17
22
|
|
|
18
23
|
function isGitRepo() {
|
|
19
|
-
|
|
20
|
-
runGit("rev-parse --is-inside-work-tree");
|
|
21
|
-
return true;
|
|
22
|
-
} catch (_) {
|
|
23
|
-
return false;
|
|
24
|
-
}
|
|
24
|
+
return fs.existsSync(path.join(process.cwd(), ".git"));
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
function ensureGitRepo() {
|
|
@@ -31,20 +31,16 @@ function ensureGitRepo() {
|
|
|
31
31
|
|
|
32
32
|
logInfo("Este directorio no es un repositorio git. Inicializando...");
|
|
33
33
|
runGit("init");
|
|
34
|
-
|
|
35
|
-
// Intentar crear master como rama inicial
|
|
36
|
-
try {
|
|
37
|
-
runGit("checkout -b master");
|
|
38
|
-
} catch (_) {
|
|
39
|
-
// Si falla, probablemente ya haya HEAD en detached; no pasa nada por ahora.
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
logSuccess("Repositorio git inicializado y rama master creada (si fue posible).");
|
|
34
|
+
logSuccess("Repositorio git inicializado.");
|
|
43
35
|
}
|
|
44
36
|
|
|
37
|
+
/**
|
|
38
|
+
* Intenta obtener la rama actual.
|
|
39
|
+
* Si no hay commits / HEAD está raro, devuelve null.
|
|
40
|
+
*/
|
|
45
41
|
function getCurrentBranch() {
|
|
46
42
|
try {
|
|
47
|
-
return runGit("
|
|
43
|
+
return runGit("symbolic-ref --short HEAD");
|
|
48
44
|
} catch (_) {
|
|
49
45
|
return null;
|
|
50
46
|
}
|
|
@@ -60,18 +56,29 @@ function branchExists(branchName) {
|
|
|
60
56
|
}
|
|
61
57
|
|
|
62
58
|
/**
|
|
63
|
-
*
|
|
59
|
+
* Asegura que la rama activa sea master.
|
|
64
60
|
*
|
|
65
61
|
* Casos:
|
|
66
62
|
* - Si ya estamos en master → OK.
|
|
67
|
-
* - Si
|
|
68
|
-
* - Si
|
|
63
|
+
* - Si no hay rama actual (repo recién creado) → crea master.
|
|
64
|
+
* - Si hay otra rama → si existe master hacemos checkout, si no renombramos a master.
|
|
69
65
|
*/
|
|
70
66
|
function ensureOnMaster() {
|
|
71
|
-
|
|
67
|
+
let current = getCurrentBranch();
|
|
72
68
|
|
|
73
|
-
if (!current) {
|
|
74
|
-
|
|
69
|
+
if (!current || current === "HEAD") {
|
|
70
|
+
logInfo("No hay rama actual válida. Creando / cambiando a 'master'...");
|
|
71
|
+
|
|
72
|
+
if (branchExists("master")) {
|
|
73
|
+
runGit("checkout master");
|
|
74
|
+
logSuccess("Ahora estás en master.");
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Repo recién creado sin ramas reales → creamos master
|
|
79
|
+
runGit("checkout -b master");
|
|
80
|
+
logSuccess("Rama master creada y activada.");
|
|
81
|
+
return;
|
|
75
82
|
}
|
|
76
83
|
|
|
77
84
|
if (current === "master") {
|
|
@@ -83,11 +90,11 @@ function ensureOnMaster() {
|
|
|
83
90
|
|
|
84
91
|
if (branchExists("master")) {
|
|
85
92
|
logInfo("Encontrada rama master. Cambiando a master...");
|
|
86
|
-
runGit("checkout master"
|
|
93
|
+
runGit("checkout master");
|
|
87
94
|
logSuccess("Ahora estás en master.");
|
|
88
95
|
} else {
|
|
89
96
|
logInfo(`No existe rama master. Renombrando rama actual '${current}' a 'master'...`);
|
|
90
|
-
runGit(
|
|
97
|
+
runGit("branch -m master");
|
|
91
98
|
logSuccess("Rama actual renombrada a master.");
|
|
92
99
|
}
|
|
93
100
|
}
|
|
@@ -99,7 +106,7 @@ function ensureKubiyRemote() {
|
|
|
99
106
|
} catch (_) {
|
|
100
107
|
throw new Error(
|
|
101
108
|
"No se encontró el remote 'kubiy'.\n" +
|
|
102
|
-
"Asegúrate de haber ejecutado antes
|
|
109
|
+
"Asegúrate de haber ejecutado antes:\n kubiy git:connect <serviceId>"
|
|
103
110
|
);
|
|
104
111
|
}
|
|
105
112
|
}
|
|
@@ -113,12 +120,11 @@ function createAutoCommit() {
|
|
|
113
120
|
const msg = `kubiy deploy - ${new Date().toISOString()}`;
|
|
114
121
|
logInfo("Creando commit automático...");
|
|
115
122
|
|
|
116
|
-
runGit("add ."
|
|
123
|
+
runGit("add .");
|
|
117
124
|
try {
|
|
118
|
-
runGit(`commit -m "${msg}"
|
|
125
|
+
runGit(`commit -m "${msg}"`);
|
|
119
126
|
logSuccess(`Commit creado: ${msg}`);
|
|
120
127
|
} catch (err) {
|
|
121
|
-
// Si no hay nada que commitear, git commit truena. Lo detectamos.
|
|
122
128
|
if (String(err.message).includes("nothing to commit")) {
|
|
123
129
|
logInfo("No hay cambios nuevos para commitear.");
|
|
124
130
|
} else {
|
|
@@ -129,35 +135,68 @@ function createAutoCommit() {
|
|
|
129
135
|
|
|
130
136
|
function pushToKubiy() {
|
|
131
137
|
logInfo("Haciendo push a 'kubiy' (rama master)...");
|
|
132
|
-
|
|
138
|
+
|
|
139
|
+
// Ruta normalizada para que ssh no se maree con backslashes
|
|
140
|
+
const identityPath = SSH_PRIV.replace(/\\/g, "/");
|
|
141
|
+
|
|
142
|
+
const env = {
|
|
143
|
+
...process.env,
|
|
144
|
+
// Forzar que git use ESTE ssh con ESTA llave y SIN validar host key
|
|
145
|
+
GIT_SSH_COMMAND: `ssh -i "${identityPath}" -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null`,
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
runGit("push kubiy master", { env });
|
|
133
149
|
logSuccess("Push a kubiy master completado.");
|
|
134
150
|
}
|
|
135
151
|
|
|
136
152
|
async function run() {
|
|
137
153
|
try {
|
|
138
|
-
// 1)
|
|
154
|
+
// 1) Repo git
|
|
139
155
|
ensureGitRepo();
|
|
140
156
|
|
|
141
|
-
// 2)
|
|
157
|
+
// 2) Estar en master sí o sí
|
|
142
158
|
ensureOnMaster();
|
|
143
159
|
|
|
144
|
-
// 3)
|
|
160
|
+
// 3) Remote kubiy configurado
|
|
145
161
|
ensureKubiyRemote();
|
|
146
162
|
|
|
147
|
-
// 4)
|
|
163
|
+
// 4) Commit automático si hay cambios
|
|
148
164
|
if (hasChangesToCommit()) {
|
|
149
165
|
createAutoCommit();
|
|
150
166
|
} else {
|
|
151
167
|
logInfo("No hay cambios locales. Solo se intentará hacer push.");
|
|
152
168
|
}
|
|
153
169
|
|
|
154
|
-
// 5) Push
|
|
170
|
+
// 5) Push
|
|
155
171
|
pushToKubiy();
|
|
156
172
|
|
|
157
173
|
logSuccess("🚀 Deploy completado. Revisa tu servicio Kubiy.");
|
|
158
174
|
} catch (err) {
|
|
175
|
+
const msg = String(err.message || "").toLowerCase();
|
|
159
176
|
logError("Error en kubiy deploy:");
|
|
160
|
-
|
|
177
|
+
|
|
178
|
+
// Caso clásico: el remoto tiene commits que el local no
|
|
179
|
+
if (
|
|
180
|
+
msg.includes("fetch first") ||
|
|
181
|
+
msg.includes("non-fast-forward") ||
|
|
182
|
+
msg.includes("failed to push some refs")
|
|
183
|
+
) {
|
|
184
|
+
logError("Tu rama local 'master' está detrás del remoto 'kubiy/master'.");
|
|
185
|
+
logError("Esto pasa cuando el servidor ya tiene commits que tu repo local no tiene.");
|
|
186
|
+
console.log("");
|
|
187
|
+
console.log("Para alinearlo, ejecuta UNA sola vez:");
|
|
188
|
+
console.log("");
|
|
189
|
+
console.log(" git fetch kubiy");
|
|
190
|
+
console.log(" git reset --hard kubiy/master");
|
|
191
|
+
console.log("");
|
|
192
|
+
console.log("Después de eso, vuelve a correr:");
|
|
193
|
+
console.log("");
|
|
194
|
+
console.log(" kubiy deploy");
|
|
195
|
+
} else {
|
|
196
|
+
// Otros errores, mostramos el mensaje crudo
|
|
197
|
+
logError(err.message);
|
|
198
|
+
}
|
|
199
|
+
|
|
161
200
|
process.exit(1);
|
|
162
201
|
}
|
|
163
202
|
}
|
package/src/ssh-config.js
CHANGED
|
@@ -7,14 +7,6 @@ const { logInfo, logSuccess } = require("./logger");
|
|
|
7
7
|
const SSH_DIR = path.join(os.homedir(), ".ssh");
|
|
8
8
|
const SSH_CONFIG = path.join(SSH_DIR, "config");
|
|
9
9
|
|
|
10
|
-
/**
|
|
11
|
-
* Asegura que exista una entrada Host en ~/.ssh/config
|
|
12
|
-
* para usar la llave de Kubiy con ese host.
|
|
13
|
-
*
|
|
14
|
-
* hostAlias: nombre lógico (p. ej. "kubiy-srv-<serviceId>")
|
|
15
|
-
* hostName: IP pública o hostname real de la EC2
|
|
16
|
-
* identityFile: ruta absoluta al id_ed25519 de Kubiy
|
|
17
|
-
*/
|
|
18
10
|
function ensureSshHostConfig(hostAlias, hostName, identityFile) {
|
|
19
11
|
if (!fs.existsSync(SSH_DIR)) {
|
|
20
12
|
fs.mkdirSync(SSH_DIR, { recursive: true });
|
|
@@ -23,7 +15,6 @@ function ensureSshHostConfig(hostAlias, hostName, identityFile) {
|
|
|
23
15
|
let existing = "";
|
|
24
16
|
if (fs.existsSync(SSH_CONFIG)) {
|
|
25
17
|
existing = fs.readFileSync(SSH_CONFIG, "utf8");
|
|
26
|
-
// Si ya hay un bloque para este Host, no duplicamos
|
|
27
18
|
const already = new RegExp(`^Host\\s+${hostAlias}\\b`, "m").test(existing);
|
|
28
19
|
if (already) {
|
|
29
20
|
logInfo(`SSH config ya tiene entrada para Host '${hostAlias}'`);
|
|
@@ -31,7 +22,6 @@ function ensureSshHostConfig(hostAlias, hostName, identityFile) {
|
|
|
31
22
|
}
|
|
32
23
|
}
|
|
33
24
|
|
|
34
|
-
// Convertir backslashes a slashes para que OpenSSH en Windows no se maree
|
|
35
25
|
const identityPath = identityFile.replace(/\\/g, "/");
|
|
36
26
|
|
|
37
27
|
const block = [
|
|
@@ -41,6 +31,10 @@ function ensureSshHostConfig(hostAlias, hostName, identityFile) {
|
|
|
41
31
|
` User deploy`,
|
|
42
32
|
` IdentityFile ${identityPath}`,
|
|
43
33
|
` IdentitiesOnly yes`,
|
|
34
|
+
// 🎯 Para evitar el prompt interactivo de host key:
|
|
35
|
+
` StrictHostKeyChecking no`,
|
|
36
|
+
// opcional, para no llenar el known_hosts global:
|
|
37
|
+
` UserKnownHostsFile ~/.ssh/kubiy_known_hosts`,
|
|
44
38
|
""
|
|
45
39
|
].join("\n");
|
|
46
40
|
|
|
@@ -53,5 +47,5 @@ function ensureSshHostConfig(hostAlias, hostName, identityFile) {
|
|
|
53
47
|
module.exports = {
|
|
54
48
|
ensureSshHostConfig,
|
|
55
49
|
SSH_DIR,
|
|
56
|
-
SSH_CONFIG
|
|
50
|
+
SSH_CONFIG,
|
|
57
51
|
};
|