- 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.3.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
1. [Autenticación](#1-autenticación) — Tokens, SSH, gh CLI
2. [Gestión de Repos](#2-gestión-de-repos) — Clone, create, fork, remotes
3. [PR Lifecycle](#3-pr-lifecycle) — Branch, commit, open, CI, merge
4. [Code Review](#4-code-review) — Diffs, inline comments, gh CLI
5. [Issues](#5-issues) — Create, triage, label, assign
6. [Knowledge Repo](#6-knowledge-repo) — Base de conocimiento persistente
7. [GitHub Pages](#7-github-pages) — Deploy estático
8. [Repo Recovery](#8-repo-recovery) — Remote overwritten, force push restore
9. [Branch Rename + Pages Reconfig](#9-branch-rename--github-pages-reconfig) — master→main completo
10. [Environment Protection Rules](#10-github-pages--environment-protection-rules) — Pitfall con deployment_branch_policy
11. [Deploy Pages para Repo EXISTENTE](#11-deploy-pages-para-repo-existente) — **Verificar existencia antes de crear**
12. [Deploy Estático desde Cero](#12-deploy-estático-desde-cero-repo-nuevo--pages) — Crear repo + push + activar Pages
---
## 1. Autenticación
**GitHub CLI:**
```bash
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:**
```bash
token=$(grep GITHUB_TOKEN /hermes-home/.env | cut -d= -f2-)
# ⚠️ GH CLI falla con GITHUB_TOKEN env var set
GITHUB_TOKEN="" echo "$token" | gh auth login --with-token
```
## 2. Gestión de Repos
```bash
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
```bash
git checkout -b feature/titulo
# ... changes ...
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 # auto-merge si CI pasa
```
## 4. Code Review
```bash
gh pr diff 123 # Ver diff
gh pr comments 123 # Ver comentarios
gh pr review 123 --approve # Aprobar
gh pr review 123 --comment -b "feedback" # Comentar
```
## 5. Issues
```bash
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.0b Pitfall: GitHub Pages `legacy` + `/dashboard` path
Cuando GitHub Pages está en modo `legacy` con `source.path: "/"`:
- **Solo acepta** `/` o `/docs` como paths. `/dashboard` devuelve **422**.
- El PUT no cambia el build_type automáticamente — sigue en legacy.
**Solución A — iframe en index.html raíz (fallback inmediato):**
```html
<!DOCTYPE html>
<html lang="es">
<head><meta charset="UTF-8"><title>Título</title></head>
<body>
<iframe src="./dashboard/index.html" style="width:100vw;height:100vh;border:none;margin:0;padding:0;"></iframe>
</body>
</html>
```
Funciona inmediatamente sin cambiar build_type. El workflow de Pages puede seguir existiendo sin conflictos.
**Solución B — Intentar activar workflow primero:**
1. Crear `.github/workflows/pages.yml` con `actions/deploy-pages@v4`
2. Commit + push
3. Esperar 60s, verificar con `curl`
4. Si sigue `errored` → usar iframe como fallback
**Verificar estado de Pages:**
```bash
curl -s https://api.github.com/repos/OWNER/REPO/pages \
-H "Authorization: token $TOKEN" | jq '{build_type, status, source}'
# build_type: "legacy" + status: "errored" = bloqueado con paths nuevos
```
**Pitfalls:**
- El workflow dispatch manual (`POST /actions/workflows/X/dispatches`) devuelve **422** si el workflow NO tiene `workflow_dispatch` en su trigger — no es error de deploy
- `GET /repos/.../pages` muestra `build_type: "legacy"` + `status: "errored"` = bloqueado con paths nuevos
- `POST /repos/.../pages` con `build_type: "workflow"` devuelve **409** si Pages ya está activo
- `PUT /repos/.../pages` con `source.path: "/dashboard"` devuelve **422** si está en legacy mode
## 7. GitHub Pages
### 7.1 Deploy básico
**Activar Pages via API REST (sin gh CLI):**
```python
import urllib.request, json
token = '' # leer de .env
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'])
# → https://OWNER.github.io/REPO/
```
**Activar con gh CLI:**
```bash
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.1a Fix: legacy → workflow via PUT (cuando POST devuelve legacy stuck)
El POST a `/pages` a menudo devuelve `build_type: "legacy"` aunque el repo tenga un workflow de Pages. Legacy puede quedarse en `status: "building"` indefinidamente (probado con HTML de 138KB). **Fix:** hacer PUT para forzar `build_type: "workflow"`:
```bash
# 1. POST activa Pages (devuelve build_type: legacy)
curl -s -X POST https://api.github.com/repos/OWNER/REPO/pages \
-H "Authorization: token $TOKEN" \
-d '{"source":{"branch":"main","path":"/"}}'
# → build_type: "legacy", status: "building"
# 2. PUT cambia a workflow mode (204 = OK)
curl -s -X PUT https://api.github.com/repos/OWNER/REPO/pages \
-H "Authorization: token $TOKEN" \
-H "Content-Type: application/json" \
-d '{"source":{"branch":"main","path":"/"},"build_type":"workflow"}'
# → 204 = success
# 3. Esperar y verificar
sleep 30
curl -s -o /dev/null -w "%{http_code}" https://OWNER.github.io/REPO/
# → 200
```
**Pitfall:** El PUT requiere que el workflow de Pages YA exista en el repo (commit + push antes de activar Pages). Si el workflow no existe, el PUT falla o el deploy falla silenciosamente.
**Secuencia completa correcta para activar Pages en repo estático existente:**
1. Crear `.nojekyll` en raíz
2. Crear `.github/workflows/pages.yml` con `actions/deploy-pages@v4`
3. Commit + push
4. `POST /repos/.../pages` → activa (devuelve legacy)
5. `PUT /repos/.../pages` con `build_type: "workflow"` → corrige
6. Verificar con `curl -sI`
### 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:**
```bash
# 1. Crear branch gh-pages desde main (con el HTML ya en la raíz)
git checkout -b gh-pages
git push origin gh-pages
# 2. Activar Pages via API apuntando a 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":"/"}}'
# 3. Esperar build y verificar
sleep 45
curl -sI https://OWNER.github.io/REPO/ | head -1
# → HTTP/2 200
```
**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`:
```yaml
name: Desplegar a GitHub Pages
on:
push:
branches: ["master"] # o "main"
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.2a Deploy con datos JSON + frontend separados (patrón CIAF-visor)
Cuando el proyecto tiene `frontend/` y `data/` como directorios separados, **no deployes solo `frontend/`** — los fetch a `../data/` fallarán. Solución: copiar datos al directorio de deploy en el workflow.
```yaml
- name: Prepare deployment
run: |
mkdir -p deploy/data
cp -r frontend/* deploy/
cp -r data/reports data/memorias data/train-tracks.geojson data/index.json data/relations.json deploy/data/
- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
path: 'deploy/'
```
Y en el HTML, usar rutas relativas al root: `fetch('data/index.json')` en vez de `fetch('../data/index.json')`.
**Pitfall:** GitHub Pages solo sirve lo que esté en el directorio de deploy. Los directorios no incluidos (como `scripts/`, `pdfs/`) no están accesibles vía URL.
### 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`:
```javascript
// 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:
Auf GitHub ansehen