3 Commits

Author SHA1 Message Date
root f152379882 fix(ci): add concurrency guard + PR trigger + workflow_dispatch
CI/CD Pipeline / Build & Deploy (pull_request) Successful in 22s
Apply the same concurrency pattern used in the python-project-template:
- cancel-in-progress: false prevents the shared act_runner from
  cancelling in-progress steps when a new push lands
- pull_request trigger ensures PRs are validated before merge
- workflow_dispatch allows manual re-runs
2026-07-09 15:23:40 +00:00
root d3aed167fa Merge pull request 'docs: personalized README' (#1) from docs/readme into main
CI/CD Pipeline / Build & Deploy (push) Successful in 23s
2026-07-09 17:23:04 +02:00
root 26f26c89f6 docs: personalized README 2026-07-09 15:22:48 +00:00
2 changed files with 169 additions and 30 deletions
+12 -1
View File
@@ -3,9 +3,20 @@ name: CI/CD Pipeline
on: on:
push: push:
branches: [main] branches: [main]
pull_request:
branches: [main]
workflow_dispatch:
# Serialise runs on the shared act_runner: prevents two simultaneous runs from
# cancelling each other's in-progress steps (observed in older portfolio runs).
# See python-project-template-internal/.gitea/workflows/ci.yaml for the same
# pattern with full context (runs 794 and 799).
concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: false
jobs: jobs:
deploy: build:
name: Build & Deploy name: Build & Deploy
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
+156 -28
View File
@@ -1,43 +1,171 @@
# Astro Starter Kit: Minimal # David Aragón — Portfolio
```sh Portfolio personal y blog técnico de David Aragón. Sitio estático construido con Astro 5, donde comparto proyectos en los que estoy trabajando (build in public), posts sobre IoT, desarrollo y decisiones técnicas, y una página de about con mi trayectoria.
npm create astro@latest -- --template minimal
- **URL pública:** https://davidaragon.impresion3d.pro
- **Autor:** David Aragón — de orfebre a fotógrafo a developer
- **Repositorio:** https://gitlab.impresion3d.pro/root/davidaragon-portfolio
## Características
- **Home** con hero, últimos 3 posts del blog, proyectos destacados y CTA de newsletter
- **Blog** (`/blog`) con posts categorizados en `technical`, `business` y `personal`, con RSS en `/rss.xml`
- **Projects** (`/projects`) con proyectos en estados `active`, `development` o `completed`
- **About** (`/about`) con la trayectoria profesional completa
- **Sitemap** autogenerado en `/sitemap-index.xml` por `@astrojs/sitemap`
- **Newsletter** vía formulario en la home (acción `/api/subscribe`)
- **Type-safe content** con Zod schemas en `src/content/config.ts`
- **Búsqueda y SEO**: meta tags, Open Graph y RSS listos para compartir
## Stack técnico
- **Astro 5** — framework de sitios estáticos con islands
- **TypeScript** — tipado estricto en todo el código
- **Tailwind CSS 3** — utility-first CSS con `@tailwindcss/typography` para prose
- **Zod** — validación de frontmatter en content collections
- **RSS** vía `@astrojs/rss`
- **Sitemap** vía `@astrojs/sitemap`
- **Nginx** como servidor estático en el contenedor de producción
- **Docker** multi-stage (Node para build, nginx para servir)
- **CI/CD** con Gitea Actions en `.gitea/workflows/ci-cd.yaml`
- **Deploy** automático a Portainer vía webhook
## Quick start (local)
Requisitos: Node.js >= 18.14.1 (recomendado 20).
```bash
# 1. Instalar dependencias
npm install
# 2. Arrancar dev server con HMR
npm run dev
# -> http://localhost:4321
# 3. Build de producción (genera ./dist/)
npm run build
# 4. Preview local del build
npm run preview
``` ```
> 🧑‍🚀 **Seasoned astronaut?** Delete this file. Have fun! ## Despliegue (producción)
## 🚀 Project Structure El sitio se construye como imagen Docker y se publica en el registry de Gitea. Portainer hace pull y reinicia el contenedor cuando el CI dispara el webhook.
Inside of your Astro project, you'll see the following folders and files: ```bash
# Construir y servir localmente con Docker Compose
docker compose up --build
# -> http://localhost:8080
```text # Producción: pull de la imagen publicada por CI
/ docker compose -f docker-compose.prod.yml up -d
├── public/ # -> http://localhost:3001
├── src/
│ └── pages/
│ └── index.astro
└── package.json
``` ```
Astro looks for `.astro` or `.md` files in the `src/pages/` directory. Each page is exposed as a route based on its file name. La imagen final (`nginx:alpine`) solo contiene los estáticos generados en `./dist/`. Ver `Dockerfile` para detalles del multi-stage.
There's nothing special about `src/components/`, but that's where we like to put any Astro/React/Vue/Svelte/Preact components. ## Cómo añadir contenido
Any static assets, like images, can be placed in the `public/` directory. ### Nuevo post de blog
## 🧞 Commands Crea un archivo Markdown en `src/content/blog/` con nombre `YYYY-MM-DD-slug.md`. El frontmatter debe cumplir el schema de `src/content/config.ts`:
All commands are run from the root of the project, from a terminal: ```markdown
---
title: "Título del post"
description: "Resumen corto para SEO y previews"
publishDate: 2026-07-09
author: "David Aragón" # opcional, default: David Aragón
tags: ["tag1", "tag2"]
category: "technical" # technical | business | personal
featured: false # true para destacar en home
draft: false # true para ocultar del sitio público
image: "/ruta/opcional.jpg" # opcional
---
| Command | Action | # Contenido del post en Markdown
| :------------------------ | :----------------------------------------------- | ```
| `npm install` | Installs dependencies |
| `npm run dev` | Starts local dev server at `localhost:4321` |
| `npm run build` | Build your production site to `./dist/` |
| `npm run preview` | Preview your build locally, before deploying |
| `npm run astro ...` | Run CLI commands like `astro add`, `astro check` |
| `npm run astro -- --help` | Get help using the Astro CLI |
## 👀 Want to learn more? Aparecerá automáticamente en `/blog/<slug>` y, si no es draft, en la home.
Feel free to check [our documentation](https://docs.astro.build) or jump into our [Discord server](https://astro.build/chat). ### Nuevo proyecto
Crea un archivo Markdown en `src/content/projects/` con frontmatter:
```markdown
---
title: "Nombre del proyecto"
description: "Descripción de una línea"
url: "https://proyecto.example.com"
github: "https://github.com/user/repo" # opcional
status: "development" # active | development | completed
tags: ["React", "FastAPI"]
startDate: 2026-07-01
featured: true # true para mostrar en home
image: "/ruta/opcional.jpg" # opcional
---
# Descripción completa del proyecto en Markdown
```
Aparecerá en `/projects/<slug>` y, si `featured: true`, también en la home.
## Estructura del proyecto
```
.
├── astro.config.mjs # Configuración Astro (site, integrations, markdown)
├── tailwind.config.cjs # Tailwind theme y content paths
├── tsconfig.json # TS estricto
├── package.json # Deps y scripts
├── Dockerfile # Multi-stage build (node -> nginx)
├── docker-compose.yml # Local dev/test
├── docker-compose.prod.yml # Producción (pull de registry)
├── nginx.conf # Configuración nginx
├── .gitea/workflows/ # Pipelines CI/CD
│ └── ci-cd.yaml
├── public/ # Assets estáticos servidos tal cual (favicon, david-aragon.jpg, etc.)
└── src/
├── components/
│ ├── layout/ # Header, Footer
│ └── ui/ # Card, Tag
├── content/
│ ├── config.ts # Schemas Zod para blog y projects
│ ├── blog/ # Posts en Markdown
│ └── projects/ # Proyectos en Markdown
├── layouts/ # BaseLayout, BlogLayout, ProjectLayout
├── pages/
│ ├── index.astro # Home
│ ├── about.astro # About
│ ├── blog/ # Index + [slug].astro
│ ├── projects/ # Index + [slug].astro
│ └── rss.xml.ts # Feed RSS (si está generado)
├── styles/ # CSS global
└── utils/ # dateFormat.ts, readingTime.ts
```
## CI/CD
Pipeline definido en `.gitea/workflows/ci-cd.yaml`. Trigger: push a `main`.
1. **Build**: checkout, login en el registry de Gitea, build de la imagen Docker multi-stage
2. **Push**: publica `gitlab.impresion3d.pro/root/davidaragon-portfolio:latest`
3. **Deploy**: el webhook configurado en Portainer hace pull de la nueva imagen y reinicia el contenedor
Secrets necesarios en el repo (Settings → Secrets):
- `DOCKER_USERNAME` — usuario del registry (normalmente `root`)
- `DOCKER_PASSWORD` — token personal con permisos de registry
Ver `CI-CD-SETUP.md` para instrucciones detalladas de Portainer y registro de runners.
## Licencia
Código del sitio: ver `LICENSE` si existe en el repo. El contenido (posts y proyectos) es © David Aragón.
## Créditos
- Construido con [Astro](https://astro.build)
- Estilado con [Tailwind CSS](https://tailwindcss.com)
- Hospedado en infraestructura propia (Gitea + Portainer)