Skip to content

ci(mobile): publicar en producción de Play y enviar a revisión de App Store al fusionar - #262

Merged
vgpastor merged 3 commits into
mainfrom
ci/mobile-production-release
Nov 3, 2026
Merged

vgpastor merged 3 commits into
mainfrom
ci/mobile-production-release

Conversation

@vgpastor

@vgpastor vgpastor commented Nov 3, 2026 •

Copy link
Copy Markdown
Contributor

Objetivo

Que fusionar en main una versión nueva de la app (mobile/version.json) la publique sola: en producción en Google Play y enviada a revisión en App Store, sin pasos manuales. La web no se toca: sigue desplegando en Vercel.

Estado de las tiendas (consultado por API, solo lectura, 3-nov-2026)

Tienda Público Pendiente
Google Play production: 1.0.11 (10011) completed. Ficha es-ES y en-US internal: 1.0.12 (10012)
App Store 1.0.11 READY_FOR_SALE (enviada el 24-oct, aprobada) build 1.0.12 (10012) VALID en TestFlight

Las dos apps ya están publicadas, así que no hay ningún primer lanzamiento que decidir y el pipeline puede ir directo a producción.

Cambios

ensure-tags.yml

  • Lanza release-mobile-app.yml sobre el tag (--ref mobile@x.y.z) con android_track=production. Así la versión y las notas salen del commit del tag, no del HEAD de main en ese momento.
  • La condición para lanzar es que la versión no tenga GitHub Release (la crea el job create-release al empezar). Si el disparo falla, basta relanzar el job; una versión ya publicada no se repite.
  • El tag web ya no depende de que los pasos móviles terminen bien.

release-mobile-app.yml

  • El track de Android se define en un solo sitio (prepare.outputs.android_track). Por defecto es production, también si el run viene de un GitHub Release publicado a mano.
  • concurrency: dos runs de la misma versión ya no compiten por subir.
  • check-app-store: si el build number ya está en App Store Connect, no se compila ni se vuelve a subir.
  • ios-submit: genera las notas y llama a .github/scripts/app-store-submit.mjs.
  • Se revisa la salida de altool. Puede salir con código 0 aunque Apple rechace el paquete, y ahora eso pone el run en rojo.
  • promote-android genera también las notas de la versión antes de promover.
  • googleapis se instala sin los scripts del proyecto (prisma generate, husky).
  • Los artefactos del release se buscan también en subcarpetas. Antes el APK/AAB nunca se subía.

google-play-version.mjs

  • check mira primero el track destino y solo da skip si el release está completed.
  • Un error de la API pone el run en rojo. Antes se tragaba con un aviso y el script decidía build.
  • promote descarta el edit también cuando no encuentra la versión.

app-store-submit.mjs (adaptado de vgpastor/sacadiez-app, en su versión de RocStatus#436 y #437)

  1. Comprueba la versión antes de esperar al build. Si ya está en revisión, publicada, sustituida o retirada, no hace nada.
  2. Crea la versión o reutiliza la editable. Solo renombra una versión editable anterior; nunca una preparada a mano para una versión posterior.
  3. Adjunta el build y declara el cifrado exento (solo HTTPS).
  4. Clasificación por edad: el dueño declaró socialMedia=false y socialMediaAgeRestricted=false el 3-nov. La ficha publicada no se puede editar (Apple responde 409, «not editable»), así que el script las escribe en el appInfo editable que aparece con la versión nueva, y solo si siguen sin contestar. Nunca pisa un cambio hecho a mano en App Store Connect.
  5. Rellena «Novedades» en todas las localizaciones (es-ES y en-US).
  6. Envía a revisión. Si un envío antiguo en UNRESOLVED_ISSUES no deja reenviar, lo cancela y abre uno nuevo.
  7. Los errores incluyen meta.associatedErrors, que es donde Apple da el motivo real de un 409.

Errores visibles

Una subida o un envío que falle pone el run en rojo con el mensaje de Google (r0adkll/upload-google-play, o googleapis en check y promote) o el de Apple (salida de altool y respuesta de la API de App Store Connect con sus errores asociados).

Pruebas

  • actionlint sin errores en todos los workflows. node --check correcto en los scripts. prettier --check . en verde.
  • google-play-version.mjs check --target-track production contra Play (solo lectura): 10011 da skip, 10012 da promote desde internal y 10013 da build.
  • app-store-submit.mjs check contra App Store Connect (solo lectura): 1.0.12/10012 da uploaded=true y 1.0.13/10013 da uploaded=false.
  • .github/scripts/test/app-store-submit.mock.mjs contra una API de Apple simulada, con salida 0 en los tres casos:
    • stale: contesta solo socialMedia, cancela el envío viejo y reenvía.
    • other-409: no cancela nada y falla.
    • newer-editable: no renombra la 1.0.14 y falla al crear la versión.
  • No se ha lanzado ningún envío real a producción desde esta PR.

Revisión

Dos revisiones independientes, una de bugs y otra de Clean Code/SOLID, sobre el primer commit. Sus hallazgos están aplicados en el segundo. Lo que no se ha tocado:

  • Unificar --target-track/--to-track y partir funciones del script de Apple: es API ya existente y no cambia el comportamiento.

Pendiente fuera del código

  • 1.0.12 está en main pero no en producción: está en Play internal y en TestFlight, y ya tiene GitHub Release, así que fusionar esta PR no la relanza. Saldrá con el siguiente cambio de versión, o antes si se lanza a mano Release Mobile App sobre mobile@1.0.12.

… on merge

- ensure-tags dispatches the release with android_track=production; a
  published GitHub Release defaults to production too (prepare.outputs.track).
- google-play-version check looks at the target track first, only skips a
  completed release and fails on API errors instead of guessing "build".
- New check-app-store job skips the iOS build when the build number is already
  in App Store Connect; new ios-submit job submits the version for review with
  app-store-submit.mjs (adapted from sacadiez-app / RocStatus).
- altool output is checked: an upload Apple rejects now fails the run.
- Apple errors include meta.associatedErrors, the real reasons of a 409.
@vercel

vercel Bot commented Nov 3, 2026 •

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
dea-map Ready Ready Preview Nov 3, 2026 12:43pm UTC

Request Review

- ensure-tags dispatches the release on the tag (--ref) whenever the version
  has no GitHub Release yet, so a failed dispatch is retried on re-run; the
  web tag step no longer depends on the mobile ones.
- release-mobile-app: concurrency group, android_track output name, release
  notes generated before a Play promote, googleapis installed without the
  project scripts, release assets found in subfolders.
- app-store-submit: answers the age rating questions the owner declared
  (socialMedia / socialMediaAgeRestricted = false) only where still unanswered,
  cancels a stale UNRESOLVED_ISSUES submission and resubmits (from RocStatus),
  checks the version before waiting for the build, treats replaced or removed
  versions as nothing to submit, renames only an older editable version and
  defaults BUNDLE_ID to es.deamap.mobile.
- Mock App Store Connect check for the script (stale / other-409 /
  newer-editable).
- AGENTS.md describes the automatic release flow.
@vgpastor
vgpastor merged commit 8eb194e into main Nov 3, 2026
13 checks passed
@vgpastor
vgpastor deleted the ci/mobile-production-release branch November 3, 2026 17:24

This branch was successfully deployed

1 active deployment
Preview — 0e46e562 Deployed Nov 3, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant