kcreate-scaffolding-gcp-script 0.0.0-stage → 0.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.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Kronops
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,371 @@
1
- # Temporary Holding Version
1
+ # KCreateScaffoldingGCPScripts
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Skill de Claude Code (`kcreate-scaffolding-gcp-script`) que genera el
4
+ scaffolding de Terragrunt para un entorno GCP nuevo, copiando y adaptando
5
+ uno ya existente del mismo repo (`live/<entorno-nuevo>/` a partir de
6
+ `live/<entorno-existente>/`). Pensado para repos con la convención de
7
+ [`club-tijuana/infra-cloud`](https://github.com/club-tijuana/infra-cloud):
8
+ `live/<entorno>/<componente>/terragrunt.hcl` + `Makefile` + `.gitignore`
9
+ por componente.
10
+
11
+ Este repo es el **instalador** del skill: contiene el skill, sus scripts y su
12
+ dependencia vendorizada, y los copia a `<repo-destino>/.claude/skills/`. No
13
+ contiene `live/` ni se instala a sí mismo.
14
+
15
+ **Este skill no despliega nada en GCP.** Solo crea/edita archivos locales.
16
+ El despliegue es un proceso aparte, posterior y manual.
17
+
18
+ > El directorio local y el nombre viejo del repo eran
19
+ > `KTerragruntScaffoldingScripts`; el repo en GitHub es
20
+ > [`kronops/KCreateScaffoldingGCPScripts`](https://github.com/kronops/KCreateScaffoldingGCPScripts).
21
+
22
+ | Documento | Para qué |
23
+ |---|---|
24
+ | `README.md` (este) | Manual de usuario: qué hace, cómo se instala y cómo se usa. |
25
+ | [`AGENT.md`](AGENT.md) | Guía operativa para agentes de IA: ciclo completo, contrato de exit codes, fallas comunes, receta de validación. |
26
+ | [`CONTRIBUTING.md`](CONTRIBUTING.md) | Flujo de contribución, convenciones e invariantes del código. |
27
+ | [`DeployNPM.md`](DeployNPM.md) | Manual operativo para publicar el paquete npm (comandos exactos, autenticación con OTP, verificación y errores comunes). |
28
+ | [`CHANGELOG.md`](CHANGELOG.md) | Historia de versiones (Keep a Changelog). |
29
+ | [`IDEA.md`](IDEA.md) | Especificación de origen del skill. |
30
+ | [`kcreate-scaffolding-gcp-script/SKILL.md`](kcreate-scaffolding-gcp-script/SKILL.md) | Instrucciones del agente, etapa por etapa (lo que ejecuta el skill instalado). |
31
+ | [`kcreate-scaffolding-gcp-script/references/lessons-learned.md`](kcreate-scaffolding-gcp-script/references/lessons-learned.md) | El "por qué" de cada script y validación, con los errores reales que los motivaron. |
32
+
33
+ ## Qué resuelve
34
+
35
+ Generar estos scripts a mano es mecánico pero con muchas oportunidades de
36
+ error que **no se detectan hasta el momento real de desplegar en GCP**
37
+ (un rango CIDR que colisiona, una IP mal transcrita, una API faltante, un
38
+ nombre de red que se quedó con el del entorno viejo). Este skill
39
+ automatiza esa generación con scripts de shell determinísticos — no con
40
+ juicio de un agente de IA en cada paso — para eliminar esa clase de
41
+ errores por diseño. El detalle completo de cada error real que este
42
+ diseño evita está en
43
+ [`kcreate-scaffolding-gcp-script/references/lessons-learned.md`](kcreate-scaffolding-gcp-script/references/lessons-learned.md).
44
+
45
+ ## Instalación
46
+
47
+ Hay dos instaladores **intercambiables**: dejan exactamente el mismo
48
+ resultado en el repo destino (mismos archivos, mismos permisos, mismos exit
49
+ codes). Elige el que te acomode.
50
+
51
+ En ambos casos se instala el skill (+ su dependencia
52
+ [`github-proyect-tracking`](https://github.com/kronops/KGithubTracking),
53
+ vendorizada en `vendor/`) en el repo donde se va a usar, como skill de
54
+ proyecto de Claude Code.
55
+
56
+ ### Opción A — `npx` (sin instalar el skill a mano)
57
+
58
+ Si el paquete está en el registro de npm (o tienes el tarball):
59
+
60
+ ```bash
61
+ npx --yes kcreate-scaffolding-gcp-script --target-repo /ruta/a/tu/repo-de-infra
62
+ npx --yes ./kcreate-scaffolding-gcp-script-0.2.0.tgz --target-repo /ruta/a/tu/repo-de-infra
63
+ ```
64
+
65
+ Generar el tarball desde una copia del repo:
66
+
67
+ ```bash
68
+ git clone git@github-work:kronops/KCreateScaffoldingGCPScripts.git
69
+ cd KCreateScaffoldingGCPScripts/npm
70
+ npm pack # prepack empaqueta skill/ + vendor/ + README + LICENSE
71
+ npx --yes ./kcreate-scaffolding-gcp-script-0.2.0.tgz --target-repo /ruta/a/tu/repo
72
+ ```
73
+
74
+ Requisitos del instalador npx: **Node ≥ 18** (cero dependencias npm). El skill
75
+ en sí no usa Node: es bash + Python 3.8+ stdlib.
76
+
77
+ > `npx ... github:kronops/KCreateScaffoldingGCPScripts` **no** sirve: npm
78
+ exige el `package.json` en la raíz del repo y aquí vive en `npm/` (npm no
79
+ soporta subdirectorios en dependencias git). Por eso la opción `npx`
80
+ requiere el paquete publicado o un tarball local.
81
+
82
+ ### Opción B — clonando el repo
83
+
84
+ ```bash
85
+ git clone git@github-work:kronops/KCreateScaffoldingGCPScripts.git
86
+ cd KCreateScaffoldingGCPScripts
87
+ ./install.sh --target-repo /ruta/a/tu/repo-de-infra
88
+ ```
89
+
90
+ ### Resultado (idéntico en ambas opciones)
91
+
92
+ ```
93
+ <tu-repo>/.claude/skills/
94
+ ├── kcreate-scaffolding-gcp-script/ # este skill
95
+ └── github-proyect-tracking/ # dependencia, para poder reanudar
96
+ ```
97
+
98
+ Si el repo destino no tiene `live/`, el instalador avisa con `[WARN]` (el
99
+ skill asume la convención `live/<entorno>/<componente>/terragrunt.hcl`) pero
100
+ igual instala: la herramienta sirve para cualquier repo, aunque falle al
101
+ usarse.
102
+
103
+ ### Flags
104
+
105
+ Los mismos nombres y semántica en `install.sh` y en el instalador npx:
106
+
107
+ | Flag | Para qué |
108
+ |---|---|
109
+ | `--target-repo RUTA` | Raíz del repo destino (obligatorio; debe ser un repo git). |
110
+ | `--skip-tracking` | No instala/actualiza `github-proyect-tracking`, por si el repo destino ya lo gestiona por su cuenta. |
111
+ | `--force` | Sobreescribe si el skill ya existe en el destino. Sin esta bandera, una instalación existente nunca se toca: se reporta con `[ERROR]` y **exit 1** (no se instala nada). |
112
+
113
+ Para desinstalar:
114
+
115
+ ```bash
116
+ # npx
117
+ npx --yes kcreate-scaffolding-gcp-script uninstall --target-repo /ruta/a/tu/repo
118
+
119
+ # clonado
120
+ ./uninstall.sh --target-repo /ruta/a/tu/repo
121
+ ```
122
+
123
+ | Flag de uninstall | Para qué |
124
+ |---|---|
125
+ | `--with-tracking` | También elimina `github-proyect-tracking`. Por defecto **no** se toca, porque otro skill del mismo repo podría seguir usándolo. |
126
+ | `--clean-gitignore` | También quita la línea `.kcreate-scaffolding/` del `.gitignore` del destino y borra la carpeta `.kcreate-scaffolding/` (configs y warnings de ejecuciones anteriores). Es destructivo a propósito: úsalo solo si ya no necesitas revisar esos archivos. |
127
+
128
+ ### Diagnóstico previo (`npx … doctor`)
129
+
130
+ Solo en el instalador npx. No modifica nada: dice qué hay instalado en el
131
+ repo destino y si están las dependencias que usan los scripts.
132
+
133
+ ```bash
134
+ npx --yes kcreate-scaffolding-gcp-script doctor --target-repo /ruta/a/tu/repo
135
+ ```
136
+
137
+ Revisa `bash`, `git`, `python3` (con `ipaddress`), `curl` y `terragrunt`
138
+ (**opcional**: si falta, el build omite `hcl fmt`/`hcl validate` y avisa).
139
+ Termina con `[OK] Entorno listo para usar el skill.` (exit 0) o con exit 1
140
+ listando los requisitos faltantes.
141
+
142
+ ### Publicar el paquete npm (mantenedores)
143
+
144
+ El procedimiento completo — y los comandos exactos, uno por uno — está en
145
+ [`DeployNPM.md`](DeployNPM.md). Resumen:
146
+
147
+ ```bash
148
+ cd npm
149
+ npm whoami # ¿hay sesión? (hoy: E401, hay que loguearse)
150
+ npm login --auth-type=legacy # usuario, password, email y, si la cuenta tiene 2FA, OTP
151
+ npm publish --dry-run # ensayo obligatorio: construye el tarball sin subir nada
152
+ npm publish # publicar (con 2FA: npm publish --otp=123456)
153
+ ```
154
+
155
+ Ojo: si la cuenta tiene 2FA, el login por navegador **no** sirve sin GUI; hay
156
+ que usar `--auth-type=legacy` y pasar el OTP. El `.npmrc` que deja el login
157
+ contiene `_authToken` y ya está en `.gitignore`.
158
+
159
+ `npm/bin/build.js` reconstruye `npm/skill/`, `npm/vendor/`,
160
+ `npm/README.md` y `npm/LICENSE` desde la raíz del repo en cada
161
+ `npm pack`/`npm publish` — son artefactos generados y están en `.gitignore`,
162
+ nunca se comitean. Prueba local sin publicar:
163
+
164
+ ```bash
165
+ cd npm && npm pack
166
+ npx --yes ./kcreate-scaffolding-gcp-script-0.2.0.tgz --target-repo /ruta/al/repo
167
+ ```
168
+
169
+ Para subir una versión nueva: `node -p "require('./package.json').version"`,
170
+ luego `npm version patch --no-git-tag-version` (o `minor`/`major` según el
171
+ cambio) y refleja la versión en `CHANGELOG.md` y en las rutas de este README.
172
+ El `--no-git-tag-version` es obligatorio aquí: el `package.json` no está en la
173
+ raíz git y sin ese flag `npm version` crea commits y tags inesperados. Subir la
174
+ versión no es opcional cuando ya se publicó: una versión del registro no se
175
+ puede reutilizar (`E409`).
176
+
177
+ ## Uso
178
+
179
+ Desde una sesión de Claude Code abierta en el repo destino (con el skill
180
+ ya instalado ahí), con el cwd en la raíz de ese repo:
181
+
182
+ ```
183
+ /kcreate-scaffolding-gcp-script <SOURCE_ENV> <NEW_ENV>
184
+ ```
185
+
186
+ - `SOURCE_ENV`: el entorno ya existente a copiar (ej. `boletera-qa`).
187
+ Cualquiera que ya exista en `live/` sirve — no hay uno "oficial".
188
+ - `NEW_ENV`: el id del entorno nuevo, patrón `<app>-qa` o `<app>-prod` en
189
+ minúsculas (ej. `xoloshop-prod`).
190
+
191
+ El agente sigue entonces las 3 etapas descritas en
192
+ [`kcreate-scaffolding-gcp-script/SKILL.md`](kcreate-scaffolding-gcp-script/SKILL.md):
193
+
194
+ 1. **Pre requisitos** — genera (o reanuda) un archivo de configuración en
195
+ `.kcreate-scaffolding/<NEW_ENV>.config`, autodetectando del propio
196
+ `SOURCE_ENV` todo lo que se pueda (org id, billing account,
197
+ región/zona, owner, IPs fijas, versiones actuales). Solo pide al
198
+ humano lo que de verdad no se puede inferir: el repo de GitHub de la
199
+ app nueva y la URL del proyecto de GitHub usado para llevar el
200
+ seguimiento de esta ejecución. Antes de construir nada, muestra el
201
+ archivo completo y pide confirmación explícita.
202
+ 2. **Construcción** — un solo comando genera `live/<NEW_ENV>/` completo,
203
+ componente por componente, con sustituciones de texto determinísticas
204
+ (nunca ediciones "a mano" de HCL). Avisa con `[WARN]` en los pocos
205
+ casos que de verdad requieren revisión humana (ver la lista completa en
206
+ `lessons-learned.md`).
207
+ 3. **Validación** — dos scripts confirman que el resultado está completo
208
+ (mismos archivos que `SOURCE_ENV`, ni más ni menos) y que cada
209
+ componente apunta siempre al proyecto GCP correcto, sin importar qué
210
+ proyecto tenga `gcloud` como default en ese momento.
211
+
212
+ Si el proceso se interrumpe a la mitad (sesión caída, error de red), basta
213
+ con pedirle al agente que vuelva a correr el mismo comando. El progreso
214
+ se registra en `github-proyect-tracking` (un Issue del repo de GitHub que
215
+ pusiste en `TRACKING_GITHUB_PROJECT_URL`) cuando está disponible — si
216
+ falla (sin red, token, URL inválida), la construcción sigue igual sin
217
+ tracking, solo con un aviso. La construcción en sí es idempotente: cada
218
+ componente se reconstruye siempre desde `SOURCE_ENV`, así que reintentar
219
+ después de un fallo a medias no requiere borrar nada ni produce un
220
+ resultado distinto (el rango CIDR elegido también se reusa, no se vuelve
221
+ a calcular).
222
+
223
+ ### El archivo de configuración
224
+
225
+ Se genera una sola vez por ejecución, en
226
+ `.kcreate-scaffolding/<NEW_ENV>.config` (gitignorado automáticamente —
227
+ nunca se comitea). Plantilla de referencia:
228
+ [`kcreate-scaffolding-gcp-script/templates/scaffolding.config.template`](kcreate-scaffolding-gcp-script/templates/scaffolding.config.template).
229
+
230
+ Campos que **siempre** hay que llenar a mano (no se pueden inferir de
231
+ `SOURCE_ENV`):
232
+
233
+ | Campo | Qué es |
234
+ |---|---|
235
+ | `APP_GITHUB_REPO` | Repo(s) de GitHub (`owner/repo`) que hacen `push` de imágenes Docker al Artifact Registry del proyecto nuevo. Uno solo en el caso común; si la app tiene varios repos, sepáralos con `;` — se genera un binding de `github_workload_identity` por cada uno. Se asume que ya existen — no se valida contra GitHub. |
236
+ | `TRACKING_GITHUB_PROJECT_URL` | URL (`https://github.com/{owner}/{repo}`) donde `github-proyect-tracking` va a crear el Issue de seguimiento de esta ejecución. |
237
+
238
+ Campos opcionales, con default vacío (no bloquean `CONFIG_READY`):
239
+
240
+ | Campo | Qué es |
241
+ |---|---|
242
+ | `EXTRA_COMPONENTS` | Componentes a incluir además de los base (ver "Componentes base vs. opcionales" abajo), separados por `;`. Vacío por defecto. |
243
+ | `DNS_DOMAIN` | Si `sql_postgres` usa `dns_domain_name`, el dominio real que `NEW_ENV` usa. Vacío por defecto — el skill genera un valor por patrón marcado con `[WARN]` para confirmar. |
244
+
245
+ Todo lo demás se autodetecta y queda ahí para revisión, no para
246
+ llenarlo desde cero. El `02_print_config.sh` también corre un chequeo de
247
+ salud ("doctor") sobre `SOURCE_ENV` antes de mostrar el config — avisa si
248
+ le falta algo que el resto de `live/` ya tiene (ver
249
+ `lessons-learned.md`, sección C).
250
+
251
+ ### Componentes base vs. opcionales
252
+
253
+ El build solo incluye, por defecto, los componentes que existen en
254
+ **todos** los entornos reales de `live/` (la intersección real, calculada
255
+ en el momento — no una lista hardcodeada). Un componente que `SOURCE_ENV`
256
+ tenga pero que no sea base (`cloud_armor`, `secrets`, etc.) queda
257
+ excluido, siguiendo la guía de experiencia (§1.2: "no incluir salvo
258
+ pedido explícito"). Para incluirlo de todas formas, agrégalo a
259
+ `EXTRA_COMPONENTS` en el config y vuelve a correr la construcción.
260
+
261
+ ## Ejecutar los scripts manualmente (sin el agente)
262
+
263
+ Cada script es independiente y se puede correr a mano, desde la raíz del
264
+ repo destino:
265
+
266
+ ```bash
267
+ S=.claude/skills/kcreate-scaffolding-gcp-script/scripts
268
+
269
+ $S/01_init_config.sh boletera-qa xoloshop-prod # pre requisitos
270
+ # ... editar los campos __PENDIENTE__ del .config ...
271
+ $S/01_init_config.sh boletera-qa xoloshop-prod # confirma CONFIG_READY
272
+ $S/02_print_config.sh xoloshop-prod # revisar antes de construir
273
+
274
+ $S/10_build_components.sh xoloshop-prod # construcción
275
+
276
+ $S/20_validate_file_parity.sh boletera-qa xoloshop-prod
277
+ $S/21_validate_project_pinning.sh xoloshop-prod
278
+ ```
279
+
280
+ Cada script termina con un mensaje de una sola línea y un código de salida
281
+ acorde — pensado para scripting, no solo para lectura humana:
282
+
283
+ | Script | `0` | `2` | `1` | `3` |
284
+ |---|---|---|---|---|
285
+ | `install.sh` | skill instalado/actualizado | — | no se instaló nada (ya existía, sin `--force`) o argumento inválido | — |
286
+ | `npm/bin/cli.js install` | skill instalado/actualizado | argumento/flag inválido o paquete corrupto | no se instaló nada (ya existía, sin `--force`) o destino no es repo git | — |
287
+ | `uninstall.sh` | desinstalado (o no estaba) | — | argumento inválido / destino no es repo git | — |
288
+ | `npm/bin/cli.js uninstall` | desinstalado (o no estaba) | argumento/flag inválido | destino no es repo git | — |
289
+ | `npm/bin/cli.js doctor` | entorno listo | argumento/flag inválido | falta algún requisito (bash/git/python3/curl) | — |
290
+ | `01_init_config.sh` | `CONFIG_READY` | `CONFIG_PENDING` (faltan campos) | error de validación | — |
291
+ | `02_print_config.sh` | config impreso | — | falta config / `NEW_ENV` | — |
292
+ | `10_build_components.sh` | `BUILD_OK: <ruta>` | — | `BUILD_FAILED: <paso> - <detalle>` | — |
293
+ | `20_validate_file_parity.sh` | `FILE_PARITY_OK: <n>` | — | `FILE_PARITY_MISMATCH` | — |
294
+ | `21_validate_project_pinning.sh` | `PROJECT_PINNING_OK: <n>` | — | `PROJECT_PINNING_FAILED` | — |
295
+ | `run_tracking.sh` | comando OK | — | error de tracking | tracking no instalado |
296
+
297
+ `2` no es un error: es la señal de "faltan datos, llénalos y vuelve a correr
298
+ el mismo comando".
299
+
300
+ ## Estructura de este repo
301
+
302
+ ```
303
+ KCreateScaffoldingGCPScripts/
304
+ ├── README.md / AGENT.md / CONTRIBUTING.md / CHANGELOG.md
305
+ ├── DeployNPM.md # manual para publicar el paquete en npm
306
+ ├── IDEA.md # especificación de origen del skill
307
+ ├── CreateScriptsNewGCPProjectInstructions.md # guía manual de referencia (base de experiencia)
308
+ ├── LICENSE # MIT
309
+ ├── .gitignore
310
+ ├── install.sh / uninstall.sh # instalan/quitan el skill de un repo destino
311
+ ├── lib/common.sh # helpers de install.sh/uninstall.sh
312
+ ├── npm/ # instalador npx (mismo contrato que install.sh)
313
+ │ ├── package.json # bin: kcreate-scaffolding-gcp-script
314
+ │ └── bin/{cli.js,build.js} # cli = instalador; build = prepack (empaqueta skill/ y vendor/)
315
+ ├── vendor/github-proyect-tracking/ # dependencia vendorizada (ver vendor/VENDORED_FROM.md)
316
+ └── kcreate-scaffolding-gcp-script/
317
+ ├── SKILL.md # instrucciones para el agente, por etapa
318
+ ├── references/
319
+ │ └── lessons-learned.md # el "por qué" de cada script/validación
320
+ ├── templates/
321
+ │ └── scaffolding.config.template
322
+ └── scripts/
323
+ ├── lib/common.sh # helpers del skill (CIDR, extracción HCL, etc.)
324
+ ├── 01_init_config.sh # Pre requisitos, paso 1
325
+ ├── 02_print_config.sh # Pre requisitos, paso 2
326
+ ├── 10_build_components.sh # Construcción
327
+ ├── 20_validate_file_parity.sh # Validación 1
328
+ ├── 21_validate_project_pinning.sh # Validación 2
329
+ └── run_tracking.sh # envoltura sobre github-proyect-tracking
330
+ ```
331
+
332
+ ## Limitaciones conocidas
333
+
334
+ - Asume que `NEW_ENV` usa la misma región/zona que `SOURCE_ENV` — no hay
335
+ forma de pedir una región distinta todavía.
336
+ - Sin suite de pruebas automatizada. La verificación es por ejecución real;
337
+ la receta reproducible (install/uninstall de humo y ciclo completo contra
338
+ una copia descartable de un entorno real) está en
339
+ [`CONTRIBUTING.md`](CONTRIBUTING.md#validación-reproducible) y
340
+ [`AGENT.md`](AGENT.md#desarrollo-y-pruebas).
341
+ - El instalador npx **no** puede consumirse como
342
+ `npx github:kronops/KCreateScaffoldingGCPScripts`: npm exige el
343
+ `package.json` en la raíz del repo y aquí vive en `npm/` (no soporta
344
+ subdirectorios en dependencias git). Requiere publicación en el registro
345
+ de npm o un tarball local (`npm pack`).
346
+ - `npm publish` está preparado pero el paquete aún no está publicado en el
347
+ registro; hoy la vía sin clonar el repo es el tarball.
348
+ - El nombre del proyecto (`PROJECT_NAME`, ej. `Xoloshop-Prod`) se infiere de
349
+ `NEW_ENV` con la convención `<App>-<QA|Prod>`; si la app tiene siglas o una
350
+ capitalización no obvia, corrígelo a mano en el config antes de construir.
351
+ - Los componentes incluidos vía `EXTRA_COMPONENTS` (sin manejo dedicado)
352
+ se copian con una sustitución genérica y quedan marcados `[WARN]` para
353
+ revisión manual — no tienen el mismo nivel de automatización que los
354
+ componentes base.
355
+ - `project_iam` requiere siempre una revisión humana (bindings
356
+ específicos del equipo/app de `SOURCE_ENV`) — no es mecanizable sin
357
+ conocer el negocio de la app nueva. Ver `lessons-learned.md` (A10).
358
+ `artifact_registry`, en cambio, ya se resuelve solo incluso cuando
359
+ `SOURCE_ENV` tiene valores genéricos: aprende el patrón de otro
360
+ entorno de `live/` que sí tenga el suyo específico (ver
361
+ `lessons-learned.md`, D7) — solo queda en `[WARN]` manual si **ningún**
362
+ entorno de `live/` tiene uno específico del que aprender.
363
+ - `service_accounts`/`project_iam` pueden copiar (renombradas) entradas
364
+ que son específicas de `SOURCE_ENV` y no corresponden a la app nueva
365
+ (ej. SAs o namespaces de un componente que `SOURCE_ENV` tiene pero
366
+ `NEW_ENV` no construye) — hoy solo se advierte si hay más de 5 service
367
+ accounts, no se filtra cuál sobra.
368
+ - El "doctor" de `02_print_config.sh` compara contra el resto de `live/`
369
+ por mayoría/recencia, no contra una lista de requisitos conocida — no
370
+ detecta un requisito nuevo si NINGÚN entorno de `live/` lo tiene todavía
371
+ (ver `lessons-learned.md`, sección C, nota en el ítem del doctor).
package/bin/build.js ADDED
@@ -0,0 +1,70 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Empaqueta el contenido del skill dentro de npm/ para su distribución
4
+ * (prepack). Se ejecuta automáticamente con `npm pack` / `npm publish`.
5
+ *
6
+ * kcreate-scaffolding-gcp-script/ → npm/skill/
7
+ * vendor/github-proyect-tracking/ → npm/vendor/github-proyect-tracking/
8
+ * README.md, LICENSE → npm/README.md, npm/LICENSE
9
+ *
10
+ * Ninguno de estos artefactos se comitea (ver .gitignore): se recrean en cada
11
+ * prepack, para que el paquete nunca quede desincronizado del repo.
12
+ */
13
+ 'use strict';
14
+
15
+ const fs = require('node:fs');
16
+ const path = require('node:path');
17
+
18
+ const here = path.join(__dirname, '..');
19
+ const root = path.join(here, '..');
20
+ const srcSkill = path.join(root, 'kcreate-scaffolding-gcp-script');
21
+ const srcTracking = path.join(root, 'vendor', 'github-proyect-tracking');
22
+ const dstSkill = path.join(here, 'skill');
23
+ const dstTracking = path.join(here, 'vendor', 'github-proyect-tracking');
24
+
25
+ function fail(msg) {
26
+ console.error(`ERROR: ${msg}`);
27
+ process.exit(1);
28
+ }
29
+
30
+ if (!fs.existsSync(path.join(srcSkill, 'SKILL.md'))) {
31
+ fail(`no se encontró ${srcSkill}/SKILL.md`);
32
+ }
33
+ if (!fs.existsSync(path.join(srcTracking, 'SKILL.md'))) {
34
+ fail(`no se encontró ${srcTracking}/SKILL.md (dependencia vendorizada)`);
35
+ }
36
+
37
+ function clean(dir) {
38
+ for (const e of fs.readdirSync(dir, { withFileTypes: true })) {
39
+ const p = path.join(dir, e.name);
40
+ if (e.isDirectory()) {
41
+ if (e.name === '__pycache__') fs.rmSync(p, { recursive: true, force: true });
42
+ else clean(p);
43
+ } else if (/\.py[co]$/.test(e.name)) {
44
+ fs.rmSync(p, { force: true });
45
+ }
46
+ }
47
+ }
48
+
49
+ function stage(src, dst) {
50
+ fs.rmSync(dst, { recursive: true, force: true });
51
+ fs.cpSync(src, dst, { recursive: true });
52
+ clean(dst);
53
+ }
54
+
55
+ stage(srcSkill, dstSkill);
56
+ stage(srcTracking, dstTracking);
57
+
58
+ // Los modos se preservan tal cual desde el origen (fs.cpSync los copia), igual
59
+ // que `cp -R` en install.sh: el resultado instalado desde el repo debe ser
60
+ // idéntico con los dos instaladores. Ojo: `npm pack`/`npm publish` normaliza
61
+ // los modos del tarball; por eso npm/bin/cli.js vuelve a poner los bits de
62
+ // ejecución al instalar (chmodScripts/addExecBits) — la red de seguridad para
63
+ // el caso del paquete publicado.
64
+
65
+ fs.copyFileSync(path.join(root, 'README.md'), path.join(here, 'README.md'));
66
+ fs.copyFileSync(path.join(root, 'LICENSE'), path.join(here, 'LICENSE'));
67
+
68
+ console.log(`skill → ${dstSkill}`);
69
+ console.log(`tracking → ${dstTracking}`);
70
+ console.log('README.md + LICENSE → npm/');