Skip to content

ci(macos): make notarization resumable from signed checkpoints - #219

Merged
egdev6 merged 3 commits into
mainfrom
fix/118-resumable-macos-notarization
Oct 30, 2026
Merged

egdev6 merged 3 commits into
mainfrom
fix/118-resumable-macos-notarization

Conversation

@egdev6

@egdev6 egdev6 commented Oct 30, 2026

Copy link
Copy Markdown
Owner

Related issue / Issue relacionada

Refs #118 (sin cierre automático).
ODD: corrección del flujo de distribución macOS aprobado, para evitar perder el bundle cuando Apple tarda más que el runner. La primera apertura real con cuarentena de #118 sigue pendiente.

Scope / Alcance

  • El productor firma sin activar la notarización automática de Tauri, guarda el DMG firmado y un manifiesto en un checkpoint inmutable antes de contactar con Apple, envía una sola vez sin esperar y conserva el UUID en un recibo separado.
  • El workflow manual de reanudación recupera esos mismos bytes, autentica run/attempt/artifacts y sus hashes, consulta el UUID y exige aceptación vinculada al hash del DMG antes de grapar el ticket y verificarlo. No recompila ni vuelve a firmar.
  • La publicación es un job separado, requiere publish: true y Environment protegido; revalida la release, no sobrescribe assets y conserva el rollback por ID propio. In Progress no publica ni reenvía.

Exclusiones: no cambios de versión, Windows/updater, claves, políticas del Environment, ni ejecución de firma/notarización/publicación. Esta PR no autoriza lanzar ninguno de los workflows. Los intentos antiguos sin checkpoint no pueden recuperarse con este flujo: el primer uso necesita una compilación y envío nuevos.

Carga de revisión: 23 archivos, +2045/-554 (2599 líneas tocadas). El mantenedor eligió explícitamente una entrega única tras conocer el tamaño; se mantienen pruebas y documentación completas, sin recortar para ajustarse al umbral orientativo.

Tipo: mantenimiento/tooling (type:chore).

Archivos Cambio
.github/{workflows,security-drafts}/macos-release.yml Productor con checkpoint, envío sin espera y recibo
.github/{workflows,security-drafts}/macos-release-resume.yml Recuperación, verificación y publicación explícita
scripts/macos-notary-{checkpoint,submit,artifact}*.mjs Manifiesto, UUID, provenance y validación fatal del ZIP
scripts/macos-release-resume*.mjs Gates de estado/hash, publicación y pruebas
scripts/verify-macos-bundle{,.test}.mjs Verificación de app contenida, montaje readonly y cleanup
scripts/macos-release-workflow.test.mjs, package.json Contratos estrictos y conexión de pruebas
docs/build-macos.md, docs/code-signing{,.en}.md Uso, recuperación, retención de 14 días y límites

Coordination / Coordinación

  • For ODD: issue/PR assignees and overlapping work checked; claim verified, or explicit maintainer coordination linked.
  • Para ODD: asignaciones y solapamientos revisados; toma verificada o acuerdo explícito del mantenedor enlazado.

Contribuidor: @egdev6.
Evidencia de coordinación: #118 está abierta, status:approved y asignada a @egdev6; implementación y PR solicitadas por el mantenedor. Sin PR abierta solapada en la consulta previa. Base local y remota comprobadas en 9e98d57193bbc5d216abddb0aa46ba90d8a0614f antes de crear el commit.

Acceptance and validation / Aceptación y validación

  • Criterios cumplidos: checkpoint previo a Apple; no espera ni retries de submit; referencia durable de UUID; artefactos autenticados por run/attempt/ID y digest ZIP fatal antes de extracción por allowlist; manifiesto/recibo estrictos; Accepted exige UUID y hash del DMG original en el log; pendiente/rechazado no publican; solo grapa el DMG retenido; verifica firma, autoridad/team, metadata/ARM64, ticket y Gatekeeper; publicación opt-in sin overwrite y con rollback solo de asset propio.
  • Se distinguen tres hashes: ZIP del artifact, DMG original enviado a Apple y DMG final con ticket. Los secretos están limitados a steps y al Environment de main; no se incluyen en artifacts. contents: write solo en el job de publicación.
  • Comprobaciones ejecutadas:
    • TDD con RED/GREEN y triangulación: módulos ausentes, rechazo de nombres ZIP truncados por NUL y diagnóstico seguro de rollback.
    • npm test: exit 0, 785 Vitest + 296 Node.
    • npm run typecheck: exit 0.
    • git diff --check y git diff --cached --check: exit 0.
    • Verificador independiente: 55 pruebas focalizadas, exit 0; sin defectos confirmados bajo el modelo de confianza en main y el Environment protegido.
    • Ambos pares draft/workflow idénticos, con contratos completos normalizados LF/CRLF y rechazo de mutaciones.
    • Revisión nativa de seguridad, resiliencia, claridad y fiabilidad: aprobada y reconocida, sin corrección requerida. Avisos no bloqueantes para seguimiento separado: R3-001 en scripts/macos-release-resume.mjs:63–74 y R4-large-artifact-extraction en scripts/macos-notary-artifact.mjs:160–162.
  • Comprobaciones no ejecutadas y motivo: Apple real, firma/build macOS, contrato real de log.sha256, servicio real de artifacts, montaje DMG, Gatekeeper, Windows nativo y primera apertura con cuarentena. Los tests usan fixtures/procesos/API simulados; una discrepancia de UUID/hash o ausencia del campo esperado bloquea la publicación. Shellcheck dedicado no ejecutado; no se añaden scripts shell independientes. Skills: no aplica.
  • Límites de política: la reanudación compara el YAML del productor con el aprobado, no cada helper histórico; exige SHA de un ancestro de main y run propio/manual/protegido. La comprobación de ancestros usa el snapshot origin/main del checkout. Ninguna de estas limitaciones acreditó un bypass externo en la revisión.
  • Bloqueos pendientes: ninguno confirmado para revisar e integrar la configuración. La validación funcional real requiere ejecuciones posteriores autorizadas; no se afirma que ya exista un DMG notarizado y publicado.

Una PR abierta no implica integración. Release, secretos y firma requieren autorización separada.

@egdev6 egdev6 added the type:chore Maintenance, release infrastructure and tooling label Oct 30, 2026
@egdev6
egdev6 merged commit f3897bc into main Oct 30, 2026
5 checks passed
@egdev6
egdev6 deleted the fix/118-resumable-macos-notarization branch October 30, 2026 13:56
sosan added a commit to sosan/quorb that referenced this pull request Oct 30, 2026
…nes) en feat/wsl-adapter

Trae a la rama de la PR el main vigente de egdev6/quorb (f3897bc, incluye
egdev6#207 y egdev6#219). docs/i18n-inventory.md se regenera desde el árbol fusionado
en un commit aparte para que el header refleje el head real.

Co-Authored-By: Claude Code <noreply@anthropic.com>
sosan added a commit to sosan/quorb that referenced this pull request Oct 30, 2026
1. shell_strategy no confunde error WSL con ausencia de Bash:
   `control_raw` devuelve el output crudo, así que se clasifica con
   `errors::classify`: si la salida contiene un token WSL reconocido
   (p. ej. WSL_E_DISTRO_NOT_FOUND porque la distro desapareció entre la
   enumeración y la sonda), se propaga el error real en vez de caer a
   `ShPosix` como estrategia válida. El fallback a `ShPosix` queda solo
   para el caso normal `command -v` sin bash (salida vacía, sin token).
   Regresión: shell_strategy_propagates_wsl_distro_loss_not_sh_posix.

2. kill_remote_process no escala tras observar la muerte: si una sonda
   `kill -0` ve el PID muerto, se rompe y NO se vuelve a comprobar ni se
   envía KILL (un `kill -0` posterior podría devolver 0 porque el PID fue
   reutilizado por otro proceso — señalizar al proceso equivocado). La
   identidad de la instancia se protege observando la desaparición, no
   volviendo a preguntar por el número. Test determinista
   case_disappears_then_reappears: PID que desaparece y reaparece con
   otra identidad → no recibe KILL.

3. session_path usa semántica del GUEST (POSIX), no del host Windows:
   `Path::is_absolute()` en Windows devuelve false para `/home/u/...` y
   true para `C:\...`, justo al revés del guest. Nuevo helper
   `is_guest_absolute` (empieza por `/`) y tests: una ruta Windows
   explícita se rechaza en modo WSL, y `/etc/passwd` como relativa del
   proveedor se rechaza aunque en Windows no sea "absoluta".

docs/i18n-inventory.md regenerado tras integrar main del upstream
(incluye egdev6#207 y egdev6#219) y los cambios de este commit.

Co-Authored-By: Claude Code <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

type:chore Maintenance, release infrastructure and tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant