Files
Pablo a054c73139 Agrego .github, que contiene los action yaml
No van a funcionar porque son de github actions, pero los subo porque no dejan de ser código fuente que puede reutilizarse, adaptándolo a otro entorno
2026-08-22 19:11:33 -03:00

178 lines
7.5 KiB
YAML

name: Build macOS release
# Compila la app de escritorio para macOS y arma el paquete que consume el
# auto-updater (soma_pro_updater). Corre en un runner macOS de GitHub: un build
# de Mac NO se puede compilar desde Linux ni Windows (necesita Xcode), así que
# esto reemplaza a tener una Mac propia.
#
# Se dispara a mano desde la pestaña Actions ("Run workflow") y elegís a qué
# Supabase apunta el build (prod o dev).
#
# Qué deja:
# - Un .dmg para la PRIMERA instalación (contiene la carpeta SOMA PRO con el
# updater y la app como hermanos + version.json). Sale como artifact.
# - El paquete de actualización (zip del SOMA PRO.app) + manifest.json.
# También como artifact, y si el build es de prod se publica solo al feed
# de GitHub Pages (repo peblo423/soma-pro-releases, carpeta macos/), que es
# de donde el updater baja las nuevas versiones.
#
# Por qué updater + app como hermanos y no una subcarpeta app/ (como Windows):
# en macOS cada .app es un bundle autocontenido, así que el updater y la app
# real conviven en la misma carpeta sin pisarse. Lo espera así updater_service.dart.
#
# Firma / Gatekeeper. El .app sale con firma ad-hoc (sin cuenta de Apple
# Developer, USD 99/año), así que la PRIMERA vez macOS lo bloquea por venir "sin
# verificar". Se destraba una única vez, tras arrastrar la carpeta a Aplicaciones:
# xattr -dr com.apple.quarantine "/Applications/SOMA PRO"
# De ahí en más las actualizaciones son automáticas: el updater las baja por HTTP
# (no quedan en cuarentena) y las aplica con ditto, que preserva permisos y
# symlinks del bundle. La única forma de borrar hasta ese paso inicial es pagar
# Apple Developer y notarizar.
on:
workflow_dispatch:
inputs:
environment:
description: "Entorno / Supabase al que apunta la app"
type: choice
options:
- prod
- dev
default: dev
jobs:
build:
runs-on: macos-latest
steps:
- name: Checkout del repo
uses: actions/checkout@v4
# Barrera contra publicar código de desarrollo en producción: solo master
# puede generar un build de prod. El dropdown sigue permitiendo elegir
# "prod" desde otra rama (útil para compilar y probar el artifact), pero
# el paso "Publicar al feed" ya tiene su propio if, y este step corta
# antes de gastar tiempo compilando si la intención no tiene sentido.
- name: Verificar rama para builds de prod
if: ${{ inputs.environment == 'prod' && github.ref != 'refs/heads/master' }}
run: |
echo "::error::Los builds de prod solo se publican desde master, no desde ${GITHUB_REF#refs/heads/}."
echo "Si querés compilar desde esta rama para probar, elegí 'dev' en el dropdown."
exit 1
# Misma versión que usa Pablo localmente, para que el build sea reproducible.
- name: Instalar Flutter 3.41.6
uses: subosito/flutter-action@v2
with:
flutter-version: 3.41.6
channel: stable
cache: true
- name: Habilitar macOS desktop
run: flutter config --enable-macos-desktop
# --- App principal ---
- name: Dependencias app (pub get)
working-directory: flutter_soma_app
run: flutter pub get
- name: Compilar app release (${{ inputs.environment }})
working-directory: flutter_soma_app
run: flutter build macos --release --dart-define-from-file=config/${{ inputs.environment }}.json
# --- Updater ---
- name: Dependencias updater (pub get)
working-directory: soma_pro_updater
run: flutter pub get
- name: Compilar updater release
working-directory: soma_pro_updater
run: flutter build macos --release
# --- Empaquetado ---
- name: Armar layout, paquete de update y manifest
id: package
run: |
set -euo pipefail
APP="flutter_soma_app/build/macos/Build/Products/Release/SOMA PRO.app"
UPDATER="soma_pro_updater/build/macos/Build/Products/Release/soma_pro_updater.app"
test -d "$APP" || { echo "No se encontró la app en $APP"; exit 1; }
test -d "$UPDATER" || { echo "No se encontró el updater en $UPDATER"; exit 1; }
VERSION=$(grep -m1 '^version:' flutter_soma_app/pubspec.yaml \
| sed 's/version:[[:space:]]*//' | cut -d'+' -f1 | tr -d '[:space:]')
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
echo "Empaquetando SOMA PRO v$VERSION (${{ inputs.environment }})"
# Carpeta de instalación: updater y app como hermanos + version.json.
# ditto (no cp) para preservar permisos y symlinks de cada bundle.
STAGE="release/macos/SOMA PRO"
rm -rf release/macos && mkdir -p "$STAGE"
ditto "$UPDATER" "$STAGE/soma_pro_updater.app"
ditto "$APP" "$STAGE/SOMA PRO.app"
echo "{\"version\": \"$VERSION\"}" > "$STAGE/version.json"
# Paquete de actualización: SOLO el bundle de la app, que es lo que el
# updater baja y extrae sobre la carpeta de instalación. `ditto -c -k`
# preserva permisos y symlinks (un zip común los rompe); --keepParent
# deja el .app como carpeta raíz del zip, tal como el updater lo espera.
mkdir -p out
ZIP="out/soma_pro-macos-$VERSION.zip"
ditto -c -k --keepParent "$APP" "$ZIP"
SHA=$(shasum -a 256 "$ZIP" | cut -d' ' -f1)
# Manifest que consume el updater desde GitHub Pages.
cat > out/manifest.json <<EOF
{
"version": "$VERSION",
"url": "https://peblo423.github.io/soma-pro-releases/macos/soma_pro-macos-$VERSION.zip",
"sha256": "$SHA"
}
EOF
- name: Armar el .dmg (primera instalación)
run: |
set -euo pipefail
STAGING="$(mktemp -d)"
cp -R "release/macos/SOMA PRO" "$STAGING/SOMA PRO"
ln -s /Applications "$STAGING/Applications"
hdiutil create -volname "SOMA PRO" -srcfolder "$STAGING" -ov -format UDZO \
"out/SomaPro-Setup-macos-${{ steps.package.outputs.version }}-${{ inputs.environment }}.dmg"
- name: Subir artifacts
uses: actions/upload-artifact@v4
with:
name: SOMA-${{ inputs.environment }}-macos
path: |
out/*.dmg
out/*.zip
out/manifest.json
if-no-files-found: error
# Publica el paquete de update al feed público SOLO en prod: el feed es
# único (no separa dev/prod), así que un build dev no debe llegarle a Juani.
- name: Publicar al feed (solo prod)
if: ${{ inputs.environment == 'prod' }}
env:
RELEASES_REPO_TOKEN: ${{ secrets.RELEASES_REPO_TOKEN }}
run: |
set -euo pipefail
if [ -z "${RELEASES_REPO_TOKEN:-}" ]; then
echo "Falta el secret RELEASES_REPO_TOKEN (PAT con Contents:write sobre soma-pro-releases)"; exit 1
fi
VERSION="${{ steps.package.outputs.version }}"
git clone --depth 1 \
"https://x-access-token:${RELEASES_REPO_TOKEN}@github.com/peblo423/soma-pro-releases.git" feed
mkdir -p feed/macos
cp "out/soma_pro-macos-$VERSION.zip" feed/macos/
cp "out/manifest.json" feed/macos/manifest.json
cd feed
git config user.name "soma-ci"
git config user.email "ci@soma.local"
git add macos
if git diff --cached --quiet; then
echo "Sin cambios para publicar."
else
git commit -m "macOS release v$VERSION"
git push
fi