kubiy-paas-cli 0.1.10 → 0.1.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,118 @@
1
+ # Kubiy CLI (`kubiy-cli`)
2
+
3
+ **English:** Official CLI for the Kubiy PaaS platform. Install from npm and use the `kubiy` command to manage your apps and services deployed on Kubiy.
4
+
5
+ **Español:** CLI oficial para la plataforma PaaS de Kubiy. Instala el paquete desde npm y usa el comando `kubiy` para interactuar con tus apps y servicios desplegados en Kubiy.
6
+
7
+ ---
8
+
9
+ ### Installation / Instalación
10
+
11
+ ```bash
12
+ npm install -g kubiy-cli
13
+
14
+ # Get help / Ver ayuda
15
+ kubiy
16
+ ```
17
+
18
+ **English:** This installs the global `kubiy` binary on your system.
19
+
20
+ **Español:** Esto instalará el binario global `kubiy` en tu sistema.
21
+
22
+ ---
23
+
24
+ ### Main commands / Comandos principales
25
+
26
+ | Command | English | Español |
27
+ |--------|---------|---------|
28
+ | `kubiy link <appId> [--env=prod\|stg\|dev] [--apikey=...] [--save-secrets]` | Link the current project to a Kubiy app/service and create `.kubiy.json`. | Vincula el proyecto actual con una app/servicio de Kubiy y genera el archivo `.kubiy.json`. |
29
+ | `kubiy deploy --message "<text>" [--static] [--dir=<folder>]` | Deploy your project to Kubiy using `.kubiy.json`. | Realiza un deploy de tu proyecto a Kubiy. Usa la configuración de `.kubiy.json`. |
30
+ | `kubiy service:get <serviceId>` | Show detailed information for a Kubiy service. | Muestra información detallada de un servicio en Kubiy. |
31
+ | `kubiy logs [<serviceId>] [--kind=deploy\|app] [--lines=200]` | Show deploy or app logs for a service. | Muestra logs de deploy o de la app para un servicio. |
32
+ | `kubiy rollback <deployId>` | Roll back to the given deploy using `.kubiy.json`. | Ejecuta un rollback al `deployId` indicado usando los datos de `.kubiy.json`. |
33
+ | `kubiy rollback <appId> <serviceId> <deployId>` | Explicit variant with all IDs passed on the command line. | Variante explícita que recibe todos los identificadores por línea de comandos. |
34
+ | `kubiy config --lang es\|en` | Set or show CLI language (Spanish or English). | Define o muestra el idioma del CLI (español o inglés). |
35
+ | `kubiy version` | Show the current CLI version. | Muestra la versión actual del CLI. |
36
+
37
+ You can also pass the language per run: `kubiy --lang en deploy ...`
38
+ También puedes indicar el idioma por ejecución: `kubiy --lang es deploy ...`
39
+
40
+ ---
41
+
42
+ ### Command `kubiy login`
43
+
44
+ **English:** In this version of the CLI, the command `kubiy login <cliToken>` is **temporarily disabled** and is not used in the current authentication flow. If you run it, the CLI will show a message that it is disabled.
45
+
46
+ **Español:** En esta versión del CLI, el comando `kubiy login <cliToken>` está **deshabilitado temporalmente** y no se utiliza en el flujo actual de autenticación. Si lo ejecutas, el CLI mostrará un mensaje indicando que está deshabilitado.
47
+
48
+ ---
49
+
50
+ ### Security / Seguridad
51
+
52
+ **English:** This CLI acts as a client to the Kubiy API:
53
+
54
+ - No secrets are hardcoded (no API keys or tokens in the source code).
55
+ - Tokens and API keys are always provided from outside (by the user or configuration).
56
+ - All sensitive operations are validated and authorized on the **Kubiy API**, not in the CLI.
57
+ - Requests are always made over HTTPS to `https://cli.kubiy.cloud/v1` (or the configured URL).
58
+
59
+ Recommendations: Do not share your `cliToken` or API keys. Do not commit `.kubiy.json` files from real projects to public repos if they contain sensitive identifiers or keys.
60
+
61
+ **Español:** Este CLI actúa como cliente frente a la API de Kubiy:
62
+
63
+ - No incluye ningún secreto hardcodeado (no hay API keys ni tokens dentro del código fuente).
64
+ - Los tokens y apikeys se proporcionan siempre desde fuera (por el usuario o por configuración).
65
+ - Todas las operaciones delicadas se validan y autorizan en la **API de Kubiy**, no en el CLI.
66
+ - Las llamadas se realizan siempre sobre HTTPS hacia `https://cli.kubiy.cloud/v1` (o la URL configurada).
67
+
68
+ Recomendaciones: No compartas tu `cliToken` ni apikeys. No subas archivos `.kubiy.json` de proyectos reales a repos públicos si contienen identificadores o claves sensibles.
69
+
70
+ ---
71
+
72
+ ### Publishing to npm / Publicación en npm
73
+
74
+ **English:** This package is ready to be published as a public npm package:
75
+
76
+ - Package name: `kubiy-cli`
77
+ - Global command: `kubiy` (defined in the `bin` field)
78
+ - Only the needed files are published (`index.js` and `src/`)
79
+
80
+ To publish a new version:
81
+
82
+ ```bash
83
+ # 1. Make sure you've updated "version" in package.json
84
+
85
+ cd kubiy-npm-cli
86
+ npm login # once, if you haven't already
87
+ npm publish # publishes kubiy-cli as a public package
88
+ ```
89
+
90
+ After publishing, users can install it with:
91
+
92
+ ```bash
93
+ npm install -g kubiy-cli
94
+ kubiy version
95
+ ```
96
+
97
+ **Español:** Este paquete está preparado para publicarse como paquete público en npm:
98
+
99
+ - Nombre del paquete: `kubiy-cli`
100
+ - Comando global: `kubiy` (definido en el campo `bin`)
101
+ - Solo se publican los archivos necesarios (`index.js` y `src/`)
102
+
103
+ Para publicar una nueva versión:
104
+
105
+ ```bash
106
+ # 1. Asegúrate de haber actualizado "version" en package.json
107
+
108
+ cd kubiy-npm-cli
109
+ npm login # una sola vez, si aún no lo hiciste
110
+ npm publish # publica kubiy-cli como paquete público
111
+ ```
112
+
113
+ Después de publicar, los usuarios pueden instalarlo con:
114
+
115
+ ```bash
116
+ npm install -g kubiy-cli
117
+ kubiy version
118
+ ```
package/index.js CHANGED
@@ -2,44 +2,79 @@
2
2
 
3
3
  const path = require("path");
4
4
  const { logInfo, logError } = require("./src/logger");
5
+ const { getLang, setLang } = require("./src/config");
6
+
7
+ const rawArgs = process.argv.slice(2);
8
+
9
+ // Extraer --lang / --lang= del CLI y dejar el resto de args limpios
10
+ let langFromCli = null;
11
+ const args = [];
12
+ for (let i = 0; i < rawArgs.length; i++) {
13
+ const a = rawArgs[i];
14
+ if (a === "--lang" && i + 1 < rawArgs.length) {
15
+ langFromCli = rawArgs[i + 1];
16
+ i++;
17
+ } else if (a.startsWith("--lang=")) {
18
+ langFromCli = a.split("=")[1];
19
+ } else {
20
+ args.push(a);
21
+ }
22
+ }
5
23
 
6
- const args = process.argv.slice(2);
7
24
  const command = args[0];
8
25
 
26
+ function resolveLang(langFromCli) {
27
+ // 1) CLI
28
+ if (langFromCli === "es" || langFromCli === "en") {
29
+ return langFromCli;
30
+ }
31
+
32
+ // 2) Config persistente
33
+ const saved = getLang && getLang();
34
+ if (saved === "es" || saved === "en") {
35
+ return saved;
36
+ }
37
+
38
+ // 3) Default
39
+ return "es";
40
+ }
41
+
9
42
  async function main() {
43
+ const lang = resolveLang(langFromCli);
44
+
10
45
  try {
11
46
  switch (command) {
12
47
  case "login":
13
- await require("./src/commands/login").run(args.slice(1));
14
- break;
48
+ logInfo("El comando 'kubiy login' está deshabilitado temporalmente y no se utiliza en esta versión del CLI.");
49
+ process.exit(1);
15
50
  case "whoami":
16
- await require("./src/commands/whoami").run(args.slice(1));
51
+ await require("./src/commands/whoami").run(args.slice(1), { lang });
17
52
  break;
18
53
  case "service:get":
19
- await require("./src/commands/service-get").run(args.slice(1));
20
- break;
21
- case "git:connect":
22
- await require("./src/commands/git-connect").run(args.slice(1));
54
+ await require("./src/commands/service-get").run(args.slice(1), { lang });
23
55
  break;
24
56
  case "link":
25
- await require("./src/commands/service-link").run(args.slice(1));
26
- break;
57
+ await require("./src/commands/service-link").run(args.slice(1), { lang });
58
+ break;
27
59
  case "deploy":
28
- await require("./src/commands/deploy").run(args.slice(1));
60
+ await require("./src/commands/deploy").run(args.slice(1), { lang });
29
61
  break;
30
62
  case "logs":
31
- await require("./src/commands/logs").run(args.slice(1));
63
+ await require("./src/commands/logs").run(args.slice(1), { lang });
32
64
  break;
33
65
  case "rollback":
34
- await require("./src/commands/rollback").run(args.slice(1));
66
+ await require("./src/commands/rollback").run(args.slice(1), { lang });
35
67
  break;
36
68
  case "version":
37
69
  case "--version":
38
70
  case "-v":
39
- await require("./src/commands/version").run(args.slice(1));
71
+ await require("./src/commands/version").run(args.slice(1), { lang });
72
+ break;
73
+ case "config":
74
+ await require("./src/commands/config").run(args.slice(1), { lang, langFromCli });
40
75
  break;
41
76
  default:
42
- printHelp();
77
+ printHelp(lang);
43
78
  process.exit(0);
44
79
  }
45
80
  } catch (err) {
@@ -48,27 +83,31 @@ async function main() {
48
83
  }
49
84
  }
50
85
 
51
- function printHelp() {
52
- logInfo("Kubiy PaaS CLI");
86
+ function printHelp(lang) {
87
+ const isEs = lang === "es";
88
+
89
+ logInfo(isEs ? "Kubiy PaaS CLI" : "Kubiy PaaS CLI");
53
90
  console.log("");
54
- console.log("Uso:");
55
- console.log(" kubiy login <cliToken>");
91
+ console.log(isEs ? "Uso:" : "Usage:");
92
+ console.log(" kubiy login <cliToken> (deshabilitado temporalmente)");
56
93
  console.log(" kubiy whoami");
57
94
  console.log(" kubiy link <appId> [--env=prod|stg|dev] [--apikey=...] [--save-secrets]");
58
- console.log(" kubiy deploy --message \"<texto>\" [--static] [--dir=<carpeta>]");
95
+ console.log(' kubiy deploy --message "<texto>" [--static] [--dir=<carpeta>]');
59
96
  console.log(" kubiy service:get <serviceId>");
60
- console.log(" kubiy git:connect <serviceId>");
61
97
  console.log(" kubiy logs [<serviceId>] [--kind=deploy|app] [--lines=200]");
62
98
  console.log(" kubiy rollback <deployId>");
63
99
  console.log(" kubiy rollback <appId> <serviceId> <deployId>");
64
100
  console.log(" kubiy version");
101
+ console.log(" kubiy config --lang es|en");
65
102
  console.log("");
66
- console.log("Ejemplos:");
103
+ console.log(isEs ? "Ejemplos:" : "Examples:");
67
104
  console.log(" kubiy link my-app-id --apikey=xxx");
68
- console.log(" kubiy deploy --message \"Release v1.0\"");
69
- console.log(" kubiy deploy -m \"Fix login\" --static");
70
- console.log(" kubiy deploy --message=\"Deploy prod\" --static --dir=dist");
105
+ console.log(' kubiy deploy --message "Release v1.0"');
106
+ console.log(' kubiy deploy -m "Fix login" --static');
107
+ console.log(' kubiy deploy --message="Deploy prod" --static --dir=dist');
71
108
  console.log(" kubiy logs --kind=deploy --lines=100");
109
+ console.log(" kubiy config --lang es");
110
+ console.log(" kubiy config --lang en");
72
111
  console.log("");
73
112
  }
74
113
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kubiy-paas-cli",
3
- "version": "0.1.10",
3
+ "version": "0.1.17",
4
4
  "description": "CLI para la plataforma PaaS de Kubiy",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -19,5 +19,9 @@
19
19
  "license": "MIT",
20
20
  "engines": {
21
21
  "node": ">=12.0.0"
22
- }
22
+ },
23
+ "files": [
24
+ "index.js",
25
+ "src"
26
+ ]
23
27
  }
@@ -0,0 +1,71 @@
1
+ const { logInfo, logError } = require("../logger");
2
+ const { getLang, setLang } = require("../config");
3
+
4
+ function parseArgs(args) {
5
+ let lang = null;
6
+
7
+ for (let i = 0; i < args.length; i++) {
8
+ const a = args[i];
9
+ if (a === "--lang" && i + 1 < args.length) {
10
+ lang = args[i + 1];
11
+ i++;
12
+ } else if (a.startsWith("--lang=")) {
13
+ lang = a.split("=")[1];
14
+ }
15
+ }
16
+
17
+ return { lang };
18
+ }
19
+
20
+ async function run(args = [], options = {}) {
21
+ const { lang: currentLangFromIndex } = options;
22
+ const { lang } = parseArgs(args);
23
+
24
+ // Si no se pasa --lang, mostrar idioma actual
25
+ if (!lang) {
26
+ const saved = getLang && getLang();
27
+ const effective = currentLangFromIndex || saved || "es";
28
+ const isEs = effective === "es";
29
+
30
+ if (isEs) {
31
+ logInfo(`Idioma actual del CLI: ${effective}`);
32
+ logInfo("Puedes cambiarlo con: kubiy config --lang es|en");
33
+ } else {
34
+ logInfo(`Current CLI language: ${effective}`);
35
+ logInfo("You can change it with: kubiy config --lang es|en");
36
+ }
37
+ return;
38
+ }
39
+
40
+ if (lang !== "es" && lang !== "en") {
41
+ const isEs = (currentLangFromIndex || getLang() || "es") === "es";
42
+ if (isEs) {
43
+ logError("Idioma no soportado. Usa 'es' o 'en'.");
44
+ } else {
45
+ logError("Unsupported language. Use 'es' or 'en'.");
46
+ }
47
+ process.exit(1);
48
+ }
49
+
50
+ try {
51
+ setLang(lang);
52
+ const isEs = lang === "es";
53
+ if (isEs) {
54
+ logInfo("Idioma guardado como Español.");
55
+ } else {
56
+ logInfo("Language saved as English.");
57
+ }
58
+ } catch (err) {
59
+ const isEs = (currentLangFromIndex || getLang() || "es") === "es";
60
+ if (isEs) {
61
+ logError("No se pudo guardar el idioma:");
62
+ } else {
63
+ logError("Failed to save language:");
64
+ }
65
+ logError(err.message || err);
66
+ process.exit(1);
67
+ }
68
+ }
69
+
70
+ module.exports = { run };
71
+
package/src/config.js CHANGED
@@ -37,11 +37,24 @@ function setCliToken(token) {
37
37
  writeConfig(cfg);
38
38
  }
39
39
 
40
+ function getLang() {
41
+ const cfg = readConfig();
42
+ return cfg.lang;
43
+ }
44
+
45
+ function setLang(lang) {
46
+ const cfg = readConfig();
47
+ cfg.lang = lang;
48
+ writeConfig(cfg);
49
+ }
50
+
40
51
  module.exports = {
41
52
  CONFIG_DIR,
42
53
  CONFIG_FILE,
43
54
  readConfig,
44
55
  writeConfig,
45
56
  getCliToken,
46
- setCliToken
57
+ setCliToken,
58
+ getLang,
59
+ setLang
47
60
  };
@@ -1,51 +0,0 @@
1
- name: Publish to npm
2
-
3
- on:
4
- # Opción 1: manual desde GitHub
5
- workflow_dispatch:
6
-
7
- # Opción 2: cuando hagas push de un tag tipo v1.2.3
8
- push:
9
- tags:
10
- - "v*"
11
-
12
- permissions:
13
- id-token: write # Necesario para OIDC con npm
14
- contents: read
15
-
16
- jobs:
17
- publish:
18
- runs-on: ubuntu-latest
19
-
20
- steps:
21
- - name: Checkout
22
- uses: actions/checkout@v4
23
-
24
- - name: Setup Node
25
- uses: actions/setup-node@v4
26
- with:
27
- node-version: "20"
28
- registry-url: "https://registry.npmjs.org"
29
-
30
- # Asegúrate de tener npm reciente (npm 11+ soporta bien trusted publishing) :contentReference[oaicite:3]{index=3}
31
- - name: Update npm
32
- run: npm install -g npm@latest
33
-
34
- - name: Install dependencies
35
- run: |
36
- if [ -f package-lock.json ] || [ -f npm-shrinkwrap.json ]; then
37
- echo "Lockfile encontrado, usando npm ci"
38
- npm ci
39
- else
40
- echo "Sin lockfile, usando npm install"
41
- npm install
42
- fi
43
-
44
- - name: Build
45
- run: npm run build --if-present
46
-
47
- - name: Test
48
- run: npm test --if-present
49
-
50
- - name: Publish to npm
51
- run: npm publish --access public
package/.kubiyignore DELETED
@@ -1,73 +0,0 @@
1
- # Kubiy Deploy Ignore File
2
- # Archivos y carpetas que se excluirán del deploy
3
- # Formato: un patrón por línea (similar a .gitignore)
4
-
5
- # Dependencias
6
- node_modules/
7
- vendor/
8
- __pycache__/
9
- *.pyc
10
- *.pyo
11
- *.pyd
12
- .Python
13
-
14
- # Build outputs
15
- bin/
16
- obj/
17
- dist/
18
- build/
19
- out/
20
- .next/
21
- .nuxt/
22
- .output/
23
-
24
- # Archivos de entorno y configuración local
25
- .env
26
- .env.local
27
- .env.*.local
28
- *.log
29
-
30
- # Sistema operativo
31
- .DS_Store
32
- Thumbs.db
33
- desktop.ini
34
-
35
- # IDEs y editores
36
- .vscode/
37
- .idea/
38
- *.swp
39
- *.swo
40
- *~
41
- .project
42
- .classpath
43
- .settings/
44
-
45
- # Git
46
- .git/
47
- .gitignore
48
-
49
- # Archivos temporales y comprimidos
50
- *.tar
51
- *.tar.gz
52
- *.zip
53
- *.rar
54
- *.7z
55
-
56
- # Archivos de test
57
- coverage/
58
- .nyc_output/
59
- *.test.js
60
- *.spec.js
61
- __tests__/
62
- test/
63
-
64
- # Documentación
65
- docs/
66
- *.md
67
- !README.md
68
-
69
- # Archivos de configuración local
70
- .kubiy.secrets.json
71
-
72
-
73
-
@@ -1,376 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="es">
3
- <head>
4
- <meta charset="UTF-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>Guía: Deploy de Sitios Estáticos con Kubiy</title>
7
- <style>
8
- * {
9
- margin: 0;
10
- padding: 0;
11
- box-sizing: border-box;
12
- }
13
-
14
- body {
15
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
16
- line-height: 1.6;
17
- color: #333;
18
- background: #f5f5f5;
19
- padding: 20px;
20
- }
21
-
22
- .container {
23
- max-width: 900px;
24
- margin: 0 auto;
25
- background: white;
26
- padding: 40px;
27
- border-radius: 8px;
28
- box-shadow: 0 2px 10px rgba(0,0,0,0.1);
29
- }
30
-
31
- h1 {
32
- color: #2563eb;
33
- margin-bottom: 10px;
34
- font-size: 2.5em;
35
- }
36
-
37
- h2 {
38
- color: #1e40af;
39
- margin-top: 40px;
40
- margin-bottom: 20px;
41
- padding-bottom: 10px;
42
- border-bottom: 2px solid #e5e7eb;
43
- }
44
-
45
- h3 {
46
- color: #3b82f6;
47
- margin-top: 30px;
48
- margin-bottom: 15px;
49
- }
50
-
51
- p {
52
- margin-bottom: 15px;
53
- text-align: justify;
54
- }
55
-
56
- .intro {
57
- background: #eff6ff;
58
- padding: 20px;
59
- border-radius: 6px;
60
- border-left: 4px solid #2563eb;
61
- margin-bottom: 30px;
62
- }
63
-
64
- .requirements {
65
- background: #f0fdf4;
66
- padding: 20px;
67
- border-radius: 6px;
68
- border-left: 4px solid #22c55e;
69
- margin: 20px 0;
70
- }
71
-
72
- .requirements ul {
73
- margin-left: 20px;
74
- margin-top: 10px;
75
- }
76
-
77
- .requirements li {
78
- margin-bottom: 8px;
79
- }
80
-
81
- .steps {
82
- background: #fef3c7;
83
- padding: 20px;
84
- border-radius: 6px;
85
- border-left: 4px solid #f59e0b;
86
- margin: 20px 0;
87
- }
88
-
89
- .step {
90
- margin-bottom: 25px;
91
- padding: 15px;
92
- background: white;
93
- border-radius: 4px;
94
- border: 1px solid #e5e7eb;
95
- }
96
-
97
- .step-number {
98
- display: inline-block;
99
- background: #2563eb;
100
- color: white;
101
- width: 30px;
102
- height: 30px;
103
- border-radius: 50%;
104
- text-align: center;
105
- line-height: 30px;
106
- font-weight: bold;
107
- margin-right: 10px;
108
- }
109
-
110
- code {
111
- background: #f3f4f6;
112
- padding: 2px 6px;
113
- border-radius: 3px;
114
- font-family: 'Courier New', monospace;
115
- font-size: 0.9em;
116
- color: #dc2626;
117
- }
118
-
119
- pre {
120
- background: #1f2937;
121
- color: #f9fafb;
122
- padding: 15px;
123
- border-radius: 6px;
124
- overflow-x: auto;
125
- margin: 15px 0;
126
- }
127
-
128
- pre code {
129
- background: none;
130
- color: inherit;
131
- padding: 0;
132
- }
133
-
134
- .warning {
135
- background: #fef2f2;
136
- padding: 15px;
137
- border-radius: 6px;
138
- border-left: 4px solid #ef4444;
139
- margin: 20px 0;
140
- }
141
-
142
- .success {
143
- background: #f0fdf4;
144
- padding: 15px;
145
- border-radius: 6px;
146
- border-left: 4px solid #22c55e;
147
- margin: 20px 0;
148
- }
149
-
150
- .info {
151
- background: #eff6ff;
152
- padding: 15px;
153
- border-radius: 6px;
154
- border-left: 4px solid #3b82f6;
155
- margin: 20px 0;
156
- }
157
-
158
- ul, ol {
159
- margin-left: 25px;
160
- margin-bottom: 15px;
161
- }
162
-
163
- li {
164
- margin-bottom: 8px;
165
- }
166
-
167
- .example {
168
- background: #f9fafb;
169
- padding: 15px;
170
- border-radius: 6px;
171
- margin: 15px 0;
172
- border: 1px solid #e5e7eb;
173
- }
174
-
175
- .troubleshooting {
176
- background: #fef3c7;
177
- padding: 20px;
178
- border-radius: 6px;
179
- margin: 20px 0;
180
- }
181
-
182
- .troubleshooting-item {
183
- margin-bottom: 20px;
184
- padding: 15px;
185
- background: white;
186
- border-radius: 4px;
187
- }
188
-
189
- .troubleshooting-item strong {
190
- color: #dc2626;
191
- }
192
- </style>
193
- </head>
194
- <body>
195
- <div class="container">
196
- <h1>🚀 Guía: Deploy de Sitios Estáticos con Kubiy</h1>
197
-
198
- <div class="intro">
199
- <p><strong>¿Qué es un deploy static?</strong></p>
200
- <p>Un deploy static te permite subir tu sitio web estático (HTML, CSS, JavaScript) a Kubiy de forma rápida y sencilla. Perfecto para sitios creados con frameworks como React, Vue, Angular, Next.js, o cualquier generador de sitios estáticos.</p>
201
- </div>
202
-
203
- <h2>📋 Requisitos Previos</h2>
204
-
205
- <div class="requirements">
206
- <p><strong>Antes de comenzar, necesitas:</strong></p>
207
- <ul>
208
- <li>✅ Tener tu proyecto vinculado con Kubiy (<code>kubiy link</code>)</li>
209
- <li>✅ Haber construido tu sitio estático (ejecutado <code>npm run build</code> o similar)</li>
210
- <li>✅ Tener instalado el CLI de Kubiy</li>
211
- <li>✅ Tener tu API Key configurada</li>
212
- </ul>
213
- </div>
214
-
215
- <h2>🎯 ¿Qué Necesitas Hacer?</h2>
216
-
217
- <div class="steps">
218
- <h3>Paso 1: Construir tu Sitio</h3>
219
- <div class="step">
220
- <span class="step-number">1</span>
221
- <p>Primero, necesitas generar los archivos estáticos de tu proyecto. Esto normalmente se hace con un comando de build:</p>
222
- <div class="example">
223
- <p><strong>Ejemplos según tu framework:</strong></p>
224
- <ul>
225
- <li><strong>React/Vite:</strong> <code>npm run build</code> → genera carpeta <code>dist/</code></li>
226
- <li><strong>Next.js:</strong> <code>npm run build</code> → genera carpeta <code>.next/</code> o <code>out/</code></li>
227
- <li><strong>Vue:</strong> <code>npm run build</code> → genera carpeta <code>dist/</code></li>
228
- <li><strong>Angular:</strong> <code>ng build</code> → genera carpeta <code>dist/</code></li>
229
- <li><strong>Nuxt:</strong> <code>npm run generate</code> → genera carpeta <code>.output/public/</code></li>
230
- </ul>
231
- </div>
232
- <div class="warning">
233
- <strong>⚠️ Importante:</strong> Asegúrate de que tu build haya generado un archivo <code>index.html</code> en la carpeta de salida. Sin este archivo, el deploy fallará.
234
- </div>
235
- </div>
236
-
237
- <h3>Paso 2: Ejecutar el Deploy</h3>
238
- <div class="step">
239
- <span class="step-number">2</span>
240
- <p>Una vez que tu sitio esté construido, ejecuta el comando de deploy:</p>
241
- <pre><code>kubiy deploy --static</code></pre>
242
-
243
- <div class="info">
244
- <p><strong>💡 Kubiy detectará automáticamente tu carpeta de build</strong></p>
245
- <p>El sistema buscará automáticamente en este orden:</p>
246
- <ol>
247
- <li><code>dist/</code></li>
248
- <li><code>build/</code></li>
249
- <li><code>out/</code></li>
250
- <li><code>.output/public/</code></li>
251
- </ol>
252
- <p>Si encuentra alguna de estas carpetas, la usará automáticamente.</p>
253
- </div>
254
- </div>
255
-
256
- <h3>Paso 3: Especificar una Carpeta Personalizada (Opcional)</h3>
257
- <div class="step">
258
- <span class="step-number">3</span>
259
- <p>Si tu carpeta de build tiene un nombre diferente, puedes especificarla:</p>
260
- <pre><code>kubiy deploy --static --dir=public</code></pre>
261
- <p>O también:</p>
262
- <pre><code>kubiy deploy --static --dir public</code></pre>
263
-
264
- <div class="example">
265
- <p><strong>Ejemplo:</strong> Si tu proyecto genera los archivos en una carpeta llamada <code>public/</code>:</p>
266
- <pre><code>kubiy deploy --static --dir=public</code></pre>
267
- </div>
268
- </div>
269
- </div>
270
-
271
- <h2>⚙️ Configuración en .kubiy.json</h2>
272
-
273
- <div class="info">
274
- <p>Kubiy guardará automáticamente la carpeta detectada en tu archivo <code>.kubiy.json</code>:</p>
275
- <pre><code>{
276
- "appId": "tu-app-id",
277
- "serviceId": "tu-service-id",
278
- "static": {
279
- "outDir": "dist"
280
- }
281
- }</code></pre>
282
- <p>La próxima vez que ejecutes <code>kubiy deploy --static</code>, usará automáticamente esta carpeta sin necesidad de especificarla.</p>
283
- </div>
284
-
285
- <h2>📝 Ejemplo Completo</h2>
286
-
287
- <div class="example">
288
- <p><strong>Flujo completo para un proyecto React:</strong></p>
289
- <pre><code># 1. Construir el proyecto
290
- npm run build
291
-
292
- # 2. Hacer el deploy
293
- kubiy deploy --static
294
-
295
- # ¡Listo! Tu sitio estará en línea</code></pre>
296
- </div>
297
-
298
- <div class="example">
299
- <p><strong>Flujo completo para un proyecto Next.js con carpeta personalizada:</strong></p>
300
- <pre><code># 1. Construir el proyecto
301
- npm run build
302
-
303
- # 2. Hacer el deploy especificando la carpeta
304
- kubiy deploy --static --dir=.next
305
-
306
- # ¡Listo! Tu sitio estará en línea</code></pre>
307
- </div>
308
-
309
- <h2>🔧 Solución de Problemas Comunes</h2>
310
-
311
- <div class="troubleshooting">
312
- <div class="troubleshooting-item">
313
- <strong>❌ Error: "No static output folder found"</strong>
314
- <p><strong>Solución:</strong> Asegúrate de haber ejecutado el comando de build de tu proyecto. Si tu carpeta tiene un nombre diferente, especifícala con <code>--dir</code>:</p>
315
- <pre><code>kubiy deploy --static --dir=tu-carpeta</code></pre>
316
- </div>
317
-
318
- <div class="troubleshooting-item">
319
- <strong>❌ Error: "index.html not found"</strong>
320
- <p><strong>Solución:</strong> Tu carpeta de build debe contener un archivo <code>index.html</code>. Verifica que el build se haya completado correctamente y que el archivo exista en la carpeta de salida.</p>
321
- </div>
322
-
323
- <div class="troubleshooting-item">
324
- <strong>❌ Error: "Output dir not found"</strong>
325
- <p><strong>Solución:</strong> La carpeta que especificaste con <code>--dir</code> no existe. Verifica la ruta y asegúrate de que el build se haya ejecutado correctamente.</p>
326
- </div>
327
-
328
- <div class="troubleshooting-item">
329
- <strong>❌ Error: "El proyecto está configurado como 'static'"</strong>
330
- <p><strong>Solución:</strong> Si tu proyecto está configurado como static en <code>.kubiy.json</code>, siempre debes usar <code>--static</code>. Si quieres hacer un deploy normal, primero cambia el <code>deployType</code> en tu configuración.</p>
331
- </div>
332
- </div>
333
-
334
- <h2>✅ Verificación del Deploy</h2>
335
-
336
- <div class="success">
337
- <p>Después de ejecutar <code>kubiy deploy --static</code>, verás mensajes como:</p>
338
- <pre><code>✓ Usando directorio static: /ruta/a/dist
339
- ✓ Artefacto static generado en temp
340
- ✓ Presign OK. deployId=xxx releaseId=yyy
341
- ✓ Artefacto subido correctamente a S3
342
- ✓ Marker subido correctamente
343
- 🚀 Deploy iniciado correctamente en Kubiy</code></pre>
344
- <p>Si ves estos mensajes, ¡tu deploy se está procesando correctamente!</p>
345
- </div>
346
-
347
- <h2>💡 Consejos Útiles</h2>
348
-
349
- <div class="info">
350
- <ul>
351
- <li><strong>Automatiza tus deploys:</strong> Puedes agregar el comando a tu script de CI/CD para que se despliegue automáticamente después de cada build.</li>
352
- <li><strong>Verifica antes de deployar:</strong> Siempre prueba tu sitio localmente después del build antes de hacer el deploy.</li>
353
- <li><strong>Revisa los logs:</strong> Si algo sale mal, puedes revisar los logs con <code>kubiy logs &lt;serviceId&gt;</code></li>
354
- <li><strong>Configuración persistente:</strong> Una vez que Kubiy detecta tu carpeta, la guarda en <code>.kubiy.json</code>, así que no necesitarás especificarla cada vez.</li>
355
- </ul>
356
- </div>
357
-
358
- <h2>📚 Comandos Relacionados</h2>
359
-
360
- <div class="example">
361
- <ul>
362
- <li><code>kubiy link &lt;appId&gt;</code> - Vincular tu proyecto con Kubiy</li>
363
- <li><code>kubiy deploy --static</code> - Deploy de sitio estático</li>
364
- <li><code>kubiy deploy --static --dir=&lt;carpeta&gt;</code> - Deploy especificando carpeta</li>
365
- <li><code>kubiy logs &lt;serviceId&gt;</code> - Ver logs del servicio</li>
366
- <li><code>kubiy service:get &lt;serviceId&gt;</code> - Ver información del servicio</li>
367
- </ul>
368
- </div>
369
-
370
- <div style="margin-top: 40px; padding-top: 20px; border-top: 2px solid #e5e7eb; text-align: center; color: #6b7280;">
371
- <p>© 2024 Kubiy - Documentación de Deploy Static</p>
372
- </div>
373
- </div>
374
- </body>
375
- </html>
376
-
@@ -1,106 +0,0 @@
1
- # Archivo .kubiyignore
2
-
3
- El archivo `.kubiyignore` te permite especificar qué archivos y carpetas deben ser excluidos cuando haces un deploy con `kubiy deploy`.
4
-
5
- ## Ubicación
6
-
7
- Crea el archivo `.kubiyignore` en la raíz de tu proyecto, junto a tu `package.json` o `.kubiy.json`.
8
-
9
- ## Formato
10
-
11
- El formato es similar a `.gitignore`: un patrón por línea. Puedes usar comentarios con `#`.
12
-
13
- ## Ejemplos
14
-
15
- ```
16
- # Dependencias
17
- node_modules/
18
- vendor/
19
-
20
- # Build outputs
21
- bin/
22
- obj/
23
- dist/
24
-
25
- # Archivos de entorno
26
- .env
27
- *.log
28
-
29
- # Python
30
- __pycache__/
31
- *.pyc
32
-
33
- # .NET
34
- bin/
35
- obj/
36
- ```
37
-
38
- ## Exclusiones por Defecto
39
-
40
- Si no creas un archivo `.kubiyignore`, Kubiy usará estas exclusiones por defecto:
41
-
42
- - `node_modules/`
43
- - `.git/`
44
- - `.env`
45
- - `.DS_Store`
46
- - `*.tar`
47
- - `*.tar.gz`
48
- - `bin/`
49
- - `obj/`
50
- - `__pycache__/`
51
- - `*.pyc`
52
- - `vendor/`
53
-
54
- ## Patrones Soportados
55
-
56
- - **Carpetas**: `node_modules/` o `node_modules` (ambos funcionan)
57
- - **Archivos**: `.env`, `*.log`
58
- - **Wildcards**: `*.pyc`, `*.log`
59
- - **Comentarios**: Líneas que empiezan con `#`
60
-
61
- ## Ejemplos por Lenguaje
62
-
63
- ### Node.js
64
- ```
65
- node_modules/
66
- npm-debug.log
67
- .env
68
- .DS_Store
69
- ```
70
-
71
- ### Python
72
- ```
73
- __pycache__/
74
- *.pyc
75
- *.pyo
76
- venv/
77
- env/
78
- .venv
79
- ```
80
-
81
- ### .NET
82
- ```
83
- bin/
84
- obj/
85
- *.user
86
- *.suo
87
- .vs/
88
- ```
89
-
90
- ### Java
91
- ```
92
- target/
93
- .classpath
94
- .project
95
- .settings/
96
- ```
97
-
98
- ## Notas
99
-
100
- - Los patrones se combinan con las exclusiones por defecto
101
- - Si especificas un patrón en `.kubiyignore`, se agregará a las exclusiones por defecto
102
- - Los comentarios (líneas que empiezan con `#`) se ignoran
103
- - Las líneas vacías se ignoran
104
-
105
-
106
-
package/fix-link.js DELETED
@@ -1,72 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- const fs = require('fs');
4
- const path = require('path');
5
- const os = require('os');
6
-
7
- const isWin = process.platform === 'win32';
8
-
9
- if (isWin) {
10
- // ==========================
11
- // LADO WINDOWS (lo que ya tenías)
12
- // ==========================
13
-
14
- // Ruta donde npm instala los comandos globales (típico en Windows)
15
- const npmBinPath = path.join(os.homedir(), 'AppData', 'Roaming', 'npm');
16
- const kubiyCmdPath = path.join(npmBinPath, 'kubiy.cmd');
17
- const kubiyPs1Path = path.join(npmBinPath, 'kubiy.ps1');
18
-
19
- // Corregir kubiy.cmd
20
- if (fs.existsSync(kubiyCmdPath)) {
21
- let content = fs.readFileSync(kubiyCmdPath, 'utf8');
22
-
23
- // Verificar si necesita corrección (no tiene 'node' explícito)
24
- if (!content.includes('node "%dp0%')) {
25
- // Reemplazar la línea que ejecuta el .js directamente
26
- content = content.replace(
27
- /"%dp0%\\node_modules\\kubiy-paas-cli\\index\.js"/g,
28
- 'node "%dp0%\\node_modules\\kubiy-paas-cli\\index.js"'
29
- );
30
-
31
- fs.writeFileSync(kubiyCmdPath, content, 'utf8');
32
- console.log('✅ Archivo kubiy.cmd corregido');
33
- }
34
- }
35
-
36
- // Corregir kubiy.ps1
37
- if (fs.existsSync(kubiyPs1Path)) {
38
- let content = fs.readFileSync(kubiyPs1Path, 'utf8');
39
-
40
- // Verificar si necesita corrección (no tiene 'node' explícito)
41
- if (!content.includes('node "$basedir')) {
42
- // Reemplazar las líneas que ejecutan el .js directamente
43
- content = content.replace(
44
- /& "`\$basedir\/node_modules\/kubiy-paas-cli\/index\.js"/g,
45
- '& node "$basedir/node_modules/kubiy-paas-cli/index.js"'
46
- );
47
- // También corregir la versión sin backticks (por si acaso)
48
- content = content.replace(
49
- /& "\$basedir\/node_modules\/kubiy-paas-cli\/index\.js"/g,
50
- '& node "$basedir/node_modules/kubiy-paas-cli/index.js"'
51
- );
52
-
53
- fs.writeFileSync(kubiyPs1Path, content, 'utf8');
54
- console.log('✅ Archivo kubiy.ps1 corregido');
55
- }
56
- }
57
-
58
- } else {
59
- // ==========================
60
- // LADO UNIX / MAC
61
- // ==========================
62
- try {
63
- const indexPath = path.join(__dirname, 'index.js');
64
-
65
- if (fs.existsSync(indexPath)) {
66
- fs.chmodSync(indexPath, 0o755);
67
- console.log('✅ Unix: permisos ejecutables aplicados a index.js (chmod +x)');
68
- }
69
- } catch (e) {
70
- console.log('⚠ No se pudo aplicar chmod a index.js en Unix:', e.message);
71
- }
72
- }
@@ -1,114 +0,0 @@
1
- // src/commands/git-connect.js
2
- const { getCliToken } = require("../config");
3
- const { apiGet, apiPost } = require("../api");
4
- const { ensureSshKey, SSH_PRIV } = require("../ssh");
5
- const { ensureSshHostConfig } = require("../ssh-config");
6
- const { addRemote } = require("../git");
7
- const { logInfo, logSuccess, logError } = require("../logger");
8
-
9
- const { execSync } = require("child_process");
10
- const fs = require("fs");
11
-
12
- function ensureGitRepo() {
13
- if (fs.existsSync(".git")) return;
14
-
15
- logInfo("Este directorio no es un repositorio git. Inicializando...");
16
- execSync("git init", { stdio: "inherit" });
17
- try {
18
- execSync("git checkout -b main", { stdio: "inherit" });
19
- } catch (_) {
20
- // Si ya existe main/master, no pasa nada
21
- }
22
- }
23
-
24
- function parseRepoUrl(gitRepoUrl) {
25
- // Esperamos algo como ssh://deploy@1.2.3.4/home/deploy/app.git
26
- try {
27
- const url = new URL(gitRepoUrl);
28
- return {
29
- host: url.hostname,
30
- path: url.pathname // /home/deploy/app.git
31
- };
32
- } catch (e) {
33
- // fallback muy básico
34
- // ssh://deploy@1.2.3.4/home/deploy/app.git
35
- if (!gitRepoUrl.startsWith("ssh://")) {
36
- throw new Error(`gitRepoUrl inválido: ${gitRepoUrl}`);
37
- }
38
- const withoutScheme = gitRepoUrl.slice("ssh://".length);
39
- const [userHost, pathPart] = withoutScheme.split("/", 2);
40
- const host = userHost.split("@").pop();
41
- return {
42
- host,
43
- path: "/" + pathPart
44
- };
45
- }
46
- }
47
-
48
- async function run(argv) {
49
- const serviceId = argv[0];
50
-
51
- if (!serviceId) {
52
- logError("Uso: kubiy git:connect <serviceId>");
53
- process.exit(1);
54
- }
55
-
56
- const token = getCliToken();
57
- if (!token) {
58
- logError("No hay CLI token. Ejecuta: kubiy login <cliToken>");
59
- process.exit(1);
60
- }
61
-
62
- // 1) Asegurar llave SSH local (~/.kubiy/id_ed25519)
63
- const pubKey = ensureSshKey();
64
-
65
- // 2) Registrar llave en tu API
66
- logInfo("Registrando llave SSH en Kubiy...");
67
- await apiPost("/cli/ssh-keys", { publicKey: pubKey });
68
- logSuccess("Llave SSH registrada.");
69
-
70
- // 3) Sincronizar llaves con la EC2 del servicio
71
- logInfo("Sincronizando llaves SSH con la instancia...");
72
- try {
73
- const syncResp = await apiPost(`/cli/services/${serviceId}/sync-ssh`, {});
74
- logSuccess(
75
- `Llaves sincronizadas. keysApplied=${syncResp.keysApplied}, ssmStatus=${syncResp.ssmStatus}`
76
- );
77
- } catch (e) {
78
- logError(`No se pudo sincronizar llaves con la instancia: ${e.message}`);
79
- // seguimos, porque igual podrías tener la llave ya metida de antes
80
- }
81
-
82
- // 4) Obtener info del servicio (para gitRepoUrl)
83
- logInfo("Obteniendo información del servicio...");
84
- const service = await apiGet(`/services/${serviceId}`);
85
-
86
- const gitRepoUrl = service.gitRepoUrl;
87
- if (!gitRepoUrl) {
88
- logError("El servicio no tiene gitRepoUrl todavía. Asegúrate que esté en RUNNING.");
89
- process.exit(1);
90
- }
91
-
92
- const { host: ec2Host, path: repoPath } = parseRepoUrl(gitRepoUrl);
93
-
94
- // 5) Configurar ~/.ssh/config con un host lógico único para este servicio
95
- const hostAlias = `kubiy-${serviceId}`.slice(0, 60); // por si se va muy largo
96
-
97
- ensureSshHostConfig(hostAlias, ec2Host, SSH_PRIV);
98
-
99
- // 6) Configurar remote con el alias, no con la IP directa
100
- ensureGitRepo();
101
- logInfo("Configurando remote 'kubiy'...");
102
- const remoteUrl = `ssh://${hostAlias}${repoPath}`;
103
- addRemote("kubiy", remoteUrl);
104
-
105
- logSuccess("Remote 'kubiy' configurado.");
106
-
107
- logSuccess("Listo. Puedes hacer ahora:");
108
- console.log(" git add .");
109
- console.log(" git commit -m \"tu mensaje\"");
110
- console.log(" git push kubiy main # o master");
111
- console.log(" kubiy deploy");
112
- }
113
-
114
- module.exports = { run };
package/src/ssh-config.js DELETED
@@ -1,51 +0,0 @@
1
- // src/ssh-config.js
2
- const fs = require("fs");
3
- const os = require("os");
4
- const path = require("path");
5
- const { logInfo, logSuccess } = require("./logger");
6
-
7
- const SSH_DIR = path.join(os.homedir(), ".ssh");
8
- const SSH_CONFIG = path.join(SSH_DIR, "config");
9
-
10
- function ensureSshHostConfig(hostAlias, hostName, identityFile) {
11
- if (!fs.existsSync(SSH_DIR)) {
12
- fs.mkdirSync(SSH_DIR, { recursive: true });
13
- }
14
-
15
- let existing = "";
16
- if (fs.existsSync(SSH_CONFIG)) {
17
- existing = fs.readFileSync(SSH_CONFIG, "utf8");
18
- const already = new RegExp(`^Host\\s+${hostAlias}\\b`, "m").test(existing);
19
- if (already) {
20
- logInfo(`SSH config ya tiene entrada para Host '${hostAlias}'`);
21
- return;
22
- }
23
- }
24
-
25
- const identityPath = identityFile.replace(/\\/g, "/");
26
-
27
- const block = [
28
- "",
29
- `Host ${hostAlias}`,
30
- ` HostName ${hostName}`,
31
- ` User deploy`,
32
- ` IdentityFile ${identityPath}`,
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`,
38
- ""
39
- ].join("\n");
40
-
41
- const newContent = existing ? `${existing.trimEnd()}\n${block}` : block.trimStart();
42
-
43
- fs.writeFileSync(SSH_CONFIG, newContent, "utf8");
44
- logSuccess(`Configurado ~/.ssh/config para Host '${hostAlias}'`);
45
- }
46
-
47
- module.exports = {
48
- ensureSshHostConfig,
49
- SSH_DIR,
50
- SSH_CONFIG,
51
- };
package/src/ssh.js DELETED
@@ -1,40 +0,0 @@
1
- const fs = require("fs");
2
- const os = require("os");
3
- const path = require("path");
4
- const { execSync } = require("child_process");
5
- const { logInfo, logSuccess, logWarn } = require("./logger");
6
-
7
- const SSH_DIR = path.join(os.homedir(), ".kubiy");
8
- const SSH_PRIV = path.join(SSH_DIR, "id_ed25519");
9
- const SSH_PUB = SSH_PRIV + ".pub";
10
-
11
- function ensureSshKey() {
12
- if (!fs.existsSync(SSH_DIR)) {
13
- fs.mkdirSync(SSH_DIR, { recursive: true });
14
- }
15
-
16
- if (!fs.existsSync(SSH_PRIV) || !fs.existsSync(SSH_PUB)) {
17
- logInfo("No existe llave SSH de Kubiy, generando una nueva...");
18
-
19
- try {
20
- execSync(
21
- `ssh-keygen -t ed25519 -f "${SSH_PRIV}" -N "" -C "kubiy-cli"`,
22
- { stdio: "inherit" }
23
- );
24
- logSuccess("Llave SSH generada en ~/.kubiy/");
25
- } catch (e) {
26
- logWarn("Error generando llave SSH:", e.message);
27
- throw e;
28
- }
29
- }
30
-
31
- const pub = fs.readFileSync(SSH_PUB, "utf8").trim();
32
- return pub;
33
- }
34
-
35
- module.exports = {
36
- SSH_DIR,
37
- SSH_PRIV,
38
- SSH_PUB,
39
- ensureSshKey
40
- };