Keyboard shortcuts

Press or to navigate between chapters

Press ? to show this help

Press Esc to hide this help

CI y Acciones

Cada workflow vive en .github/workflows/. Las secciones a continuación los agrupan por desencadenador: automáticos en eventos de git, o workflows invocados por mantenedores/de asesoramiento mediante workflow_dispatch y programaciones.

Flujos de trabajo automáticos

Puerta de calidad (ci.yml)

Se activa en cada PR dirigido a master y en pushes confiables a master. Job compuesto con múltiples ramas de matriz:

  • fmt: cargo fmt --all -- --check
  • history-guard: obtiene el historial completo y compara el commit en pruebas con origin/master; las solicitudes de extracción usan el github.event.pull_request.head.sha explícito, mientras que los pushes de confianza y las ejecuciones de merge-queue usan github.sha. El guard y su prueba con fixture rechazan un git merge-base vacío, evitando que una segunda raíz injertada colapse git blame después de la fusión
  • lint: cargo clippy --workspace --exclude zeroclaw-desktop --all-targets --features ci-all -- -D warnings, después cargo doc --no-deps --workspace --exclude zeroclaw-desktop (las advertencias de rustdoc son errores fatales mediante .cargo/config.toml build.rustdocflags; desktop se excluye para ajustarse a xtask build_api / docs-deploy y evitar GTK/glib-sys en el ejecutor de lint), y la comprobación de higiene de comentarios
  • build: matriz: x86_64-unknown-linux-gnu, aarch64-apple-darwin, x86_64-pc-windows-msvc
  • check: tres pasadas por el área de trabajo con las advertencias tratadas como errores (excluyendo zeroclaw-desktop): con todas las características; sin características predeterminadas; y con las características predeterminadas y --all-targets, que es la única etapa que compila los destinos de prueba con el conjunto de características predeterminadas
  • check-32bit: i686-unknown-linux-gnu sin características predeterminadas
  • bench: verificación de compilación de los benchmarks
  • prueba: la comprobación independiente del host del protocolo de firmware de scripts/ci/firmware_protocol_gate.sh y cargo nextest run --locked --workspace --exclude zeroclaw-desktop en Linux, incluidos los controles de arquitectura para el aislamiento de escritura de configuración y la cobertura de Fluent (sin cadenas de texto sin procesar destinadas al usuario)
  • parallel-runtime-test: pruebas repetidas de runtime/canal en el mismo proceso desde scripts/ci/parallel_runtime_test_gate.sh, ejecutadas en paralelo con el trabajo de pruebas principal para las rutas de PR relevantes y de forma incondicional en los pushes a master y las ejecuciones de la cola de fusión
  • seguridad: cargo deny check
  • nix-eval: evalúa las aserciones del módulo de NixOS (verificación del flake nixos-module-eval)
  • docs-style: lint de Markdown, comprobación de prosa con raya larga y verificación de enlaces en líneas modificadas mediante scripts/ci/docs_quality_gate.sh y scripts/ci/docs_links_gate.sh

fmt se ejecuta primero como la barrera serial de bajo coste. Todos los demás trabajos declaran needs: [fmt] directa o transitivamente y se despliegan en paralelo una vez que el formateo pasa; CI Required Gate agrega cada resultado. La protección de ramas fija el trabajo de barrera compuesta. Un PR no puede fusionarse hasta que esto esté en verde. La ejecución del push a master mantiene la misma señal de calidad mientras siembra cachés de Rust confiables para ejecuciones posteriores de PR.

Fresh required CI suele ser la evidencia compartida para las superficies de Cargo que realmente ejecuta. Una nueva ejecución local del mismo comando de Cargo en el mismo head, destino y conjunto de características es confianza duplicada, no una prueba más sólida. Antes de pedir Cargo o Clippy adicionales, compara la superficie modificada con los archivos de flujo de trabajo actuales y las comprobaciones reales en el PR. La validación adicional corresponde donde la puerta de entrada requerida no demuestra lo que está bajo revisión:

  • una plataforma recibió comprobaciones de compilación, pero no pruebas;
  • una plataforma, crate o ruta está fuera del trabajo de lint requerido;
  • un cambio de escritorio no activó el flujo de trabajo de escritorio;
  • un objetivo de release está fuera de la matriz de PR y solo está cubierto por los flujos de trabajo release/manual;
  • CI obsoleta, cancelada, omitida o no disponible no es evidencia reciente.

Cuando una definición o importación está condicionada por una feature, compara su predicado cfg con cada consumidor. Valida tanto la configuración habilitada como cada configuración deshabilitada pertinente: una comprobación con la feature habilitada demuestra que el consumidor sigue funcionando, mientras que la comprobación de todo el workspace con no-default-features detecta discrepancias que producen advertencias, como definiciones privadas o importaciones sin usar. Esa comprobación ejecuta cargo check sin --all-targets, por lo que nunca compila los destinos de prueba: un auxiliar condicionado por un test simple cuyos únicos llamadores están detrás de una feature se detecta, en cambio, en la etapa de default-features/all-targets. Las combinaciones de features específicas siguen siendo necesarias cuando ninguna de las dos configuraciones de CI requeridas ejercita el predicado modificado.

Pruebas de plataforma programadas (platform-tests.yml)

Ejecuta cargo nextest run --locked --workspace --exclude zeroclaw-desktop --no-fail-fast en macos-14 y windows-latest después de una comprobación de formato rápida en Linux. La matriz se ejecuta para:

  • solicitudes de incorporación de cambios que modifican el propio platform-tests.yml;
  • ejecuciones manuales; y
  • el horario nocturno de las 03:17 UTC.

Los trabajos usan continue-on-error y no contribuyen a CI Required Gate. Son pruebas de portabilidad, no requisitos para la fusión. Las solicitudes de incorporación de cambios de código normales no inician automáticamente la matriz; los mantenedores pueden iniciarla manualmente para una rama cuando resulte útil disponer de pruebas centradas en una plataforma. El flujo de trabajo no se ejecuta para eventos ordinarios de push o merge_group. Las ejecuciones nocturnas y las iniciadas manualmente en master pueden escribir en cachés de confianza; las ejecuciones de solicitudes de incorporación de cambios no pueden hacerlo. --no-fail-fast mantiene visibles todos los fallos de plataforma en una sola ejecución.

Escaneo diario de avisos (daily-audit.yml)

Ejecuta cargo deny check advisories diariamente a las 09:00 UTC contra el árbol de dependencias. Abre un issue cuando hay hallazgos. No se requiere ninguna acción a menos que se reporte una vulnerabilidad.

Auditoría diaria de npm (daily-npm-audit.yml)

Ejecuta npm audit --audit-level=high diariamente a las 09:23 UTC contra web/package-lock.json. Abre un único issue deduplicado de security + dependencies cuando avisos de npm de alta severidad afecten al lockfile web comprometido.

Escaneo semanal de imágenes con Trivy (trivy-scheduled.yml)

Analiza las imágenes GHCR de dist y default-features publicadas cada sábado y sube los hallazgos de gravedad ALTA/CRÍTICA a la pestaña Security como SARIF. El análisis es de informe prioritario (exit-code: 0 para hallazgos), pero una imagen esperada ausente hace fallar el trabajo antes de la configuración de Trivy, indicando la etiqueta ausente y el flujo de trabajo publicador propietario en el error.

Canary semanal del bucket de Scoop (scoop-bucket-canary.yml)

Prueba el flujo de publicación de Scoop con la versión estable actual cada lunes. Resuelve la etiqueta vX.Y.Z más reciente e invoca pub-scoop.yml con dry_run: true y credential_canary: true, de modo que pone a prueba el SCOOP_BUCKET_TOKEN real contra el bucket real sin escribir nada.

credential_canary es la parte de ese contrato que falla de forma segura: la ausencia de SCOOP_BUCKET_REPO o SCOOP_BUCKET_TOKEN hace que la ejecución falle, y las credenciales configuradas deben llegar a la comprobación de autorización de git push --dry-run. Una ejecución manual genérica de pub-scoop.yml que solo incluya dry_run: true sigue siendo permisiva para la generación del manifiesto y puede omitir esa comprobación cuando las credenciales no están disponibles; no uses el modo genérico como evidencia de verificación de credenciales.

Esto existe porque SCOOP_BUCKET_TOKEN está vinculado a una cuenta: caduca y pierde silenciosamente los permisos de escritura cuando cambia el permiso de colaborador de la identidad propietaria en el bucket. Ambas cosas han ocurrido. Antes del canario, lo único que ponía a prueba la credencial era el trabajo de scoop posterior a la publicación, por lo que un token inutilizado se descubría después de que la versión ya se había generado y anunciado, y el bucket tenía que actualizarse manualmente.

El canario detecta el deterioro de las credenciales. Deliberadamente, no es lo que mantiene el bucket en estado correcto y no está conectado a Release Stable: una credencial inservible del gestor de paquetes nunca debe bloquear ni retrasar una publicación.

Cómo se mantiene correcto el bucket de Scoop

Hoy, el publicador de versiones es el único escritor automatizado:

  1. pub-scoop.yml hace push al publicar. Los usuarios de Scoop ven la nueva versión inmediatamente cuando se completa correctamente. Necesita el SCOOP_BUCKET_TOKEN entre repositorios, que es la parte frágil.
  2. Los mantenedores recuperan los envíos fallidos. Rota o repara el token, envía Scoop Bucket Canary para verificarlo mediante la ruta credential_canary con cierre ante fallos, vuelve a ejecutar el publicador con dry_run: false y confirma que el manifiesto del bucket contiene la versión de lanzamiento.

Se propone un Excavator del lado del bucket en scoop-zeroclaw#1. Una vez que se fusione ese flujo de trabajo, el repositorio del bucket conceda a Actions permisos de lectura/escritura para los flujos de trabajo y una prueba de humo del mantenedor demuestre que realiza un commit con una actualización, puede convertirse en una capa de recuperación independiente de las credenciales. Hasta que se cumplan las tres condiciones, no se debe asumir que un publicador que haya fallado se recuperará automáticamente.

Los bloques checkver y autoupdate ya son fundamentales para la ruta prevista de Excavator. La ruta actual de publicación también usa scripts/release/scoop_metadata.sh para obtener la plantilla de URL de lanzamiento a partir de autoupdate, por lo que ambas rutas comparten un único contrato de manifiesto. No elimines esos bloques ni los quites manualmente de dist/scoop/zeroclaw.json.

Etiquetador de rutas de PR (pr-path-labeler.yml)

Aplica automáticamente etiquetas de ruta y alcance según los archivos modificados. Se ejecuta al abrir el PR, al reabrirlo y con cada actualización enviada a la rama del PR. Dado que sync-labels: true está habilitado, las etiquetas definidas en .github/labeler.yml se recalculan a partir del conjunto actual de archivos del PR.

Este flujo de trabajo actualmente no aplica las etiquetas risk:*, size:*, type:*, de nivel de contribuidor, de estado, de resolución, de inactividad ni de retoma. Si a un PR le falta una etiqueta de ruta/alcance, verifica si las rutas en .github/labeler.yml cubren los cambios.

Dependabot tiene una configuración de etiquetas separada en .github/dependabot.yml para sus propios PRs. Los PRs de actualización de Cargo comienzan con dependencies; los PRs de actualización de GitHub Actions y Docker comienzan con ci y dependencies.

Planificador del panel del proyecto (project-dashboard-plan.yml)

Se ejecuta manualmente para un solo número de issue. Lee el estado y las etiquetas del issue, y luego escribe un resumen de paso solo de informe proponiendo el valor existente de Project Status que mejor se ajusta al issue.

Este flujo de trabajo no se ejecuta automáticamente en eventos de issues, no escribe campos de ProjectV2, no edita issues, no agrega etiquetas, no publica comentarios ni recalcula las etiquetas PR risk:*, size:* o type:*. La mutación en vivo de ProjectV2 o la planificación automática de eventos de issues requiere un mapeo de campos aprobado por separado, una política de desencadenamiento y una credencial con ámbito de proyecto.

Validar el título del PR (pr-title.yml)

Se ejecuta en cada apertura/edición/sincronización de PR. Ejecuta las pruebas unitarias del validador (scripts/check-pr-title.test.sh) y verifica el título del PR contra Conventional Commits (scripts/check-pr-title.sh).

Desplegar documentación de mdBook en Pages (docs-deploy.yml)

Se activa al hacer push de tags (y workflow_dispatch); compila y publica la documentación versionada en la rama gh-pages. Consulte Release Runbook → Versioned documentation deployment para conocer las reglas de versión mínima y de arranque inicial.

Verificación de PR de Imagen Docker (docker-image-pr.yml)

Se ejecuta solo cuando cambian los archivos de contexto de Docker, Compose o release-Docker. Valida la configuración de Compose combinada predeterminada y Alpine y, para los cambios que van más allá de las ediciones exclusivas de Compose, compila las imágenes de prueba rápida predeterminada y Debian precompiladas, además de los Dockerfiles de origen, sin publicarlos. Las imágenes de origen predeterminada y Alpine se compilan para linux/amd64 y linux/arm64; la imagen de origen Debian se compila para linux/amd64. Los carriles independientes de Alpine y Debian para linux/amd64 habilitan plugins-wasm-runtime-only, de modo que sus contextos de compilación demuestran continuamente que el contrato WIT del repositorio está disponible para las compilaciones de origen con plugins habilitados.

La imagen de origen del Containerfile de todas las funcionalidades se construye para linux/amd64 cuando cambia ese archivo o el flujo de trabajo de Docker. Usa un ámbito de caché aislado y no se carga ni se publica. La variante Alpine amd64 ejecuta ambos binarios, inicia la imagen construida mediante la configuración de Compose combinada y comprueba el estado del gateway y las superficies del dashboard. La variante Alpine arm64 solo cubre la compilación y el ensamblado de la imagen. Los cambios que solo afectan a Compose usan una matriz reducida de Alpine amd64 para que sigan probando el contrato de ejecución sin reconstruir imágenes no relacionadas. Todos los trabajos tienen permisos de solo lectura en el repositorio y ningún permiso de escritura en el registro.

Publicación de Docker (docker-publish.yml)

Compila, firma y escanea la matriz generada de cuatro variantes de dev/ci/docker-tags.toml: minimal, default-features, dist y all-features. Una etiqueta v* creada por una persona inicia este flujo de trabajo directamente. Una versión estable iniciada con workflow_dispatch crea su etiqueta con GITHUB_TOKEN, lo que no emite otro evento de push de etiqueta, por lo que release-stable-manual.yml llama a Docker Publish de forma síncrona en la etiqueta de versión inmutable después de que la versión canónica y los trabajos de Docker se completen correctamente.

Esta matriz complementa, sin reemplazar, las imágenes preconstruidas latest, versionadas y debian de la versión estable. Ambas rutas utilizan distintas entradas de compilación y publican etiquetas diferentes.

Lanzamiento de Discord (discord-release.yml)

Se ejecuta después de una versión estable exitosa. Publica las notas de la versión en el Discord de la comunidad.

Lanzamiento de Tweet (tweet-release.yml)

Se ejecuta después de una versión estable exitosa. Publica un tweet de anuncio.

Comprobación semanal de la vigencia de AUR (aur-freshness-check.yml)

Compara la versión de AUR publicada de zeroclawlabs con la versión estable actual de GitHub cada lunes y falla si la versión de AUR está desactualizada.

Publicar en el AUR sigue un modelo de lanzar y olvidar: si pub-aur.yml falla, nadie vuelve a comprobarlo, por lo que el paquete queda desactualizado silenciosamente. Eso es exactamente lo que ocurrió después de v0.8.4. Una ventana de mantenimiento de aur.archlinux.org coincidió con el lanzamiento, el único intento de clonación, sin reintentos, falló con The AUR is down due to maintenance, y el paquete quedó tres semanas desactualizado sin ninguna señal. El publicador ahora permite como máximo una publicación activa que no sea una ejecución en seco y reintenta para superar una breve interrupción; GitHub puede reemplazar una publicación real anterior en cola dentro del mismo grupo de concurrencia, mientras que las ejecuciones en seco usan un grupo independiente. Cada intento vuelve a clonar el estado canónico del paquete y se niega a sustituir una tupla epoch:pkgver-pkgrel más reciente por una más antigua. Un presupuesto de reintentos aún no puede cubrir todos los fallos, por lo que esta comprobación es la última línea de defensa que convierte una omisión silenciosa o una ejecución reemplazada en un caso visible.

Si no se puede acceder a la RPC de AUR, la comprobación emite una advertencia y pasa en lugar de fallar. Una interrupción de AUR es un problema de disponibilidad del servicio ascendente, no de obsolescencia de paquetes, y la próxima ejecución programada vuelve a comprobarlo. La obsolescencia es persistente, por lo que un retraso en la detección es aceptable; una alerta semanal por la ventana de mantenimiento de otra persona, no.

Los documentos se construyen y publican como parte del pipeline de lanzamiento en lugar de en cada push a master. La traducción es un flujo de trabajo solo local para PRs de caché de traducción dedicados, nuevos idiomas y pasadas de traducción de lanzamiento. Los PRs de documentación en inglés de rutina pueden diferir el ruido generado de .po a gran escala. Consulta Docs & Translations para la guía de contribuidores y el Release Runbook para el procedimiento de lanzamiento.

Flujos de trabajo manuales y de asesoramiento

Escaneo mensual de obsoletos (monthly-outdated.yml)

Escaneo mensual programado el día 1 de cada mes a las 09:00 UTC. Ejecuta cargo outdated --workspace en todos los miembros del espacio de trabajo. Abre un issue con la etiqueta dependencies- cuando se encuentran dependencias obsoletas. Permisos: contents: read + issues: write. Una protección contra duplicados evita que se acumulen si el issue anterior sigue abierto.

Primer paso de triaje para un issue nuevo: comprueba si las crates desactualizadas reportadas tienen cambios de versión incompatibles con semver y si la API de la crate consumidora cambió. Si el cambio es trivial (patch/minor), crea una PR corta solo de dependencias. Si la actualización está bloqueada por rupturas de semver, cierra el issue con una nota y el nombre de la crate que bloquea.

Compilación multiplataforma (cross-platform-build-manual.yml)

Activación manual para compilar binarios de lanzamiento en toda la matriz de destinos: Linux x86_64/aarch64 GNU y MUSL más armv7 y arm hard-float, macOS Intel/ARM, Windows x86_64, y aarch64-linux-android (compilado con el NDK). Úsalo para verificar que una rama compila sin errores en destinos no Linux antes de crear la etiqueta.

Cada ejecución también ejecuta de forma independiente una pequeña matriz de pruebas de humo de las herramientas de lanzamiento. Establece release_tools_only cuando solo se necesite esta evidencia; los trabajos web y de compilación de lanzamiento se omiten entonces. En Linux x86_64 alojado por GitHub de confianza, la prueba de humo instala el archivo comprimido de cross con la versión fijada, confirma tanto cross como cross-util y registra cross --version. En Windows x86_64 alojado por GitHub de confianza, utiliza la misma versión de Rust y la misma estructura de rutas de Bash a Cargo que el flujo de trabajo de lanzamiento estable, y después registra tanto cargo-tauri.exe --version como cargo tauri --version. Cada variante registra el commit exacto probado y la arquitectura del ejecutor en el resumen público del trabajo. La prueba de humo utiliza permisos de solo lectura del repositorio y no tiene ningún trabajo de publicación, entorno, secreto ni carga de artefactos.

Las variantes de compilación de MUSL también instalan cross mediante scripts/ci/install_release_tool.sh, que descarga el artefacto exacto de la versión upstream fijada y verifica su SHA-256 antes de instalarlo. El trabajo obligatorio de Repository Structure prueba la asignación compatible entre ejecutor y artefacto, así como el contrato del flujo de trabajo de smoke, sin realizar llamadas de red.

Clippy multiplataforma (cross-platform-clippy.yml)

Cobertura de lint de advisory programada manual y semanalmente en objetivos macOS aarch64 y Windows x86_64. Replica el comando de lint de PR requerido con --target establecido para cada plataforma, pero intencionalmente no se ejecuta en PRs y no forma parte de CI Required Gate.

Clippy requerido de Linux, Clippy multiplataforma informativo y Clippy de Windows específico llaman a scripts/ci/run_clippy.sh. Ese ejecutor se encarga de los formatos de comando admitidos, la propagación del estado de salida de Cargo y los diagnósticos compartidos de duración, caché, recuento de compilaciones y recuento de descargas. Los archivos de flujo de trabajo siguen encargándose de los desencadenadores, ejecutores, cadenas de herramientas, cachés, tiempos de espera y la inclusión en las comprobaciones obligatorias.

Lanzamiento Estable (release-stable-manual.yml)

Activación manual del pipeline de lanzamiento completo. Compila todos los objetivos, crea el GitHub Release, publica las imágenes Docker precompiladas latest, versionadas y debian en GHCR, ejecuta la matriz de variantes Docker generada en la etiqueta de lanzamiento, activa el redespliegue del sitio web e invoca los sub-workflows de distribución (Scoop, AUR, Discord, tweet). Homebrew Core detecta las nuevas versiones a través de su propio servicio autobump. Dos puertas de entorno requieren aprobación de un mantenedor durante la ejecución: github-releases (el job publish) y docker.

Los recursos descargables usan atestaciones Build Level 2 alojadas en GitHub. Los paquetes sin conexión y el material de raíz de confianza se incluyen en un archivo de verificación, y ambos formatos de SBOM se validan mediante sumas de comprobación y se atestiguan antes de crear la versión. Cosign sigue limitado a la firma de imágenes de GHCR.

Consulte el Runbook de versiones para conocer el procedimiento completo.

Las herramientas de compilación utilizadas únicamente en las versiones de lanzamiento no se compilan desde el código fuente en cada ejecución. El flujo de trabajo instala los binarios de lanzamiento fijados de upstream de cross y Tauri CLI mediante scripts/ci/install_release_tool.sh; ese script verifica un SHA-256 mantenido por el repositorio para cada archivo comprimido específico del ejecutor antes de colocar el binario en el directorio bin de Cargo. Para actualizar cualquiera de las herramientas, es necesario actualizar conjuntamente su versión, nombre del recurso y suma de comprobación, y luego ejecutar scripts/ci/install_release_tool.test.sh.

Editores de paquetes

Cada uno se activa en workflow_dispatch con una entrada de versión. También se invocan desde el flujo de trabajo de lanzamiento después de una publicación exitosa.

Flujo de trabajoQué hace
pub-aur.ymlActualiza el PKGBUILD del Repositorio de Usuarios de Arch y lo envía al AUR
pub-crates.ymlEmpaqueta y verifica la versión coordinada del espacio de trabajo y, a continuación, la publica en crates.io en orden de dependencias, tras la barrera del entorno crates-io
pub-scoop.ymlActualiza el manifiesto de Scoop para Windows

El servicio oficial de autobump de Homebrew Core descubre versiones estables de GitHub y abre actualizaciones de fórmulas de forma independiente. No restaures un publicador de Homebrew propiedad del proyecto ni un token de fork; eso duplica la automatización autorizada de Homebrew.

Secrets requeridos

SecretoUtilizado por
AUR_SSH_KEYpub-aur.yml
CARGO_REGISTRY_TOKENSecreto del repositorio que se pasa explícitamente a pub-crates.yml y al que solo hace referencia su trabajo de publicación protegido; v0.8.5 necesita publish-new para zerorelay, zeroclaw-relay-proto y zeroclaw-tls, mientras que las actualizaciones coordinadas posteriores necesitan publish-update
DISCORD_WEBHOOK_URLdiscord-release.yml
TWITTER_ACCESS_TOKEN, TWITTER_ACCESS_TOKEN_SECRET, TWITTER_CONSUMER_API_KEY, TWITTER_CONSUMER_API_SECRET_KEYtweet-release.yml
SCOOP_BUCKET_TOKENpub-scoop.yml, release-stable-manual.yml, scoop-bucket-canary.yml; PAT con permisos específicos limitado a zeroclaw-labs/scoop-zeroclaw con acceso de lectura/escritura a Contents
WEBSITE_REPO_PATrelease-stable-manual.yml (activa el redespliegue del repositorio del sitio web)
GITHUB_TOKEN (automático)Todos los flujos de trabajo que envían commits, abren PRs o publican imágenes en GHCR

Las imágenes de Docker se publican en GHCR mediante el GITHUB_TOKEN automático; no hay ningún token de registro independiente. Guarda CARGO_REGISTRY_TOKEN como secreto del repositorio y asigna únicamente ese secreto con nombre al publicador reutilizable. El flujo de trabajo invocado solo lo referencia en el paso de publicación irreversible, cuyo trabajo requiere aprobación mediante el entorno crates-io; la comprobación previa sin token ni lo referencia ni lo exporta. La comprobación previa empaqueta el mismo commit inmutable de la versión antes de que un aprobador pueda iniciar el trabajo de publicación.

La mayoría de los crates del conjunto de versiones coordinadas ya existen y cumplen los requisitos para la publicación de confianza en crates.io. La versión v0.8.5 además crea zerorelay, zeroclaw-relay-proto y zeroclaw-tls, por lo que su token de arranque debe incluir publish-new. El token de entorno sigue siendo la vía de arranque hasta que cada crate tenga una entrada de publicador de confianza para este flujo de trabajo. Una vez configuradas esas entradas, migra el trabajo para que GitHub intercambie la identidad OIDC por un token de corta duración en lugar de conservar CARGO_REGISTRY_TOKEN.

Actualmente, la organización deshabilita las claves de despliegue en el bucket de Scoop, y el GITHUB_TOKEN automático no puede escribir en otro repositorio. Mantén SCOOP_BUCKET_TOKEN limitado estrictamente al bucket; no reutilices el token de CLI amplio de un responsable. El publicador comprueba el acceso de escritura con git push --dry-run y luego usa el mismo transporte de Git para la actualización real.

Rotación de SCOOP_BUCKET_TOKEN

Como las claves de implementación no están disponibles, esta credencial es un token de acceso personal y, por tanto, tiene dos modos de fallo independientes, que ya han causado problemas en un lanzamiento:

  1. El token caduca. Los PAT de granularidad fina tienen una duración máxima, por lo que esto se repite con una periodicidad fija, independientemente de que cambie o no cualquier otra cosa.
  2. La identidad propietaria pierde el permiso de escritura en el bucket. El token puede seguir siendo válido mientras la cuenta asociada a él solo sea un colaborador con read. Esto produce remote: Permission to zeroclaw-labs/scoop-zeroclaw.git denied to <account> y HTTP 403, no un error de autenticación, por lo que parece un problema de código cuando en realidad es un problema de permisos.

Haz que la cuenta ZeroClaw-Bot sea la propietaria del token, nunca una cuenta personal, para que el proceso de publicación no dependa de las credenciales de un único mantenedor. Para rotarlo:

  1. Como ZeroClaw-Bot, crea un PAT de granularidad fina con Propietario del recurso zeroclaw-labs, Acceso al repositorio limitado al único repositorio zeroclaw-labs/scoop-zeroclaw, y Permisos del repositorio → Contenidos: lectura y escritura. Nada más.
  2. Confirma que la organización aprobó el token. Los PAT de permisos detallados para el propietario de recursos de una organización permanecen pendientes hasta que se aprueban, y un token pendiente se autentica, pero no puede hacer push.
  3. Confirma que ZeroClaw-Bot aún tenga write en el bucket: gh api repos/zeroclaw-labs/scoop-zeroclaw/collaborators/ZeroClaw-Bot/permission --jq '.role_name'. El paso 1 no concede acceso al repositorio; solo delimita lo que puede usar el token. Un token no puede superar los permisos que ya tiene su propietario.
  4. Establece el secreto: gh secret set SCOOP_BUCKET_TOKEN --repo zeroclaw-labs/zeroclaw.
  5. Compruébalo sin tocar el bucket ejecutando Scoop Bucket Canary. Una ejecución correcta demuestra que el nuevo token puede hacer push.

Registra la fecha de caducidad en algún lugar persistente cuando hagas la rotación. El canario detectará un token caducado en el plazo de una semana de todos modos, pero solo después de que ya haya dejado de funcionar.

Propiedad de paquetes de AUR

El paquete propiedad del proyecto es actualmente zeroclawlabs, mantenido por zeroclaw-bot. El paquete con nombre canónico zeroclaw es un paquete de terceros y no puede reclamarse rotando AUR_SSH_KEY. Si ese mantenedor sigue inactivo, sigue el proceso de solicitud de paquetes huérfanos de AUR antes de cambiar pkgname o el destino de clonación del flujo de trabajo. Tras la transferencia de propiedad, coordina el renombrado o la fusión del paquete en un único cambio revisado.

Comportamiento de la caché de compilación

La mayoría de los trabajos con mucho uso de Rust en ci.yml almacenan la caché mediante la acción compuesta local ./.github/actions/rust-cache, que selecciona el backend de caché usando el mismo conmutador CI_USE_BLACKSMITH que selecciona el ejecutor: useblacksmith/rust-cache (disco NVMe persistente de Blacksmith) cuando el trabajo se ejecuta en un ejecutor de Blacksmith, y Swatinem/rust-cache en los demás casos. Cualquier valor del conmutador distinto de true (incluido que no esté definido y cualquier PR de un fork) recurre a Swatinem/rust-cache en ejecutores alojados en GitHub, por lo que la caché nunca se pierde cuando Blacksmith está desactivado. Ambas referencias de acción están incluidas en la acción compuesta independientemente del conmutador, por lo que ambas deben mantenerse en la lista de permitidos. Las etapas de compilación para macOS y Windows siguen usando Swatinem/rust-cache, y los trabajos fmt, nix-eval y docs-style (ninguno de los cuales compila el espacio de trabajo) no usan ninguna caché de Rust. Conviene conocer estos comportamientos al investigar fallos intermitentes relacionados con la caché:

  • Las escrituras en caché son solo para master. save-if está condicionado a github.ref == 'refs/heads/master', por lo que las ejecuciones de PR leen la caché inicializada desde master pero nunca la actualizan. Las ramas de PR no pueden contaminar la caché compartida con artefactos específicos de la rama. El disparador push en master es lo que proporciona al flujo de trabajo una ejecución confiable con escritura en caché después de los merges.
  • El caché se guarda en caso de fallo. Se establece cache-on-failure: true en cada trabajo, por lo que una ejecución parcial aún prepara el caché para el siguiente intento.
  • La caché de compilación de Windows está habilitada. La etapa de compilación de Windows ejecuta la misma acción de caché de Rust fijada que Linux y macOS. Si el comportamiento de la caché de Windows falla de forma intermitente o presenta regresiones, revierta el cambio del flujo de trabajo y documente la evidencia de fallo de restauración/guardado en el issue de la caché.
  • La compilación incremental está desactivada. CARGO_INCREMENTAL: 0 a nivel del flujo de trabajo. Las compilaciones incrementales aumentan el tamaño de la caché y generan artefactos no reproducibles en condiciones parciales de obsolescencia.
  • cargo-deny y cargo-nextest se instalan desde cero en cada ejecución. El trabajo security ejecuta cargo install cargo-deny --locked; el trabajo Linux test y las dos ejecuciones programadas de platform-tests.yml descargan el binario adecuado de cargo-nextest desde get.nexte.st. Ninguna de las dos herramientas se almacena en caché, por lo que cada instalación añade un coste fijo a su trabajo. Cambiar cualquiera de ellas a taiki-e/install-action permitiría almacenarlas en caché, pero esa acción no está actualmente en la lista de permitidos.

Cuando el semáforo se pone en rojo

SíntomaLo primero que debes verificar
Release Stable muere en startup_failure con cero trabajos tras cambiar una referencia uses:Comprueba el resumen de la ejecución y la política de Actions del repositorio. Si GitHub informa de un rechazo de acciones seleccionadas, compara la referencia modificada con la lista de permitidos, añade solo el patrón rechazado, espera a que se propaguen los cambios de configuración y, después, inicia una ejecución nueva. De lo contrario, investiga la definición del flujo de trabajo u otra política del repositorio; startup_failure por sí solo no identifica la causa
Puerta de CI requerida rojoComience con fmt, luego lint, luego test y, por último, build
La validación de la versión fallóLa versión de Cargo.toml no coincide con la entrada del flujo de trabajo, o la etiqueta ya existe
La etapa de compilación de lanzamiento fallóEl registro de trabajo del objetivo específico. Android es experimental y se ejecuta con continue-on-error.
El tiempo de espera de la puerta de entorno se agotóVolver a ejecutar solo el trabajo que ha caducado desde la página de ejecución del flujo de trabajo
El editor de distribución fallóVuelve a ejecutar el subflujo correspondiente manualmente con dry_run: true primero

Acciones permitidas

El repositorio ejecuta Actions en modo selected; solo las acciones incluidas en esta lista de permitidos pueden ejecutarse. La lista de permitidos debe mantenerse restringida; las nuevas acciones de terceros requieren la aprobación explícita de un mantenedor antes de ser agregadas.

Todas las referencias de terceros están fijadas a un SHA de commit completo con un comentario de versión al final; la columna de versión a continuación registra ese comentario.

AcciónUsado enPropósito
actions/checkout (v6.0.2)La mayoría de los flujos de trabajoRepositorio de checkout
actions/cache (v4.2.3, v5.0.5)docker-image-pr.yml, tweet-release.ymlCaché genérica de dependencias y base de datos de Trivy
actions/setup-node (v7.0.0)ci-sbom.yml, ci.yml, cross-platform-build-manual.yml, daily-npm-audit.yml, pub-crates.yml, release-stable-manual.ymlCadena de herramientas de Node para la generación de SBOM de npm, pruebas/auditoría web y compilaciones web/de escritorio
actions/upload-artifact (v7.0.1)release-stable-manual.yml, cross-platform-build-manual.yml, docker-publish.yml, trivy-scheduled.ymlSubir artefactos de compilación y artefactos de transferencia SARIF de Trivy
actions/download-artifact (v8.0.1)release-stable-manual.yml, cross-platform-build-manual.yml, docker-publish.ymlDescargar artefactos de compilación y artefactos de entrega SARIF de Trivy
actions/attest (v4.2.2)release-stable-manual.ymlGenerar procedencia de nivel 2 de compilación alojada en GitHub para activos de lanzamiento
actions/labeler (v6.1.0)pr-path-labeler.ymlAplicar etiquetas de ruta/alcance desde .github/labeler.yml
dtolnay/rust-toolchain (stable, v1)ci.yml, platform-tests.yml, pub-crates.yml, release-stable-manual.yml, cross-platform-build-manual.yml, cross-platform-clippy.yml, daily-audit.yml, docs-deploy.yml, codeql.ymlInstalar la cadena de herramientas de Rust
Swatinem/rust-cache (v2.9.2)ci.yml (ruta alojada en GitHub de ./.github/actions/rust-cache), platform-tests.yml, pub-crates.yml, release-stable-manual.yml, cross-platform-build-manual.yml, cross-platform-clippy.yml, docs-deploy.ymlAlmacenamiento en caché de compilaciones y dependencias de Cargo en ejecutores hospedados en GitHub
useblacksmith/rust-cache (v3.0.1)ci.yml (ruta de Blacksmith de ./.github/actions/rust-cache)Almacenamiento en caché de compilaciones/dependencias de Cargo en el disco persistente de Blacksmith; se selecciona únicamente cuando CI_USE_BLACKSMITH=true
docker/setup-buildx-action (v3.11.1, v4.0.0)release-stable-manual.yml, docker-publish.ymlConfiguración de Docker Buildx
docker/login-action (v3.4.0, v4.1.0)release-stable-manual.yml, docker-publish.yml, trivy-scheduled.ymlAutenticación de GHCR
docker/build-push-action (v6.18.0, v7.1.0)release-stable-manual.yml, docker-publish.ymlConstrucción y envío de imágenes multiplataforma
sigstore/cosign-installer (v3.8.1)release-stable-manual.yml, docker-publish.ymlInstalar cosign para la firma sin clave de imágenes de contenedor de GHCR
anchore/sbom-action (v0.24.0)release-stable-manual.ymlGenera SBOM de SPDX y CycloneDX para cada release
aquasecurity/trivy-action (v0.36.0)docker-image-pr.yml, docker-publish.yml, trivy-scheduled.ymlAnálisis de vulnerabilidades de contenedores solo para informes
github/codeql-action/upload-sarif (v3.36.2)docker-publish.yml, trivy-scheduled.yml, ci-code-analysis.ymlCarga los informes SARIF de Trivy y Semgrep en la pestaña Seguridad
github/codeql-action/init (v3.36.2)codeql.ymlInicializar el análisis de CodeQL (Rust y JS/TS)
github/codeql-action/analyze (v3.36.2)codeql.ymlSubir CodeQL SARIF a la pestaña de Seguridad

El GitHub Release en sí se crea con gh release create dentro del job publish, no con una action de release.

Patrones de lista blanca equivalentes (mantenidos estrechos a propósito):

actions/*
dtolnay/rust-toolchain@*
Swatinem/rust-cache@*
useblacksmith/rust-cache@*
docker/*
sigstore/cosign-installer@*
anchore/sbom-action@*
aquasecurity/trivy-action@*
github/codeql-action/upload-sarif@*
github/codeql-action/init@*
github/codeql-action/analyze@*

Exportar la política efectiva actual:

sh

gh api repos/zeroclaw-labs/zeroclaw/actions/permissions
gh api repos/zeroclaw-labs/zeroclaw/actions/permissions/selected-actions

Cualquier PR que agregue o modifique el origen de una acción uses: debe incluir una nota de impacto de la lista de permitidos en su cuerpo. Evita excepciones amplias con comodines; amplía la lista de permitidos únicamente para acciones faltantes verificadas.

Reglas de mantenimiento

  • Mantén el CI Required Gate determinista y pequeño. Agregar trabajos al gate requiere un argumento de calidad claro.
  • Todas las referencias de acciones de terceros deben estar fijadas a un SHA de commit completo (según la política de lista de permitidos anterior).
  • Mantén ci.yml, dev/ci.sh y .githooks/pre-push alineados. Las comprobaciones compartidas deben residir en scripts/ci/; cada punto de entrada invoca la función auxiliar en lugar de copiar sus comandos. Para la comprobación independiente del protocolo de firmware, el punto de entrada local documentado es ./dev/ci.sh firmware-protocol.
  • Mantén alineados scripts/ci/prepare_docker_context.sh, docker-image-pr.yml y el job de Docker en release-stable-manual.yml para que la validación de PRs ejercite la misma forma de contexto que publica el flujo de trabajo de release.
  • Ejecuta python3 scripts/ci/release_attestation_contract_test.py después de cambiar la atestación de lanzamiento, el checksum, el SBOM o la secuencia del archivo de verificación.
  • El trabajo de control docs-style ejecuta bash scripts/ci/docs_quality_gate.sh (lint de Markdown + comprobación de prosa con raya em) y bash scripts/ci/docs_links_gate.sh (control de enlaces en líneas cambiadas). Ejecuta ambos scripts localmente antes de enviar cambios en la documentación.

Reversión de emergencia

Si la lista de permitidos bloquea una acción crítica durante un incidente:

  1. Establece temporalmente la política de Actions de nuevo en all.
  2. Restaurar la lista blanca selected después de identificar la entrada faltante.
  3. Registra el incidente y el delta final de la lista de permitidos.

Esta es la única ruta justificada hacia el modo all, y nunca debería prolongarse más allá del incidente.