Entrega é parte do produto

O aplicativo não termina quando compila na máquina de desenvolvimento. Uma release profissional precisa ser reproduzível, identificável, assinada, validada e monitorada.

Versionamento e artefatos

Em pubspec.yaml:

version: 1.2.0+42

A parte antes de + comunica a versão ao usuário; o build number identifica uma entrega nas lojas. Gere artefatos com a mesma revisão testada:

flutter build appbundle --release
flutter build ipa --release
flutter build web --release
Artefato flutter build <target> --release

build produz um artefato para o alvo solicitado; --release seleciona otimizações e remove ferramentas de desenvolvimento incompatíveis com distribuição. O comando não publica nem comprova que o aplicativo funciona em produção.

appbundle gera o formato de distribuição Android recomendado para a loja; ipa depende da toolchain e assinatura Apple em macOS; web produz arquivos estáticos para hospedagem. O host do pipeline precisa suportar o alvo.

Registre revisão, versão da toolchain, ambiente, caminho, tamanho e hash do artefato. O arquivo distribuído deve ser exatamente aquele gerado pela revisão validada, não uma reconstrução manual posterior.

Debug, profile e release respondem perguntas diferentes. Debug favorece iteração e asserts; profile permite medir desempenho com instrumentação apropriada; release representa otimização e distribuição. Faça diagnóstico funcional cedo, análise de desempenho em profile e smoke test do artefato release.

Requisitos de assinatura variam por plataforma. Chaves e certificados não pertencem ao repositório nem à saída de logs.

Ambientes e flavors

Desenvolvimento, homologação e produção devem ter endpoints, serviços e identificadores próprios.

final class AppEnvironment {
  const AppEnvironment({required this.name, required this.apiUrl});
  final String name;
  final Uri apiUrl;
}

Valores públicos de configuração podem entrar por --dart-define; segredos reais devem permanecer no backend ou em armazenamento protegido do pipeline. Um segredo incluído no binário do cliente deve ser considerado público.

Pipeline mínimo

name: flutter-ci
on:
  pull_request:
  push:
    branches: [main]

jobs:
  validate:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: subosito/flutter-action@v2
        with:
          channel: stable
          cache: true
      - run: flutter pub get
      - run: dart format --output=none --set-exit-if-changed .
      - run: flutter analyze
      - run: flutter test --coverage
      - run: flutter build web --release

Em produção, fixe versões de actions por referência confiável, proteja ambientes e exija aprovação para distribuição.

Leia o pipeline como uma cadeia de evidências: pub get reconstrói dependências; format e analyze validam consistência estática; test verifica comportamento coberto; build prova que o alvo gera artefato. Cada etapa deve falhar rápido e preservar logs suficientes, sem expor secrets.

Publicação controlada

Antes da loja, prepare descrição, ícones, screenshots, política de privacidade, classificação etária e conta de suporte. Use canais internos e testes fechados antes do rollout público.

Fastlane pode automatizar metadados e envio, mas a automação precisa manter rastreabilidade: versão, commit, ambiente, aprovador e artefato.

Checklist de release

  • Pipeline verde na revisão que será publicada.
  • Versão e notas atualizadas.
  • Assinatura e ambiente confirmados.
  • Testes em dispositivo real e atualização sobre versão anterior.
  • Permissões e política de privacidade revisadas.
  • Crash reporting e métricas identificando a nova versão.
  • Responsável, canal de incidente e plano de contenção definidos.

Aplicativos móveis não têm rollback instantâneo para todos os usuários. Prefira rollout gradual, feature flags seguras e compatibilidade de backend com versões anteriores.

Pós-deploy

Observe crash-free users, falhas de inicialização, erros de API, latência e conversões críticas por versão. Defina limites antes da publicação. Se uma métrica ultrapassar o limite, pause o rollout e siga o plano de resposta.

Prática guiada: construa uma entrega auditável

Continue no Sales Management com o gate do módulo 9 passando. O objetivo é gerar e preservar um artefato de homologação; esta prática não publica em loja nem em produção.

Checkpoint 1 — identifique a release antes de compilar

Atualize pubspec.yaml com uma versão de laboratório, por exemplo 1.0.0+1, e registre a toolchain:

flutter --version
flutter doctor -v
git rev-parse HEAD

Salve as três informações em release-evidence.md. Não avance se o checkout possuir mudanças não compreendidas ou se o gate local estiver vermelho.

Checkpoint 2 — torne o ambiente explícito e tipado

Crie lib/core/config/app_environment.dart:

enum AppEnvironment { development, staging, production }

final class AppConfig {
  AppConfig._({required this.environment, required this.apiUrl});

  final AppEnvironment environment;
  final Uri apiUrl;

  factory AppConfig.fromDefines() {
    const name = String.fromEnvironment('APP_ENV');
    const rawApiUrl = String.fromEnvironment('API_URL');
    final environment = AppEnvironment.values.firstWhere(
      (value) => value.name == name,
      orElse: () => throw StateError('APP_ENV inválido: $name'),
    );
    final apiUrl = Uri.tryParse(rawApiUrl);
    if (apiUrl == null || !apiUrl.hasScheme) {
      throw StateError('API_URL inválida');
    }
    return AppConfig._(environment: environment, apiUrl: apiUrl);
  }
}

Execute homologação com:

flutter run --dart-define=APP_ENV=staging --dart-define=API_URL=https://staging.example.invalid

Endpoints e identificadores públicos podem estar no binário. Senhas, tokens e chaves administrativas não podem: mova-os para o backend ou para secrets usados apenas na etapa que realmente precisa deles.

Checkpoint 3 — gere o artefato local adequado ao host

flutter clean
flutter pub get
dart format --output=none --set-exit-if-changed .
flutter analyze
flutter test
flutter build web --release --dart-define=APP_ENV=staging --dart-define=API_URL=https://staging.example.invalid

No Windows ou Linux com toolchain Android configurada, gere também flutter build appbundle --release .... flutter build ipa exige macOS, Xcode e assinatura Apple; trate-o como uma etapa separada em um runner compatível.

Abra build/web por um servidor HTTP local e faça smoke test de inicialização, navegação, carregamento e falha de API. Abrir index.html diretamente não representa uma hospedagem real.

Checkpoint 4 — calcule identidade e integridade

No PowerShell:

Compress-Archive -Path build/web/* -DestinationPath build/sales-management-web.zip
Get-FileHash build/sales-management-web.zip -Algorithm SHA256
Get-Item build/sales-management-web.zip | Select-Object Name, Length, LastWriteTimeUtc

Acrescente ao release-evidence.md: versão, build number, commit, ambiente, versão Flutter/Dart, alvo, nome, tamanho e SHA-256. O hash permite confirmar que o arquivo aprovado é o mesmo arquivo entregue.

Checkpoint 5 — reproduza o gate no GitHub Actions

Crie .github/workflows/flutter-ci.yml:

name: flutter-ci

on:
  pull_request:
  push:
    branches: [main]

permissions:
  contents: read

jobs:
  validate:
    runs-on: ubuntu-latest
    timeout-minutes: 20
    steps:
      - uses: actions/checkout@v4
      - uses: subosito/flutter-action@v2
        with:
          channel: stable
          cache: true
      - run: flutter pub get
      - run: dart format --output=none --set-exit-if-changed .
      - run: flutter analyze
      - run: flutter test --coverage
      - run: >-
          flutter build web --release
          --dart-define=APP_ENV=staging
          --dart-define=API_URL=https://staging.example.invalid
      - uses: actions/upload-artifact@v4
        with:
          name: sales-management-web
          path: build/web
          if-no-files-found: error

Em um projeto real, revise e fixe actions por referências confiáveis conforme a política da organização. O job de pull request valida; um futuro job de distribuição deve usar ambiente protegido, permissão mínima e aprovação humana.

Checkpoint 6 — ensaie a decisão sem publicar

Crie docs/release-checklist.md com responsável, revisão aprovada, smoke tests, métricas, limite de erro e ação de contenção. Simule dois cenários:

  1. tudo dentro dos limites: registrar decisão prosseguir;
  2. aumento de falhas de API: registrar pausar rollout, preservar evidências e acionar o responsável.

Para mobile, “rollback” normalmente significa interromper rollout, corrigir e enviar uma nova versão; por isso o backend deve permanecer compatível com clientes antigos.

Falhas comuns:

SintomaCausa provávelCorreção
CI usa Flutter diferentecanal flutuante sem registrofixe a versão aprovada e registre-a
staging chama produçãodefine ausente ou fallback insegurofalhe cedo para ambiente inválido
artefato não corresponde ao commitbuild manual posteriorpromova o artefato já validado
segredo aparece no bundlevalor privado enviado por dart-defineremova do cliente e rotacione-o

Critério de conclusão e prática independente

O módulo termina quando o gate local passa, o workflow possui permissões mínimas, o artefato de homologação tem SHA-256 e a evidência permite relacioná-lo ao commit. Nenhuma publicação real é necessária.

Como prática independente, desenhe um job Android em runner compatível que produza AAB assinado a partir de secrets protegidos. Documente quais etapas podem rodar em pull request e quais somente após aprovação, sem adicionar credenciais reais.

Termos para revisar: semantic version, build number, artifact, signing, flavor, environment, secret, protected environment, staged rollout e rollback strategy. Consulte a referência do curso.