-
Notifications
You must be signed in to change notification settings - Fork 0
Deploy y mantenimiento
🇬🇧 English first · 🇪🇸 Español más abajo.
"deploy:marca": "npm run build && firebase deploy --only hosting:marca",
"deploy:personal": "npm run build:personal && node scripts/desplegar-personal.mjs"Everything else in package.json is dev, build, build:personal, lint and
preview. There is no CI, no GitHub Action and no deploy hook: publishing is one command
run by hand.
npm install
npm run dev # http://localhost:5173
npm run deploy:marca # build + publishfirebase.json and .firebaserc between them fix the destination:
| Field | Value |
|---|---|
| Firebase project | sales-weather-etl |
| Hosting target | marca |
| Site | proyectos-mindset-code |
| Public directory | dist |
| Rewrite |
** → /index.html
|
The rewrite is what makes a single-page app work on static hosting: any path returns
index.html and React Router resolves it in the browser. The consequence is that
every URL returns 200, including ones that do not exist — a typo in a link does not
show up as a 404 in the logs.
--only hosting:marca is not optional dressing. The Firebase project hosts more than one
site, and a bare firebase deploy would touch what the target excludes.
scripts/desplegar-personal.mjs exists because the destination site's identifier cannot
live in this repository: it is public and belongs to the organisation, and whoever reads
it must not be able to reach the signed portfolio from here. So the script:
- Reads
SITIO_PERSONALfrom.env.personal— gitignored, present on one machine — and exits with a clear message if it is missing. -
Writes
firebase.personal.jsonon the fly, pointing at that site and atdist-personal. That file is gitignored too. - Copies
personal/retrato.jpgintodist-personal/, warning rather than failing if it is not there. - Deploys with
--config firebase.personal.json. - Deletes the temporary config in a
finally, so it disappears whether or not the deploy succeeded.
Point 5 is the one that matters: a failed deploy that left the config behind would leave
the site identifier sitting in the working tree, one git add . away from being
published.
The portrait is copied after the build for the same class of reason. It lives in
personal/ rather than public/ because Vite copies public/ wholesale into the
output, so a portrait there would ship with the brand build — the one that must not carry
a face.
The JSON files are committed, so this is a normal commit:
# 1. Regenerate in the project that owns the data
# (the three .mjs generators live in project-sales-weather-etl)
node generate_churn_json.mjs
# 2. Copy the files across
cp web/public/data/churn/*.json ../project-portfolio/public/data/churn/
# 3. Commit and publish
cd ../project-portfolio
git add public/data && git commit -m "Actualiza los datos de churn"
npm run deploy:marcaNothing automates step 2. See Arquitectura del sitio for which generator produces which folder.
The embedded simulator is copied the same way and has already drifted.
public/demos/revenue/ is a copy of project-revenue-management-web; the copy here
carries a fix to the 7-day chart that the original does not. Copying the original over it
would undo that fix. Back-porting the fix first is the way round it.
npm run devVite serves public/ directly, so changing a JSON needs a browser refresh and no
rebuild. npm run preview serves the built dist/ if you need to check the production
bundle, and npm run lint runs ESLint 9 with the React Hooks and React Refresh plugins.
| Entry | Reason |
|---|---|
.env.personal, personal/, firebase.personal.json
|
everything that identifies or signs the personal variant |
dist/, dist-marca/, dist-personal/, .firebase/
|
build output — the source is the source |
CLAUDE.md, .claude/, agents/, skills/, .engram/
|
local tooling, not part of the site |
Note that plain .env is not on the list: under Vite only VITE_-prefixed variables
reach the bundle, and that file holds the shared build configuration, while anything that
identifies a person goes in .env.personal.
"deploy:marca": "npm run build && firebase deploy --only hosting:marca",
"deploy:personal": "npm run build:personal && node scripts/desplegar-personal.mjs"Lo demás en package.json es dev, build, build:personal, lint y preview. No hay
CI, ni GitHub Action, ni hook de despliegue: publicar es un comando lanzado a mano.
npm install
npm run dev # http://localhost:5173
npm run deploy:marca # compila y publicaEntre firebase.json y .firebaserc queda fijado el destino:
| Campo | Valor |
|---|---|
| Proyecto de Firebase | sales-weather-etl |
| Destino de hosting | marca |
| Sitio | proyectos-mindset-code |
| Directorio público | dist |
| Reescritura |
** → /index.html
|
La reescritura es lo que hace que una aplicación de una sola página funcione sobre hosting
estático: cualquier ruta devuelve index.html y React Router la resuelve en el navegador.
La consecuencia es que todas las URL devuelven 200, también las que no existen — una
errata en un enlace no aparece como un 404 en los registros.
--only hosting:marca no es un adorno. El proyecto de Firebase aloja más de un sitio, y
un firebase deploy a secas tocaría lo que el destino deja fuera.
scripts/desplegar-personal.mjs existe porque el identificador del sitio de destino no
puede vivir en este repositorio: es público y pertenece a la organización, y quien lo lea
no debe poder llegar desde aquí al portafolio firmado. Así que el script:
- Lee
SITIO_PERSONALde.env.personal—en.gitignore, presente en una sola máquina— y sale con un mensaje claro si falta. -
Escribe
firebase.personal.jsonal vuelo, apuntando a ese sitio y adist-personal. Ese fichero también está en.gitignore. - Copia
personal/retrato.jpgadist-personal/, avisando en vez de fallar si no está. - Despliega con
--config firebase.personal.json. - Borra la configuración temporal en un
finally, de modo que desaparece haya salido bien o mal el despliegue.
El punto 5 es el que importa: un despliegue fallido que dejara la configuración atrás
dejaría el identificador del sitio en el árbol de trabajo, a un git add . de publicarse.
El retrato se copia después de compilar por la misma clase de razón. Vive en personal/ y
no en public/ porque Vite copia public/ entera a la salida, así que un retrato ahí se
publicaría también en la compilación de marca — justo la que no debe llevar cara.
Los JSON están commiteados, así que esto es un commit normal:
# 1. Regenerar en el proyecto dueño de los datos
# (los tres generadores .mjs viven en project-sales-weather-etl)
node generate_churn_json.mjs
# 2. Copiar los ficheros
cp web/public/data/churn/*.json ../project-portfolio/public/data/churn/
# 3. Commit y publicación
cd ../project-portfolio
git add public/data && git commit -m "Actualiza los datos de churn"
npm run deploy:marcaEl paso 2 no lo automatiza nada. En Arquitectura del sitio está qué generador produce cada carpeta.
El simulador embebido se copia igual y ya se ha separado del original.
public/demos/revenue/ es una copia de project-revenue-management-web; la copia de aquí
lleva un arreglo del gráfico de 7 días que el original no tiene. Copiar el original encima
desharía ese arreglo. Llevar antes el arreglo al original es la forma de evitarlo.
npm run devVite sirve public/ directamente, así que cambiar un JSON solo pide recargar el navegador,
sin recompilar. npm run preview sirve el dist/ ya compilado si hace falta comprobar el
bundle de producción, y npm run lint pasa ESLint 9 con los plugins de React Hooks y React
Refresh.
| Entrada | Razón |
|---|---|
.env.personal, personal/, firebase.personal.json
|
todo lo que identifica o firma la variante personal |
dist/, dist-marca/, dist-personal/, .firebase/
|
salida de compilación — la fuente es la fuente |
CLAUDE.md, .claude/, agents/, skills/, .engram/
|
herramientas locales, que no son parte del sitio |
Conviene notar que el .env a secas no está en la lista: con Vite solo llegan al
bundle las variables con prefijo VITE_, y ese fichero lleva la configuración de
compilación compartida, mientras que todo lo que identifica a una persona va en
.env.personal.