Compare commits

..
Author SHA1 Message Date
devops e3ab3f7fc0 fix(ci): correr Semgrep nativo (venv) en vez de docker run anidado
Build and Push Frontend / Escaneo de Secretos (Gitleaks) (pull_request) Successful in 22s
Build and Push Frontend / Construir y Subir Imagen (pull_request) Skipped
El runner de Gitea ejecuta cada job dentro de un contenedor propio que
habla con el daemon Docker del host (sibling containers) -- un
`docker run -v "\${{ github.workspace }}:/src"` desde ahí intenta
montar una ruta que solo existe DENTRO del contenedor del job, no en
el host real: "mkdir /workspace: read-only file system". Confirmado en
el run real (job 128, task_id 128) tras el fix del anchor.

Se valida localmente contra docker.gitea.com/runner-images:ubuntu-latest
(la misma imagen del runner real) que python3/pip3 están disponibles.
pip3 install directo falla por paquetes de apt sin metadata compatible
(PyJWT, "RECORD file not found") -- se usa un venv aislado en su lugar,
validado end-to-end con los dos steps extraídos del YAML real.
2026-08-14 23:50:23 -05:00
devops 6773a8085d fix(ci): quitar anchors/aliases YAML de build.yaml, no soportados por Gitea Actions
Build and Push Frontend / Escaneo de Secretos (Gitleaks) (pull_request) Successful in 39s
Build and Push Frontend / Construir y Subir Imagen (pull_request) Skipped
Gitea descartaba el workflow completo en TODOS los eventos (push y
pull_request), desde el primer commit de gitleaks: "unknown on type:
&yaml.Node{...Value:"frontend_paths"...}". El YAML era válido (pyyaml
lo parsea sin problema, resolviendo el alias como cualquier parser
estándar) pero el parser propio de Gitea Actions para el bloque "on:"
no resuelve &anchor/*alias antes de inspeccionar el tipo de nodo.

Confirmado en vivo: tras mergear #19 a main, deploy-docs.yaml corrió
normal (sin anchors) pero build.yaml no generó ningún action_run.

Fix: paths duplicados literalmente entre push: y pull_request:, sin
anchor. Válido con parser YAML + bash -n en los 20 steps.
2026-08-14 23:24:31 -05:00
+57 -21
View File
@@ -1,10 +1,14 @@
name: Build and Push Frontend name: Build and Push Frontend
on: on:
# NOTA: sin anchors/aliases de YAML (&x / *x) a propósito -- el parser
# de workflows de Gitea Actions no los resuelve en el bloque "on:" y
# descarta el archivo completo con "unknown on type" (visto en vivo el
# 2026-08-15). Las dos listas de paths quedan duplicadas literalmente.
push: push:
branches: branches:
- main - main
paths: &frontend_paths paths:
# Código y configuración real del frontend. # Código y configuración real del frontend.
# Los cambios exclusivos de GitOps (frontend.yaml, ingress, patches, etc.) # Los cambios exclusivos de GitOps (frontend.yaml, ingress, patches, etc.)
# no vuelven a construir la imagen. # no vuelven a construir la imagen.
@@ -32,7 +36,28 @@ on:
pull_request: pull_request:
branches: branches:
- main - main
paths: *frontend_paths paths:
- 'workloads/ecommerce/Dockerfile'
- 'workloads/ecommerce/.dockerignore'
- 'workloads/ecommerce/.npmrc'
- 'workloads/ecommerce/package.json'
- 'workloads/ecommerce/package-lock.json'
- 'workloads/ecommerce/next.config.*'
- 'workloads/ecommerce/tsconfig.json'
- 'workloads/ecommerce/tailwind.config.*'
- 'workloads/ecommerce/postcss.config.*'
- 'workloads/ecommerce/eslint.config.*'
- 'workloads/ecommerce/*.js'
- 'workloads/ecommerce/*.mjs'
- 'workloads/ecommerce/*.ts'
- 'workloads/ecommerce/*.tsx'
- 'workloads/ecommerce/app/**'
- 'workloads/ecommerce/src/**'
- 'workloads/ecommerce/components/**'
- 'workloads/ecommerce/lib/**'
- 'workloads/ecommerce/public/**'
- 'workloads/ecommerce/styles/**'
- '.gitea/workflows/build.yaml'
permissions: permissions:
contents: write contents: write
@@ -260,6 +285,27 @@ jobs:
--exit-code 0 \ --exit-code 0 \
"${MANIFEST_FILE}" "${MANIFEST_FILE}"
# Instalado directo con pip (no como container aparte): el runner de
# Gitea ejecuta cada job ya dentro de un contenedor propio que habla
# con el daemon Docker del host (sibling containers) -- un
# `docker run -v "${{ github.workspace }}:/src"` desde acá intenta
# montar una ruta que solo existe DENTRO del contenedor del job, no
# en el host real, y falla con "read-only file system". Evitamos por
# completo el problema corriendo Semgrep nativo, igual que
# gitleaks/trivy/syft/cosign.
# venv en vez de "pip3 install --break-system-packages": la imagen del
# runner ya trae paquetes de Python instalados por apt (ej. PyJWT)
# sin metadata compatible con pip, y pip aborta al intentar
# reemplazarlos ("RECORD file not found"). Un venv aislado evita
# tocar los paquetes del sistema por completo.
- name: Instalar Semgrep
shell: bash
run: |
set -euo pipefail
python3 -m venv /tmp/semgrep-venv
/tmp/semgrep-venv/bin/pip install --quiet "semgrep==1.173.0"
/tmp/semgrep-venv/bin/semgrep --version
# Modo auditoría: sin --error a propósito, Semgrep siempre termina # Modo auditoría: sin --error a propósito, Semgrep siempre termina
# con exit 0 aunque reporte hallazgos. Es la primera vuelta — se # con exit 0 aunque reporte hallazgos. Es la primera vuelta — se
# revisan los resultados en conjunto antes de decidir qué reglas # revisan los resultados en conjunto antes de decidir qué reglas
@@ -268,27 +314,17 @@ jobs:
shell: bash shell: bash
run: | run: |
set -euo pipefail set -euo pipefail
SEMGREP_IMAGE="semgrep/semgrep:1.173.0" /tmp/semgrep-venv/bin/semgrep scan \
--config=p/typescript \
docker run --rm \ --config=p/react \
-v "${{ github.workspace }}:/src" \ --config=p/nextjs \
-w /src \ --config=p/security-audit \
"${SEMGREP_IMAGE}" \ --json \
semgrep scan \ --output=semgrep-report.json \
--config=p/typescript \ "${APP_DIR}"
--config=p/react \
--config=p/nextjs \
--config=p/security-audit \
--json \
--output=semgrep-report.json \
"${APP_DIR}"
echo "=== Resumen Semgrep ===" echo "=== Resumen Semgrep ==="
docker run --rm \ /tmp/semgrep-venv/bin/python -c "
-v "${{ github.workspace }}:/src" \
-w /src \
"${SEMGREP_IMAGE}" \
python3 -c "
import json import json
data = json.load(open('semgrep-report.json')) data = json.load(open('semgrep-report.json'))
results = data.get('results', []) results = data.get('results', [])