Integração com GitHub Actions
Um guia para GitHub Actions + modelos de PR que exigem evidências de teste em dispositivo - para que "testado no simulador" não faça merge de alterações de navegação nativa sem um caminho de QA real no iPhone e Android.
Busque em todas as páginas da documentação
Um guia para GitHub Actions + modelos de PR que exigem evidências de teste em dispositivo - para que "testado no simulador" não faça merge de alterações de navegação nativa sem um caminho de QA real no iPhone e Android.
Cartão de receita de referência rápida - pronto para copiar e colar.
<!-- .github/pull_request_template.md -->
## Resumo
<!-- O que mudou e por quê -->
## Ticket
<!-- SHIP-___ -->
## Evidências de teste em dispositivo (obrigatório para UI / nativo / navegação)
| Plataforma | Dispositivo / SO | Fonte do Build | Resultado |
|----------|--------------------|------------------|--------|
| iOS | ex: iPhone 14 / 17| QR da prévia EAS | PASS |
| Android | ex: Pixel 7 / 14 | QR da prévia EAS | PASS |
## Caminhos de teste exercitados
- [ ] Inicialização a frio / login
- [ ] Tela(s) alterada(s): ___
- [ ] Deep link / push (se aplicável)
## Capturas de tela / gravações
<!-- Arraste o link da nuvem do Maestro, gravação de tela ou captura de tela -->
## CI
- [ ] Verificação `quality` verde
- [ ] build_id da prévia anotado: ___# .github/workflows/pr-evidence.yml
name: PR Evidence
on:
pull_request:
types: [opened, edited, synchronize, reopened]
jobs:
evidence:
runs-on: ubuntu-latest
steps:
- name: Validate PR template
uses: actions/github-script@v7
with:
script: |
const body = context.payload.pull_request.body ?? '';
const needsDevice = /native|navigation|gesture|camera|ui/i.test(body)
|| context.payload.pull_request.labels.some(l => l.name === 'needs-device-qa');
if (!needsDevice) {
core.info('No device-heavy paths detected - evidence check skipped');
return;
}
const required = ['Device test evidence', 'Test paths exercised', 'iOS', 'Android', 'PASS'];
const missing = required.filter(r => !body.includes(r));
if (missing.length) {
core.setFailed(`PR body missing: ${missing.join(', ')}`);
}# .github/workflows/pr-checks.yml (excerpt - pair with evidence)
name: PR Checks
on:
pull_request:
branches: [main]
jobs:
quality:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with: { node-version: 20, cache: npm }
- run: npm ci
- run: npx expo customize tsconfig.json
- run: npm run format:check && npm run lint && npm run typecheck
- run: npm run test -- --ciQuando usar isso:
build_id eles testaram.Quando evitar:
skip-device-qa ou filtros de caminho em workflows.Passo 1 - Adicionar modelo de PR e rótulos
mkdir -p .github<!-- .github/pull_request_template.md -->
## Resumo
## Ticket
SHIP-
## Tipo de alteração
- [ ] Apenas JS / cópia (seguro para OTA)
- [ ] Layout / estilo de UI
- [ ] Navegação / gestos
- [ ] Módulo nativo / plugin de configuração
- [ ] Upgrade de SDK
## Evidências de teste em dispositivo
> Obrigatório quando qualquer caixa acima, exceto "Apenas JS / cópia", estiver marcada.
| Plataforma | Dispositivo / SO | Build (`build_id` ou link de prévia) | Resultado |
|----------|-------------|-----------------------------------|--------|
| iOS | | | PASS / FAIL |
| Android | | | PASS / FAIL |
## Caminhos de teste exercitados
- [ ] Inicialização a frio
- [ ] Restauração de autenticação / sessão
- [ ] Funcionalidade em mudança: ___
## Automação
- [ ] Fluxo do Maestro: `flows/smoke.yaml` (link ou artefato de CI)
- [ ] Captura de tela / gravação de tela anexada
## Notas de Rollback (se impactar produção)
<!-- Plano de canal OTA, feature flag ou branch de hotfix --># Criar rótulos do GitHub (CLI gh)
gh label create "needs-device-qa" --color B60205 --description "Requer evidências de dispositivo no PR"
gh label create "skip-device-qa" --color C5DEF5 --description "Docs ou apenas CI - sem matriz de dispositivo"Passo 2 - Rótulo automático baseado em caminho
# .github/workflows/pr-labeler.yml
name: PR Labeler
on:
pull_request:
types: [opened, synchronize]
jobs:
label:
runs-on: ubuntu-latest
steps:
- uses: actions/labeler@v5
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}# .github/labeler.yml
needs-device-qa:
- changed-files:
- any-glob-to-any-file:
- 'app/**'
- 'src/**/*.tsx'
- 'ios/**'
- 'android/**'
- 'app.json'
- 'eas.json'Passo 3 - Workflow de validação de evidências
# .github/workflows/pr-evidence.yml
name: PR Evidence
on:
pull_request:
types: [opened, edited, synchronize, reopened]
permissions:
pull-requests: read
jobs:
evidence:
if: >-
!contains(github.event.pull_request.labels.*.name, 'skip-device-qa')
runs-on: ubuntu-latest
steps:
- uses: actions/github-script@v7
with:
script: |
const pr = context.payload.pull_request;
const body = pr.body ?? '';
const title = pr.title ?? '';
const uiPaths = /(src\/|app\/|\.tsx|navigation|gesture|native|plugin)/i;
const needsEvidence =
pr.labels.some(l => l.name === 'needs-device-qa') ||
uiPaths.test(body) ||
uiPaths.test(title);
if (!needsEvidence) {
core.info('Skipping device evidence - JS/docs-only change');
return;
}
const fail = (msg) => core.setFailed(msg);
if (!/\| iOS \|.*\|.*\|.*PASS/i.test(body.replace(/\n/g, ' '))) {
fail('iOS row with PASS missing in device table');
}
if (!/\| Android \|.*\|.*\|.*PASS/i.test(body.replace(/\n/g, ' '))) {
fail('Android row with PASS missing in device table');
}
if (!body.includes('Test paths exercised')) {
fail('Test paths exercised section missing');
}
const buildRef = /build_id|eas\.dev|expo\.dev\/accounts/i;
if (!buildRef.test(body)) {
fail('No EAS preview build_id or install link in PR body');
}Passo 4 - Proteção de branch
GitHub → Settings → Branches → main:
Require status checks:
- quality (pr-checks.yml)
- evidence (pr-evidence.yml)
Require pull request reviews: 1Documentar em CONTRIBUTING.md - revisores rejeitam PRs com texto placeholder e.g. iPhone.
Passo 5 - Fluxo do contribuinte com build de prévia
# Autor adiciona rótulo após abrir o PR (ou o labeler adiciona automaticamente)
gh pr create --fill
gh pr edit --add-label needs-device-qaSolicitar prévia de Builds de Prévia em PRs:
gh pr edit 42 --add-label needs-preview
# CI posta QR - autor instala em dispositivos físicos# Executar Maestro localmente contra o binário de prévia
maestro test flows/checkout-smoke.yaml
# Anexar gravação; colar build_id na tabela do PRExemplo de tabela de PR preenchida:
| Plataforma | Dispositivo / SO | Fonte do Build | Resultado |
|----------|----------------------|---------------------------------------|--------|
| iOS | iPhone 14 / iOS 17.4 | build_id 8f3a2c (PR #42 preview) | PASS |
| Android | Pixel 7 / API 34 | build_id 8f3a2c (PR #42 preview) | PASS |Passo 6 - Upload opcional do Maestro em sucesso da prévia
# .github/workflows/preview-maestro.yml (excerpt)
- name: Maestro smoke on preview artifact
if: success()
run: |
maestro test flows/smoke.yaml --format junit --output maestro.xml
- uses: actions/upload-artifact@v4
with:
name: maestro-${{ github.event.pull_request.number }}
path: maestro.xmlVincular artefato no PR - satisfaz a caixa de seleção "Automação".
| Verificação | Workflow | Bloqueia merge |
|---|---|---|
| Lint / tsc / Jest | pr-checks.yml | Sim |
| Evidência do modelo | pr-evidence.yml | Sim (caminhos de UI) |
| Build de prévia | preview-build.yml | Não - informa evidência |
| Maestro no EAS | EAS Workflow | Apenas lançamento |
# Token de robô para workflows de prévia - nunca conta pessoal
# Segredo do GitHub: EXPO_TOKEN (ver GitHub Actions + EAS)Padrão híbrido: GitHub Actions para portões de PR; Workflows EAS para cadeias de lançamento de tags.
if: github.event.pull_request.draft == false.needs-device-qa.synchronize; CI comenta com o último build_id.skip-device-qa. Correção: Revisão de CODEOWNERS para remoção do rótulo.| Alternativa | Usar Quando | Não Usar Quando |
|---|---|---|
| Modelo de honra | Equipe pequena, alta confiança | Submissões que falham no QA |
| Maestro obrigatório apenas no EAS | Orçamento para dispositivos na nuvem | Necessidade de feedback rápido de PR |
| Aprovação manual de QA no Jira | Indústrias regulamentadas | Falta de link entre ticket e PR |
| Linter de PR Danger JS | Regras personalizadas complexas | Equipe prefere apenas YAML |
Não. Use o rótulo skip-device-qa ou filtros de caminho excluindo docs/** e *.md. Mantenha a verificação quality para todos os PRs.
Permita que o QA edite o corpo do PR ou comente com a tabela de evidências; pull_request_target em edited reexecuta a validação. Melhor: QA posta um modelo de comentário que o autor copia para o corpo.
Não para módulos nativos, plugins de configuração ou upgrades de SDK. Registre a prévia do EAS ou o build_id do cliente de desenvolvimento - Maestro E2E.
Jest prova a lógica; evidências de dispositivo provam layout, gestos e pontes nativas. Ambos são necessários para PRs de UI - Noções Básicas de Teste Mobile.
Sim - Formulários de Issue do GitHub suportam campos obrigatórios. Converta a tabela de dispositivos em entradas de formulário obrigatórias; Actions ainda valida o corpo do PR se os contribuidores usarem Closes # para vincular.
EXPO_TOKEN, caching, monorepoVersões da Stack: Esta página foi escrita para React 19.2.3, React Native 0.86.0 e Expo SDK 57 (
expo~57.0.4).
Revisado por Chris St. John·Última atualização: 19 de jul. de 2026