Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -81,3 +81,22 @@ jobs:

- name: Validate Ansible
run: make test-ansible

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SPA tests run without a build

High Severity

Generated portal/public/index.html is gitignored, but the portal Jest job and make test never run npm run build. Requests to / and /admin therefore sendFile a missing shell, so CI fails. The same unbuilt public/ is what ISO and Ansible copy onto installed machines.

Additional Locations (2)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 87f9d55. Configure here.

test-frontend:
runs-on: ubuntu-latest
needs: validate
steps:
- uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 20
cache: npm
cache-dependency-path: portal/frontend/package-lock.json

- name: Install frontend dependencies
run: cd portal/frontend && npm ci

- name: Run frontend tests
run: cd portal/frontend && npm test
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ portal/configs/generated/
# Variables Ansible generadas en runtime
ansible/generated/

# Build del frontend React (se regenera con npm run build en portal/frontend)
portal/public/assets/
portal/public/index.html
portal/public/favicon.svg

# Logs
*.log

Expand Down
13 changes: 11 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
# NEUBAT - Makefile
TAG ?= 1.0.0

.PHONY: portal install-deps validate lint test test-smoke test-vm test-bash test-ansible validate-ansible lint-ansible build-iso release
.PHONY: portal install-deps install-deps-frontend build-frontend validate lint test test-smoke test-vm test-bash test-ansible validate-ansible lint-ansible test-frontend build-iso release

install-deps:
cd portal && npm install

portal: install-deps
install-deps-frontend:
cd portal/frontend && npm install

build-frontend: install-deps-frontend
cd portal/frontend && npm run build

portal: build-frontend
cd portal && npm start

validate:
Expand Down Expand Up @@ -48,6 +54,9 @@ lint-ansible:

test-ansible: validate-ansible lint-ansible

test-frontend: install-deps-frontend
cd portal/frontend && npm test

# Construir ISO híbrida con autoinstalación (requiere Docker)
build-iso:
bash scripts/build-iso.sh "$(TAG)"
Expand Down
10 changes: 7 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,11 @@ neubat/
│ ├── routes/install.js # API: creación y entrega de configs, boot iPXE
│ ├── routes/admin.js # API de administración
│ ├── routes/status.js # API: health y listado de instalaciones
│ ├── public/index.html # Frontend responsive (SPA ligera)
│ └── public/admin.html # Panel de administración
│ ├── frontend/ # SPA React + Vite + shadcn/ui
│ │ ├── src/pages/ # HomePage y AdminPage
│ │ ├── src/components/ui/ # Componentes shadcn/ui
│ │ └── package.json
│ └── public/ # Build estático del frontend + wiki.html
├── netboot/
│ ├── ipxe/neubat.ipxe # Menú de arranque por red
│ └── grub/loopback.cfg # Fallback: arranque de ISO desde disco (GRUB loopback)
Expand Down Expand Up @@ -82,7 +85,8 @@ docker compose up -d
O en local con Node.js:

```bash
cd portal
cd portal/frontend && npm install && npm run build
cd ..
npm install
npm start # http://localhost:3000
```
Expand Down
3 changes: 2 additions & 1 deletion docs/ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
| P1 | Endurecer sudoers post-instalación (retirar NOPASSWD) | Dev | 1h | ✅ Hecho (19-sep-2026, automático al final de `30-postinstall.sh`) |
| P2 | Panel de administración web para seguimiento | Frontend | 8h | ✅ Hecho (19-sep-2026) |
| P1 | Publicar release v1.0.0 con ISO híbrida en GitHub | DevOps | 1h | ✅ Hecho (20-sep-2026) |
| P2 | Integración con Ansible para configuración post-instalación | DevOps | 6h | Pendiente |
| P2 | Integración con Ansible para configuración post-instalación | DevOps | 6h | ✅ Hecho (20-sep-2026) |
| P1 | Rediseño GUI-UX con React + shadcn/ui | Frontend | 10h | ✅ Hecho (20-sep-2026) |
| P2 | Soporte de cifrado LUKS en particionado | Dev | 4h | Pendiente |
| P3 | Snapshots btrfs automáticos pre/post actualización | Dev | 3h | Pendiente |

Expand Down
11 changes: 9 additions & 2 deletions portal/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,20 @@ FROM node:20-alpine

WORKDIR /app

# Instalar dependencias primero para aprovechar la caché de capas
# Backend dependencies
COPY portal/package*.json ./portal/
RUN cd /app/portal && npm ci --omit=dev

# Copiar todo el repositorio (portal + scripts + configs)
# Frontend dependencies
COPY portal/frontend/package*.json ./portal/frontend/
RUN cd /app/portal/frontend && npm ci

# Copy full repo
COPY . /app

# Build React SPA into portal/public
RUN cd /app/portal/frontend && npm run build

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Docker copy can clobber frontend modules

Medium Severity

Frontend npm ci runs, then COPY . /app copies the full build context with no .dockerignore. A host portal/frontend/node_modules overwrites the Alpine install, including Vite/Rolldown native binaries, so npm run build can fail on developer machines even though a clean clone succeeds.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 87f9d55. Configure here.


WORKDIR /app/portal

ENV NODE_ENV=production \
Expand Down
24 changes: 24 additions & 0 deletions portal/frontend/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*

node_modules
dist
dist-ssr
*.local

# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
8 changes: 8 additions & 0 deletions portal/frontend/.oxlintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"$schema": "./node_modules/oxlint/configuration_schema.json",
"plugins": ["react", "typescript", "oxc"],
"rules": {
"react/rules-of-hooks": "error",
"react/only-export-components": ["warn", { "allowConstantExport": true }]
}
}
32 changes: 32 additions & 0 deletions portal/frontend/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# React + TypeScript + Vite

This template provides a minimal setup to get React working in Vite with HMR and some Oxlint rules.

Currently, two official plugins are available:

- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Oxc](https://oxc.rs)
- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/)

## React Compiler

The React Compiler is not enabled on this template because of its impact on dev & build performances. To add it, see [this documentation](https://react.dev/learn/react-compiler/installation).

## Expanding the Oxlint configuration

If you are developing a production application, we recommend enabling type-aware lint rules by installing `oxlint-tsgolint` and editing `.oxlintrc.json`:

```json
{
"$schema": "./node_modules/oxlint/configuration_schema.json",
"plugins": ["react", "typescript", "oxc"],
"options": {
"typeAware": true
},
"rules": {
"react/rules-of-hooks": "error",
"react/only-export-components": ["warn", { "allowConstantExport": true }]
}
}
```

See the [Oxlint rules documentation](https://oxc.rs/docs/guide/usage/linter/rules) for the full list of rules and categories.
25 changes: 25 additions & 0 deletions portal/frontend/components.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"$schema": "https://ui.shadcn.com/schema.json",
"style": "new-york",
"rsc": false,
"tsx": true,
"tailwind": {
"config": "",
"css": "src/index.css",
"baseColor": "neutral",
"cssVariables": true,
"prefix": ""
},
"iconLibrary": "lucide",
"rtl": false,
"aliases": {
"components": "@/components",
"utils": "@/lib/utils",
"ui": "@/components/ui",
"lib": "@/lib",
"hooks": "@/hooks"
},
"menuColor": "default",
"menuAccent": "subtle",
"registries": {}
}
12 changes: 12 additions & 0 deletions portal/frontend/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<!doctype html>
<html lang="es">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>NEUBAT — Instalación desatendida de Arch Linux</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
Loading
Loading