{"id":51593035,"url":"https://github.com/theburrowhub/ghss","last_synced_at":"2026-07-11T16:02:02.718Z","repository":{"id":364650770,"uuid":"1268642932","full_name":"theburrowhub/ghss","owner":"theburrowhub","description":"App de escritorio para auditar y sincronizar la configuración de repos de GitHub desde un repo de referencia","archived":false,"fork":false,"pushed_at":"2026-06-13T22:01:01.000Z","size":366,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-13T23:21:19.570Z","etag":null,"topics":["devtools","github","rust","settings","tauri"],"latest_commit_sha":null,"homepage":"https://theburrowhub.github.io/ghss","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/theburrowhub.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-13T19:16:44.000Z","updated_at":"2026-06-13T22:01:00.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/theburrowhub/ghss","commit_stats":null,"previous_names":["theburrowhub/ghss"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/theburrowhub/ghss","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/theburrowhub%2Fghss","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/theburrowhub%2Fghss/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/theburrowhub%2Fghss/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/theburrowhub%2Fghss/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/theburrowhub","download_url":"https://codeload.github.com/theburrowhub/ghss/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/theburrowhub%2Fghss/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35367446,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-11T02:00:05.354Z","response_time":104,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["devtools","github","rust","settings","tauri"],"created_at":"2026-07-11T16:02:02.125Z","updated_at":"2026-07-11T16:02:02.703Z","avatar_url":"https://github.com/theburrowhub.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003cimg src=\"assets/banner.png\" alt=\"ghss — un mapache sincroniza la configuración (Rulesets, Branch protections, GitHub Actions, Repository settings) entre repositorios de GitHub\" width=\"100%\" /\u003e\n\u003c/p\u003e\n\n\u003ch1 align=\"center\"\u003e\n  \u003cimg src=\"assets/logo.png\" alt=\"Logo de ghss: mapache con gafas y escudo de git dentro de un óvalo de GitHub\" width=\"96\" height=\"96\" valign=\"middle\" /\u003e\n  \u0026nbsp;ghss — GitHub Settings Sync\n\u003c/h1\u003e\n\nAplicación de escritorio (macOS / Linux) construida con Tauri 2.x que sincroniza la configuración de GitHub desde un repositorio de referencia hacia uno o varios repositorios destino, con auditoría previa y deselección granular de cada cambio.\n\n---\n\n## ¿Qué es ghss?\n\nghss resuelve un problema habitual en equipos que gestionan múltiples repositorios: mantener la configuración de GitHub consistente entre todos ellos. El flujo es:\n\n1. **Conectar** con tu cuenta de GitHub.\n2. **Elegir un repo de referencia** (el que tiene la configuración canónica).\n3. **Auditar** el resto de repos para ver cuáles difieren y en qué.\n4. **Revisar los diffs** con granularidad por setting antes de aplicar nada.\n5. **Sincronizar** solo lo que elijas, repo a repo, setting a setting.\n\nEl motor de diff y sync vive íntegramente en Rust (puro, sin Tauri), lo que facilita el testing y garantiza que no se aplique ningún cambio sin haberlo calculado antes.\n\n---\n\n## Flujo de uso\n\n```\nAuth → Repos → Auditoría → Pre-sync (diff) → Ejecución\n```\n\n| Pantalla | Qué hace |\n|---|---|\n| **Auth** | Selecciona el método de autenticación y valida el token con GitHub. Muestra login/avatar al autenticar. |\n| **Repos** | Lista todos los repos accesibles (personales + orgs). Marca uno como referencia (estrella) y selecciona destinos (checkbox). Repos sin permiso `admin` son visibles pero no seleccionables. |\n| **Auditoría** | Compara en paralelo todos los repos listados contra la referencia. Muestra badge `✓ en sync` / `✗ N diferencias` por repo, expandible por categoría. Acción rápida: \"seleccionar divergentes como destinos\". |\n| **Pre-sync** | Árbol Categoría → Setting, solo diferencias, formato `destino → referencia`. Checkbox por setting y por categoría (tri-estado). Confirmación con conteo de cambios y repos afectados. |\n| **Ejecución** | Progreso por repo vía eventos Tauri. Errores inline sin abortar el resto. Resumen final: éxitos / warnings / errores. |\n\n---\n\n## Instalación\n\n### macOS\n\n**Homebrew:**\n\n```bash\nbrew install theburrowhub/tap/ghss\nghss\n```\n\nActualizar: `brew upgrade ghss`. La fórmula instala el binario `ghss`, que abre la interfaz al ejecutarlo.\n\n**O descarga directa:** el `.dmg` de la [última release](https://github.com/theburrowhub/ghss/releases/latest) (Apple Silicon e Intel), ábrelo y arrastra **ghss** a Aplicaciones.\n\n### Linux\n\nDescarga de la [última release](https://github.com/theburrowhub/ghss/releases/latest) el `.deb` (Debian/Ubuntu) o el `.AppImage` portable:\n\n```bash\n# Debian / Ubuntu\nsudo dpkg -i ghss_*_amd64.deb\n\n# AppImage (cualquier distro)\nchmod +x ghss_*.AppImage\n./ghss_*.AppImage\n```\n\nRequiere el runtime WebKitGTK (`webkit2gtk-4.1`), presente en la mayoría de escritorios modernos.\n\nDocumentación completa: **https://theburrowhub.github.io/ghss/**\n\n---\n\n## Requisitos (para compilar)\n\n- **Rust** toolchain stable (instalación recomendada: `rustup`)\n- **Node 20+** con npm\n- **Sistema operativo**: macOS o Linux (Windows no soportado en v1)\n- `gh` CLI instalado y autenticado (opcional, pero es el método de auth por defecto)\n\n---\n\n## Comandos\n\n```bash\n# Instalar dependencias de frontend\nnpm install\n\n# Arrancar en modo desarrollo (Vite HMR + Rust compilado en debug)\nnpm run tauri dev\n\n# Compilar para producción (genera binario optimizado + app bundle)\nnpm run tauri build\n\n# Ejecutar suite de tests Rust\ncd src-tauri \u0026\u0026 cargo test\n\n# Ejecutar suite de tests de frontend\nnpm test\n```\n\n---\n\n## Métodos de autenticación\n\nghss soporta tres métodos, seleccionables desde la pantalla de Auth:\n\n### 1. gh CLI (por defecto)\n\nSi tienes `gh auth login` ejecutado en tu máquina, ghss detecta el token automáticamente invocando `gh auth token`. No requiere ninguna configuración adicional.\n\n### 2. PAT guardado en keychain\n\nIntroduce un Personal Access Token de GitHub. ghss lo guarda de forma segura en el keychain del sistema operativo (Keychain en macOS, Secret Service en Linux via `keyring`). No se almacena en disco en texto plano.\n\nEl PAT necesita los scopes: `repo`, `read:org`.\n\n### 3. OAuth Device Flow\n\nRequiere registrar una OAuth App propia en GitHub y proporcionar el **Client ID**. ghss inicia el Device Flow, muestra el código de usuario y la URL de autorización, y sondea hasta obtener el token. Este método no requiere que `gh` CLI esté instalado.\n\nPara registrar la OAuth App: GitHub → Settings → Developer settings → OAuth Apps → New OAuth App. No necesita callback URL (es Device Flow).\n\n---\n\n## Categorías sincronizables\n\n| Categoría | Qué incluye |\n|---|---|\n| **Default branch** | Nombre de la rama por defecto (`default_branch`). Si la rama no existe en el destino, se reporta \"no aplicable\" sin intentar crearla. |\n| **Features** | Wiki, Issues, Projects, Discussions, Allow forking (`has_wiki`, `has_issues`, `has_projects`, `has_discussions`, `allow_forking`) |\n| **Pull Requests** | Estrategias de merge (merge commit, squash, rebase), títulos y mensajes de merge commits, allow auto-merge, delete branch on merge, allow update branch |\n| **Others** | Requerir firma en commits web (`web_commit_signoff_required`) |\n| **Tags** | Rulesets con target `tag` (GitHub migró protected tags a rulesets) |\n| **Rules** | Rulesets con target `branch` (conditions, rules, bypass_actors, enforcement) + branch protection clásica para cada rama protegida que exista en el destino |\n\n### Semántica de Rulesets\n\n- Upsert por nombre: si el destino tiene un ruleset con el mismo nombre → `PUT` (actualizar); si no → `POST` (crear).\n- No se borran rulesets extra del destino (sync aditivo/correctivo, no destructivo).\n- `bypass_actors` con IDs de equipos/apps de la org de referencia que no existan en el destino → se copia el ruleset sin esos actores + warning.\n\n### Semántica de branch protection clásica\n\n- Para cada rama protegida de la referencia que **exista** en el destino: `PUT .../protection` con configuración completa.\n- Ramas que no existen en el destino → \"no aplicable\" + warning.\n\n---\n\n## Limitaciones (sin API pública en v1)\n\nLos siguientes toggles de la UI de GitHub **no se sincronizan** porque GitHub no expone API pública para ellos (o se descartaron en v1). La app los identifica como \"no sincronizable (sin API)\":\n\n- **Sponsorships** — no existe endpoint de escritura\n- **Restrict wiki editing to collaborators** — disponible solo vía GraphQL (descartado en v1)\n- **Allow comments on individual commits** — sin API pública\n- **Auto-close issues with merged linked PRs** — sin API pública\n- **Limit branch/tag updates per push** (push limits) — sin API pública\n- **Include Git LFS objects in archives** — sin API pública\n- **PR creation allowed by** (permisos de Pull Requests en forks) — sin API pública\n\n---\n\n## Verificación manual pendiente\n\nLas siguientes verificaciones requieren un token válido de GitHub y no pueden ejecutarse en entornos sin acceso a `api.github.com`.\n\n**Prerrequisito**: `gh auth login` con una cuenta real de GitHub.\n\n### Checklist de verificación e2e\n\n- [ ] Abrir la app con `npm run tauri dev`\n- [ ] En la pantalla Auth: autenticar con el método gh CLI (o PAT)\n- [ ] Verificar que aparece el login/avatar del usuario\n- [ ] En la pantalla Repos: confirmar que se listan repos personales y de orgs\n- [ ] Marcar un repo de referencia con configuración conocida\n- [ ] Ejecutar auditoría contra al menos un repo destino\n- [ ] Crear un repo de prueba desechable: `gh repo create ghss-test-target --private`\n- [ ] Ejecutar sync contra `ghss-test-target` con algunos settings seleccionados\n- [ ] Verificar en GitHub web que los settings se aplicaron correctamente\n- [ ] Comprobar que la pantalla de Ejecución muestra éxitos/errores correctamente\n- [ ] Limpiar: `gh repo delete ghss-test-target --yes`\n\n\u003e **Nota**: Estos pasos están bloqueados en la verificación automatizada del proyecto porque el token de `gh` CLI disponible en el entorno de CI no tiene acceso válido a `api.github.com`.\n\n---\n\n## Arquitectura interna\n\n```\nghss/\n├── src-tauri/           # Backend Rust\n│   ├── src/\n│   │   ├── github/      # Cliente API GitHub (reqwest): repos, settings, rulesets, branch protection\n│   │   ├── auth/        # gh CLI token, PAT + keyring, device flow\n│   │   ├── model/       # RepoSettingsSnapshot, SettingsDiff, categorías\n│   │   ├── diff/        # Motor de comparación referencia vs destino\n│   │   ├── sync/        # Aplicación de cambios (PATCH repos, upsert rulesets, PUT protection)\n│   │   └── commands.rs  # Comandos Tauri expuestos al frontend\n│   └── tests/           # Unit + integración con wiremock\n└── src/                 # Frontend React + TypeScript\n    ├── views/           # Auth, Repos, Audit, PreSync, Execution\n    ├── components/      # DiffTree, RepoList, CategoryBadge...\n    └── api.ts           # invoke() typed wrappers\n```\n\n---\n\n## Publicación (release + Homebrew)\n\nEl repo lleva dos workflows de GitHub Actions:\n\n- **`pages.yml`** — despliega el sitio `site/` en GitHub Pages en cada push a `main`. Ya activo en https://theburrowhub.github.io/ghss/\n- **`release.yml`** — al hacer push de un tag `vX.Y.Z`:\n  1. Compila la app con `tauri-action` en macOS (arm64 + x86_64) y publica el `.dmg` en la release.\n  2. Empaqueta el binario como `ghss_\u003cversion\u003e_\u003ctarget-triple\u003e.tar.gz` (convención del tap, estilo cargo-dist como `fang`).\n  3. Genera/actualiza `Formula/ghss.rb` en `theburrowhub/homebrew-tap`.\n\n### Configuración previa (una sola vez)\n\nEl paso 3 necesita un secret en el repo `ghss`:\n\n- **`TAP_GITHUB_TOKEN`**: un PAT con permiso de escritura sobre `theburrowhub/homebrew-tap` (mismo nombre de secret que usan `fang`, `go-secret`… en la org).\n\n```bash\ngh secret set TAP_GITHUB_TOKEN --repo theburrowhub/ghss\n```\n\n### Cortar una versión\n\n```bash\ngit tag v0.1.0\ngit push origin v0.1.0\n```\n\n\u003e Nota: el `.dmg` no está firmado/notarizado (requiere credenciales de Apple Developer). En macOS, la primera apertura pide confirmación en Ajustes → Privacidad y seguridad. La instalación vía Homebrew (binario) no tiene esa fricción.\n\n---\n\n## Fuera de alcance (v1)\n\n- Windows\n- Sync de webhooks, secrets, labels, colaboradores, environments\n- Borrado de rulesets/protecciones sobrantes en repos destino\n- Programación/scheduling de syncs automáticos\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftheburrowhub%2Fghss","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftheburrowhub%2Fghss","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftheburrowhub%2Fghss/lists"}