| name | github-workflow |
| description | Flujo completo de trabajo con GitHub: autenticación, gestión de repos, PR lifecycle, code review, issues, knowledge repo como base de conocimiento persistente, deploy estático en Pages, y recuperación de repos corruptos. |
| version | 1.2.0 |
| author | Hermes Agent |
| tags | ["github","git","workflow","deployment","knowledge-repo","recovery"] |
GitHub Workflow — Guía Completa
Flujo completo de trabajo con GitHub para agentes IA.
Tabla de Contenidos
- Autenticación — Tokens, SSH, gh CLI
- Gestión de Repos — Clone, create, fork, remotes
- PR Lifecycle — Branch, commit, open, CI, merge
- Code Review — Diffs, inline comments, gh CLI
- Issues — Create, triage, label, assign
- Knowledge Repo — Base de conocimiento persistente
- GitHub Pages — Deploy estático
- Repo Recovery — Remote overwritten, force push restore
- Branch Rename + Pages Reconfig — master→main completo
- Environment Protection Rules — Pitfall con deployment_branch_policy
- Deploy Pages para Repo EXISTENTE — Verificar existencia antes de crear
- Deploy Estático desde Cero — Crear repo + push + activar Pages
1. Autenticación
GitHub CLI:
curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg 2>/dev/null
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | tee /etc/apt/sources.list.d/github-cli.list > /dev/null
apt-get update -qq && apt-get install -y -qq gh
Auth con token:
token=$(grep GITHUB_TOKEN /hermes-home/.env | cut -d= -f2-)
GITHUB_TOKEN="" echo "$token" | gh auth login --with-token
2. Gestión de Repos
git clone https://github.com/OWNER/REPO.git
git remote add upstream https://github.com/ORIGINAL/REPO.git
git fetch upstream && git merge upstream/main
3. PR Lifecycle
git checkout -b feature/titulo
git add -A && git commit -m "feat: description"
git push -u origin feature/titulo
gh pr create --title "feat: title" --body "description"
gh pr merge --auto
4. Code Review
gh pr diff 123
gh pr comments 123
gh pr review 123 --approve
gh pr review 123 --comment -b "feedback"
5. Issues
gh issue create --title "Bug: ..." --body "description" --label "bug"
gh issue list --state open
gh issue edit 456 --add-label "priority-high"
6. Knowledge Repo
Usar un repos GitHub como base de conocimiento persistente:
notes/ — Notas con formato YYYY-MM-DD-titulo.md
mastermind/ o skills/ — SKILL.md files
memory/ — Backups de memoria
scripts/ — Automatizaciones
config/ — Configuraciones
Sync: git pull → cp -n mastermind/*.md /hermes-home/skills/mastermind/
7.0 Decidir: GitHub Pages vs NaN
| Criterio | GitHub Pages | NaN.builders |
|---|
| Estático puro (HTML/CSS/JS) | ✅ Ideal — gratis, simple | ❌ Overkill |
| Node.js backend | ❌ No soportado | ✅ Necesario |
| APIs/proxy CORS | ❌ No (usar proxy público) | ✅ Servidor propio |
| Variables de entorno | ❌ No | ✅ Sí |
| Velocidad deploy | 1-2 min (workflow) | 2-5 min (Kaniko) |
| Control total | Limitado | Completo |
Regla: Estáticos puros → GitHub Pages. Todo lo que necesite servidor → NaN.
7. GitHub Pages
7.1 Deploy básico
Activar Pages via API REST (sin gh CLI):
import urllib.request, json
token = ''
data = json.dumps({"build_type": "workflow"}).encode()
req = urllib.request.Request(
'https://api.github.com/repos/OWNER/REPO/pages',
data=data,
headers={
'Authorization': f'token {token}',
'Accept': 'application/vnd.github.v3+json',
'Content-Type': 'application/json'
},
method='POST'
)
resp = urllib.request.urlopen(req)
print(json.loads(resp.read())['html_url'])
Activar con gh CLI:
gh api repos/:owner/:repo/pages -X POST \
-f source.branch=main -f source.path=/
Pitfall: build_type: "workflow" requiere que exista un workflow de GitHub Actions que use actions/deploy-pages@v4. Si el workflow no existe, el deploy falla silenciosamente.
7.1b Deploy ultra-rápido con branch gh-pages (HTML puro, sin build)
Para un HTML estático SIN build step (sin Vite, sin Node.js), el deploy más rápido es usar el branch gh-pages directamente. No requiere workflow de Actions, no requiere esperar a que GitHub Pages "active" el sitio.
Pasos:
git checkout -b gh-pages
git push origin gh-pages
curl -X POST https://api.github.com/repos/OWNER/REPO/pages \
-H "Authorization: token $TOKEN" \
-H "Accept: application/vnd.github.v3+json" \
-d '{"branch":"gh-pages","source":{"branch":"gh-pages","path":"/"}}'
sleep 45
curl -sI https://OWNER.github.io/REPO/ | head -1
Ventajas sobre workflow de Actions:
- Sin necesidad de crear
.github/workflows/pages.yml
- Sin environment protection rules que puedan bloquear
- Sin
actions/deploy-pages@v4 que pueda fallar
- Build más rápido (GitHub Pages construye directamente el branch)
Pitfall: Si Pages ya estaba activado (por un workflow anterior), el POST devuelve 409 ("Pages is already enabled"). En ese caso, el branch gh-pages ya se usa y no hace falta la llamada API.
Pitfall: Si el workflow de Actions existe pero falla, el branch gh-pages sigue siendo una alternativa válida.
7.2 Workflow para sites estáticos
Crear .github/workflows/pages.yml:
name: Desplegar a GitHub Pages
on:
push:
branches: ["master"]
workflow_dispatch:
permissions:
contents: read
pages: write
id-token: write
concurrency:
group: "pages"
cancel-in-progress: false
jobs:
deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/configure-pages@v5
- uses: actions/upload-pages-artifact@v3
with:
path: '.'
- uses: actions/deploy-pages@v4
id: deployment
Pitfall: Para sites estáticos HTML (sin build), crear .nojekyll en la raíz del repo para evitar que GitHub procese con Jekyll.
7.2 Vite + GitHub Pages con Service Worker (patrón crítico)
Cuando usas Vite para build + GH Pages para deploy, hay 4 problemas que se repiten:
7.2.1 Service Worker no se despliega
Vite solo procesa lo que rollup toca. El SW (sw.js) existe en la raíz del repo pero no se copia al dist/ automáticamente.
Fix: Añadir copia manual en postbuild.js:
const swSrc = path.join(__dirname, 'sw.js');
const swDest = path.join(distDir, 'sw.js');
if (fs.existsSync(swSrc)) {
fs.copyFileSync(swSrc, swDest);
}
Asegurar que package.json ejecuta postbuild:
"build": "vite build && node postbuild.js"
7.2.2 Ruta del SW — absoluta vs relativa
❌ navigator.serviceWorker.register('/sw.js') — busca en la raíz del dominio (ntizar.github.io/sw.js), no en el subpath del repo.
✅ navigator.serviceWorker.register('./sw.js') — busca relativo al path del sitio (ntizar.github.io/SistemaElectricoFuturo/sw.js), que es donde realmente está.
7.2.3 STATIC_ASSETS desalineados con el build
El SW típicamente lista assets como /css/app.css, /js/app.js, etc. Pero tras un build de Vite:
- Los CSS pueden ir a
/assets/index-XXXX.css (con hash)
- Los JS IIFE pueden estar en
/js/app.js si se copian con postbuild
- Los CSS legacy pueden no existir si Vite los bundlea
Fix: STATIC_ASSETS del SW debe listar solo archivos que realmente existen en dist/ después del build. Si el postbuild copia JS a dist/js/, las rutas en el SW deben coincidir.
const STATIC_ASSETS = [
'/',
'/index.html',
'/js/app.js',
];
7.2.4 SW cache addAll() → fail silencioso → app rota
Si cache.addAll(STATIC_ASSETS) encuentra un 404 (porque un asset listado no existe), todo el install event falla. El SW nuevo nunca se activa y el navegador sigue usando la caché vieja. Síntoma: fondo blanco, CSS/JS no cargan, hard refresh no funciona.
Diagnóstico: DevTools → Application → Service Workers → ver si el SW nuevo está en estado "waiting" o "errored". Mirar el output de cache.addAll().
Fix (3 pasos obligatorios):
- Eliminar referencias a assets que no existen en
dist/ del STATIC_ASSETS
- Bump CACHE_NAME (ej.
v3.4 → v4.1) para forzar re-caché completo desde cero
- Hard refresh (
Ctrl+Shift+R) o Unregister en DevTools después del deploy
7.3 favicon.ico 404 en GitHub Pages
GitHub Pages busca favicon.ico en la raíz del dominio (ntizar.github.io/favicon.ico), no en el subpath del repo. Si no existe, aparece error 404 en consola.
Fix: Crear favicon.svg en el repo, añadirlo al <head>:
<link rel="icon" type="image/svg+xml" href="favicon.svg">
Y copiarlo al dist/ en el postbuild (igual que el SW).
7.4 CORS proxy para API externas en sitios estáticos
GitHub Pages es hosting estático — no hay backend para hacer proxy. Las APIs que no envían Access-Control-Allow-Origin: * no se pueden llamar directamente desde el navegador.
Patrón: Usar un proxy CORS público como intermediario:
const rawUrl = `https://api-externa.com/data?param=value`;
const proxyUrl = `https://api.allorigins.win/raw?url=${encodeURIComponent(rawUrl)}`;
fetch(proxyUrl)
.then(r => r.text())
.then(text => {
const data = JSON.parse(text);
})
.catch(() => null);
Alternativas de proxy:
https://api.allorigins.win/raw?url=... ✅ probado
https://corsproxy.io/?url=...
https://api.allorigins.win/get?url=... (versión con metadata wrapper)
⚠️ No asumir que el proxy devuelve JSON: allorigins.win devuelve HTML plano a veces. Usar .text() + JSON.parse() para mejorar tolerancia.
7.5 Debugging de errores 404 en GitHub Pages
Cuando un sitio GH Pages muestra fondo blanco o faltan recursos, el flujo de diagnóstico es:
- curl a la página principal →
curl -sI https://user.github.io/repo/ → verificar 200 OK
- curl a cada asset referenciado:
curl -sI https://user.github.io/repo/js/app.js | head -3
curl -sI https://user.github.io/repo/assets/index-XXXX.css | head -3
- Inspeccionar el HTML servido →
curl -s https://user.github.io/repo/ | grep -E '(script src|link.*css|sw\.js|favicon)'
- Buscar rutas absolutas en el HTML:
/css/... en vez de ./css/... o /SistemaElectricoFuturo/css/...
- Verificar Service Worker en DevTools → Application → Service Workers → ver si cache.addAll() está fallando
Causas comunes:
- Ruta absoluta
/js/app.js cuando el sitio está en un subpath → 404
- Vite genera
/assets/index-XXXX.css sin prefijo del subpath → 404
- postbuild.js no copia assets necesarios (SW, favicon, CSS legacy)
- SW cacheado sirve assets viejos que ya no existen → bump CACHE_NAME