feat(legal+ci): termos de uso + workflow Forgejo Actions pra build Android automático
Some checks are pending
Build Android (APK + AAB) / build-android (push) Waiting to run

LEGAL
- GET /termos: termos de uso completos (11 seções) com aviso CRÍTICO de limitação de responsabilidade pra navegação náutica (não substitui chartplotter/cartas/atenção do skipper)
- Reembolso CDC art. 49 (7 dias arrependimento) explicito
- Lei aplicável Brasil + foro SP

CI/CD
- .forgejo/workflows/build-android.yml: pipeline completo (checkout → JDK17 → Android SDK → npm install mobile/ → cap sync → gradle bundleRelease + assembleRelease → upload artifacts → release no manual)
- .forgejo/workflows/README.md: como configurar runner Forgejo no Coolify, secrets necessários (KEYSTORE_BASE64, KEYSTORE_PWD, FORGEJO_TOKEN), alternativas (Codemagic, GitHub Actions)
- Trigger automático em push em app/, mobile/, scripts/sync-html.mjs
- Trigger manual via botão Forgejo

VALIDADO
- Bundletool 1.17.2 instalado em ~/bundletool/
- AAB validado: arquivos OK
- APK por device gerado: 2.8-2.9 MB (vs 3.4 MB universal — Play Store entrega menor)
- ~/Downloads/Shivao-v1.2.0.apks (12MB, contém splits por arquitetura)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
PontualTech / Karlão 2026-04-27 18:57:01 -03:00
parent 43b6cc0d5d
commit c46d30f7b9
3 changed files with 250 additions and 0 deletions

View file

@ -0,0 +1,63 @@
# Forgejo Actions — CI/CD do Shivao
## Como ativar (uma vez)
### 1. Configure um runner Forgejo no Coolify
```bash
# Sub-domínio sugerido: actions.pontualtech.work (DNS A → Hetzner)
# Sobe via Coolify usando docker-compose:
```
```yaml
# Cole no Coolify → Pontualtech → New Resource → Docker Compose Empty
services:
forgejo-runner:
image: code.forgejo.org/forgejo/runner:6
restart: unless-stopped
environment:
FORGEJO_INSTANCE_URL: https://git.pontualtech.work
FORGEJO_RUNNER_REGISTRATION_TOKEN: ${RUNNER_TOKEN} # pega em git.pontualtech.work/admin/runners
volumes:
- runner_data:/data
- /var/run/docker.sock:/var/run/docker.sock
volumes:
runner_data:
```
### 2. Configure secrets no Forgejo
`git.pontualtech.work/karlao/shivao-projeto/settings/actions/secrets`
| Secret | Como obter |
|---|---|
| `SHIVAO_KEYSTORE_BASE64` | `base64 -w0 ~/Downloads/Shivao-keystore-backup/shivao-release-CAPACITOR.keystore` |
| `SHIVAO_KEYSTORE_PWD` | `ShivaoKeystore2026!` (a senha que você definiu) |
| `FORGEJO_TOKEN` | Settings → Applications → Generate New Token (permissions: write:repository) |
### 3. Triggers do workflow
- **Auto:** push em `master` que toque em `app/`, `mobile/` ou `scripts/sync-html.mjs`
- **Manual:** botão "Run workflow" no painel Forgejo Actions
## Output
Cada build gera:
- APK assinado: `Shivao-v{X.Y.Z}.apk`
- AAB assinado: `Shivao-v{X.Y.Z}.aab`
- Anexados como artifact (download via UI Forgejo)
- Se trigger for manual: cria release `v{X.Y.Z}-ci` no repo
## Vantagens vs build local
- ✅ Zero setup local — Karlão pode editar HTML do iPad e o build roda no servidor
- ✅ Imutável e reproduzível
- ✅ Self-hosted (alinhado com `feedback_self_hosted.md`)
- ✅ Logs centralizados
- ⚠️ Custo: 1 container Coolify rodando (low-resource, ~50MB RAM idle)
## Alternativas se runner não funcionar
- **Codemagic:** 500min grátis/mês, conecta ao Forgejo via webhook
- **GitHub Actions (free tier):** mirror do repo no GitHub → workflow padrão
- **Build local:** `cd mobile && npm run android:build:aab` (já documentado em mobile/README.md)

View file

@ -0,0 +1,97 @@
name: Build Android (APK + AAB)
on:
push:
branches: [master]
paths:
- 'app/**'
- 'mobile/**'
- 'scripts/sync-html.mjs'
- '.forgejo/workflows/build-android.yml'
workflow_dispatch: {} # botão manual no painel Forgejo
jobs:
build-android:
runs-on: ubuntu-latest
permissions:
contents: write # pra upload de release
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node 20
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Setup JDK 17
uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: '17'
- name: Setup Android SDK
uses: android-actions/setup-android@v3
with:
packages: 'platforms;android-34 build-tools;34.0.0 platform-tools'
- name: Install root deps (sync script)
run: |
cd "${{ github.workspace }}"
# Sem package.json no root, script é puro Node ESM
node --version
- name: Sync HTML (1 fonte → server + mobile)
run: node scripts/sync-html.mjs
- name: Install Capacitor deps
working-directory: mobile
run: npm ci --ignore-scripts
- name: Capacitor sync
working-directory: mobile
run: npx cap sync android
- name: Decode keystore from secrets
run: |
echo "${{ secrets.SHIVAO_KEYSTORE_BASE64 }}" | base64 --decode > mobile/android/app/shivao-release.keystore
ls -lh mobile/android/app/shivao-release.keystore
- name: Build APK + AAB (release, signed)
working-directory: mobile/android
env:
SHIVAO_KEYSTORE_PWD: ${{ secrets.SHIVAO_KEYSTORE_PWD }}
run: |
chmod +x ./gradlew
./gradlew bundleRelease assembleRelease --no-daemon --stacktrace
- name: Rename artifacts with version
run: |
VERSION=$(grep "versionName" mobile/android/app/build.gradle | head -1 | grep -oE '"[^"]+"' | tr -d '"')
echo "Version: $VERSION"
cp mobile/android/app/build/outputs/apk/release/app-release.apk Shivao-v${VERSION}.apk
cp mobile/android/app/build/outputs/bundle/release/app-release.aab Shivao-v${VERSION}.aab
echo "VERSION=$VERSION" >> $GITHUB_ENV
- name: Upload APK + AAB as artifacts (CI)
uses: actions/upload-artifact@v3
with:
name: shivao-android-${{ env.VERSION }}
path: |
Shivao-v${{ env.VERSION }}.apk
Shivao-v${{ env.VERSION }}.aab
- name: Create Forgejo release
if: github.event_name == 'workflow_dispatch'
uses: actions/forgejo-release@v2
with:
direction: upload
tag: v${{ env.VERSION }}-ci
title: "Shivao v${{ env.VERSION }} (CI build)"
files: |
Shivao-v${{ env.VERSION }}.apk
Shivao-v${{ env.VERSION }}.aab
token: ${{ secrets.FORGEJO_TOKEN }}
url: https://git.pontualtech.work
repo: karlao/shivao-projeto

View file

@ -263,6 +263,96 @@ app.get('/.well-known/assetlinks.json', (req, res) => {
}]); }]);
}); });
// Termos de Uso
app.get('/termos', (req, res) => {
res.type('html').send(`<!DOCTYPE html><html lang="pt-BR"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Termos de Uso · Shivao</title><style>body{font-family:Georgia,serif;max-width:780px;margin:40px auto;padding:0 20px;color:#0e2a3d;background:#efe5cd;line-height:1.7}h1,h2{font-style:italic;color:#a07832}h1{border-bottom:2px solid #a07832;padding-bottom:8px}h2{margin-top:32px}.warn{background:#8c343422;border-left:4px solid #8c3434;padding:12px 16px;margin:20px 0}a{color:#3f7768}small{opacity:.7}</style></head><body>
<h1>Termos de Uso Shivao</h1>
<p><small>Última atualização: 27 de abril de 2026 · Versão 1.0</small></p>
<p>Ao usar o aplicativo <strong>Shivao</strong> (operado por <strong>PontualTech</strong>, CNPJ 32.772.178/0001-47), você concorda com estes termos. Leia com atenção.</p>
<h2>1. Aceitação</h2>
<p>O uso do app implica aceitação completa destes termos. Se não concorda, não use.</p>
<h2>2. Cadastro e conta</h2>
<ul>
<li>Você precisa ter 18 anos OU autorização do responsável legal.</li>
<li>Informações verdadeiras e atualizadas. Senha é responsabilidade sua.</li>
<li>1 conta por usuário. Compartilhamento de credenciais é proibido.</li>
<li>Podemos suspender contas com violação destes termos.</li>
</ul>
<h2>3. Planos, pagamentos e renovação</h2>
<ul>
<li><strong>Free:</strong> grátis, recursos limitados (vigia local + diário 10 últimas).</li>
<li><strong>Pro/Captain:</strong> assinatura mensal ou anual via Asaas (PIX, cartão, boleto).</li>
<li><strong>Renovação:</strong> ao fim do ciclo, você renova manualmente. Sem cobrança automática surpresa.</li>
<li><strong>Reembolso:</strong> 7 dias de arrependimento (CDC art. 49) devolução integral via mesmo método. Após 7 dias: pro-rata do tempo restante.</li>
</ul>
<h2>4. Uso permitido</h2>
<ul>
<li>Uso pessoal ou profissional náutico (lazer, trabalho, charters).</li>
<li>1 usuário = 1 ou múltiplos barcos (no plano Captain).</li>
<li>Compartilhamento público de posição é OK pra tripulação/familia (links temporários).</li>
</ul>
<h2>5. Uso PROIBIDO</h2>
<ul>
<li> Engenharia reversa do app ou backend (exceto pra interoperar legalmente).</li>
<li> Revender o serviço como white-label sem licença comercial.</li>
<li> Atacar a infraestrutura (DDoS, brute-force, exploit).</li>
<li> Cadastrar bots ou contas falsas em massa.</li>
<li> Usar pra atividade ilegal (pesca em área proibida, navegação clandestina, etc).</li>
</ul>
<h2>6. Limitação de responsabilidade IMPORTANTE</h2>
<div class="warn"><strong> AVISO CRÍTICO PARA NAVEGAÇÃO:</strong>
<p>O Shivao é uma <strong>FERRAMENTA AUXILIAR</strong> de navegação e segurança. <strong>NÃO substitui</strong>:</p>
<ul>
<li>Equipamentos náuticos certificados (chartplotter, AIS, VHF, balsas).</li>
<li>Cartas náuticas oficiais (Marinha do Brasil, NOAA).</li>
<li>Atenção do skipper.</li>
<li>Comunicação com a Capitania dos Portos.</li>
</ul>
<p>Não nos responsabilizamos por:</p>
<ul>
<li>Decisões tomadas com base no app (rota, fundeio, meteorologia).</li>
<li>Falha de GPS, internet, sensores ou notificações.</li>
<li>Danos materiais, pessoais ou ambientais decorrentes do uso.</li>
<li>Perda de dados (faça backups regulares).</li>
</ul>
<p><strong>O comandante da embarcação é o único responsável pela segurança a bordo.</strong></p></div>
<h2>7. Propriedade intelectual</h2>
<ul>
<li>Código, logo, nome "Shivao" pertencem à PontualTech.</li>
<li>Seus dados (viagens, mídia) pertencem a VOCÊ exporte quando quiser, exclua a qualquer momento.</li>
<li>Bibliotecas open source: Leaflet (BSD-2), OpenStreetMap (ODbL), express-rate-limit (MIT), bcryptjs (MIT), jsonwebtoken (MIT).</li>
</ul>
<h2>8. Suspensão e cancelamento</h2>
<ul>
<li>Você pode cancelar a qualquer momento via app (Aba Conta Sair Excluir conta).</li>
<li>Podemos suspender se houver violação destes termos, com aviso por e-mail (exceto urgências de segurança).</li>
<li>Após cancelamento: 30 dias pra reativar, depois exclusão permanente.</li>
</ul>
<h2>9. Mudanças nos termos</h2>
<p>Notificaremos por e-mail mudanças materiais com 30 dias de antecedência. Versão atual em <a href="https://shivao.pontualtech.work/termos">shivao.pontualtech.work/termos</a>.</p>
<h2>10. Lei aplicável e foro</h2>
<p>Estes termos seguem a lei brasileira. Foro: comarca de São Paulo/SP. Disputas de consumo podem usar <a href="https://www.consumidor.gov.br">consumidor.gov.br</a> antes de judicializar.</p>
<h2>11. Contato</h2>
<p>Suporte: <a href="mailto:contato@pontualtech.com.br">contato@pontualtech.com.br</a><br>
Privacidade/LGPD: <a href="mailto:dpo@pontualtech.com.br">dpo@pontualtech.com.br</a></p>
<hr style="margin:40px 0;border:none;border-top:1px solid #a07832">
<p style="text-align:center"><small>Shivao · Diário de Bordo · PontualTech · ${new Date().getFullYear()}</small></p>
</body></html>`);
});
// Política de Privacidade (URL pública obrigatória pra Play Store + LGPD) // Política de Privacidade (URL pública obrigatória pra Play Store + LGPD)
app.get('/politica', (req, res) => { app.get('/politica', (req, res) => {
res.type('html').send(`<!DOCTYPE html><html lang="pt-BR"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Política de Privacidade · Shivao</title><style>body{font-family:Georgia,serif;max-width:780px;margin:40px auto;padding:0 20px;color:#0e2a3d;background:#efe5cd;line-height:1.7}h1,h2{font-style:italic;color:#a07832}h1{border-bottom:2px solid #a07832;padding-bottom:8px}h2{margin-top:32px}code{background:#fff;padding:2px 6px;border-radius:3px;font-size:.9em}a{color:#3f7768}small{opacity:.7}</style></head><body> res.type('html').send(`<!DOCTYPE html><html lang="pt-BR"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Política de Privacidade · Shivao</title><style>body{font-family:Georgia,serif;max-width:780px;margin:40px auto;padding:0 20px;color:#0e2a3d;background:#efe5cd;line-height:1.7}h1,h2{font-style:italic;color:#a07832}h1{border-bottom:2px solid #a07832;padding-bottom:8px}h2{margin-top:32px}code{background:#fff;padding:2px 6px;border-radius:3px;font-size:.9em}a{color:#3f7768}small{opacity:.7}</style></head><body>