Pular para o conteúdo
Voltar ao início
Tutorial

Workflows: Automatize tarefas de dev no Android, sem servidor

Automatize tarefas no Android com os Workflows do PocketCode: 25 gatilhos, ramificações, loops, cron, permissões por workflow e secrets criptografados. Sem servidor.

13 min
Por Pelayo Naredo
Workflows: Automatize tarefas de dev no Android, sem servidor

Todo desenvolvedor acumula as mesmas pequenas tarefas repetitivas: rodar os testes depois de um push, fazer backup do banco quando sai um deploy, formatar ao salvar, avisar quando um build quebra. Num notebook você junta tudo isso com runners de CI, tarefas cron e uns scripts de shell em algum servidor. Num celular, a resposta de sempre é «não dá». O Pocket Code muda isso com os Workflows: um motor de automação orientado a eventos que permite automatizar tarefas no Android inteiramente no dispositivo, sem nenhum servidor para alugar nem nada para manter vivo na nuvem.

Um workflow é simples de descrever: um gatilho (um evento dentro do IDE ou um agendamento) mais uma sequência de etapas que rodam sobre um contexto compartilhado. Isso basta para construir fluxos de dev de verdade — do tipo para o qual você normalmente montaria um pipeline de CI — bem ao lado do seu editor, do seu terminal e do seu gerenciador de banco de dados.

Quatro formas de criar um

Você nunca precisa começar de uma tela em branco:

ModoComo você criaExemplo
TemplateToque em Activate em um dos 17 templates integrados"Testes e, se passarem, deploy", "Verificar um endpoint", "Backup do banco após o deploy"
Descrever para a IAEscreve uma frase e recebe um scaffold editável"depois de cada commit, rode os testes e me avise se falharem" vira um workflow com o seu ramo de erro
EditorO botão "+" para o formulário completoMonte do zero, com expressões e política de retry
Importar um arquivoAbre um .pcwf.json que alguém te mandouChega desativado e com id novo, então nada roda até você ter lido

Ativar um template o clona em uma cópia editável com um id novo, então ajustá-la nunca toca no original.

Gatilhos: o que acorda um workflow

Os workflows escutam os eventos que passam pelo IDE. O motor assina o bus interno do app e associa cada evento a um tipo de gatilho. São vinte e cinco tipos, e um workflow pode ter um gatilho principal e quantos extras você quiser:

FamíliaGatilhos
GitPush (sem campo de branch), commit (só pela tela Projetos)
ArquivosSalvo, criado, apagado, renomeado
Projeto e buildProjeto aberto, projeto fechado, build terminado, execução terminada, comando de terminal terminado
Deploy e dadosDeploy concluído, deploy falhou, consulta de banco executada
Outros módulosResposta do API Tester, design exportado, o agente de IA mexeu num arquivo, o agente de IA terminou um turno
Do próprio celularAtalho, tile de configurações rápidas, texto compartilhado, arquivo compartilhado, app em primeiro plano
Encadear e manualErro detectado (um erro de build ou de execução, uma execução de workflow que falhou, um comando de terminal que falhou rodado pelo agente de IA), manual

O filtro é tipado, e isso é uma mudança real em relação a versões anteriores: cada gatilho declara os seus campos, e você compara campo com valor usando operadores — igual, contém, começa por, corresponde, globs de caminho. Não é mais procurar uma substring no texto do evento. E como ninguém acerta um filtro de primeira, o editor tem um botão de capturar o próximo evento: você faz a ação, e ele mostra a carga real que o gatilho traz para você escrever o filtro contra algo que existe.

Nem todos os tipos têm ainda quem os emita. Dois nunca disparam hoje: projeto fechado e o agente de IA terminou um turno. Um evento de push não traz nome de branch, então um filtro por branch nunca corresponde, e dois dos 17 templates (Auto-Deploy no push para main e Testes depois do push para main) filtram assim. Em vez de escondê-lo, o painel de problemas avisa quando um workflow usa um gatilho que hoje nunca dispararia.

Agendamento: cron no seu celular, sem servidor

É aqui que a «automação sem servidor» fica concreta. Qualquer workflow pode ter um ou mais agendamentos: um intervalo predefinido (a cada 15 minutos, a cada hora, a cada 6 horas), ou uma expressão cron de cinco campos com curingas *, listas N,M, intervalos N-M e passos */N. Enquanto você digita, a tela mostra o próximo disparo ou avisa que a expressão está errada.

Três coisas que vale saber:

  • A mudança de hora está resolvida. Os agendamentos usam o fuso horário do dispositivo (não há seletor de fuso). Na primavera, na hora que não existe, dispara no salto; no outono, na hora que acontece duas vezes, dispara uma só. Está testado.
  • Uma política para o que foi perdido. Você escolhe: pular o que caiu com o dispositivo desligado, ou recuperar uma vez quando o app iniciar de novo. Uma, não as quarenta e oito de um feriadão.
  • Condições do dispositivo. Qualquer rede, só Wi-Fi ou nenhuma; só carregando; não com bateria fraca; só com o dispositivo ocioso. Uma condição atrasa o disparo, não o cancela, e a tela diz isso com essas palavras.

E uma honestidade incômoda: o Android não roda trabalho em segundo plano mais do que a cada quinze minutos. Um intervalo abaixo disso é elevado e o app te dá o número exato. Um cron abaixo disso ninguém eleva, então a única coisa verdadeira é que não há garantia — e é isso que a tela diz, em vez de um número inventado.

Os agendamentos são persistidos e re-enfileirados quando o app inicia, então a morte de um processo não esvazia a sua automação sem você perceber. Para mudar um agendamento, você o apaga e cria outro.

Ramificações, loops e sub-workflows

O editor não é uma lista de etapas em fila. São sete tipos de etapa, seis deles controle de fluxo, e os ramos aninham-se dentro de ramos: o que você constrói é uma árvore.

  • Se / senão — dois ramos. A condição é uma árvore, não um espaço único: And, Or e Not aninham-se, então «os testes passaram e o branch é main» é uma condição, não dois workflows.
  • Paralelo — N ramos ao mesmo tempo, unidos de três formas: quando todos terminarem, com o primeiro que terminar, ou com o primeiro que terminar bem. Os dois últimos cancelam os ramos perdedores para que parem de causar efeitos.
  • Para cada — itera uma lista com um alias por item, um limite de segurança de iterações e um número opcional de iterações em simultâneo.
  • Tentar / se falhar — se algo do primeiro bloco falhar, o segundo roda com a mensagem de erro ligada a uma variável que você nomeia.
  • Sub-workflow — roda outro workflow inteiro dentro deste, com as suas próprias entradas. É o que transforma um workflow longo em peças reutilizáveis.
  • Esperar — um tempo, ou até acontecer um evento com o tempo como limite. «Espera o deploy acabar» em vez de «espera dois minutos e torce».

E sem montar uma etapa de controle: cada etapa de ação pode carregar uma condição própria opcional. Se for falsa a etapa é ignorada, sem envolvê-la num se / senão inteiro.

Quinze ações, todas ligadas

São quinze etapas de ação, e as quinze estão ligadas a algo que roda mesmo: executar um comando, uma requisição HTTP, uma operação de git, um deploy, uma consulta ou backup do banco, ler, escrever ou verificar um arquivo, abri-lo no editor, analisar ou gerar com IA, transformar um valor, definir uma variável e notificar.

Que as quinze tenham implementação não é detalhe de apresentação: há um teste que fica vermelho nomeando qualquer tipo que perca a sua. Um tipo sem nada por trás falha alto em vez de dar sucesso em silêncio.

Alguns limites que vale conhecer. A etapa de deploy só dispara Render, Netlify e DigitalOcean (um branch ou um ambiente são anotados mas não respeitados). A etapa de git tem sete operações: status, commit, push, pull, checkout, log e diff. Uma consulta ao banco nomeia uma das suas conexões Neon, Supabase, Turso ou Upstash. E definir variável devolve o seu valor como {{step.<id>.output.value}}; não cria um {{var.nome}}.

Se uma etapa é destrutiva calcula-se com os seus parâmetros à frente, não pelo tipo: git status não é git push, e um SELECT não é um DROP. Rotular o tipo inteiro de destrutivo obrigaria a confirmar até um status, e pedir confirmação para tudo ensina a aceitar sem ler.

Passar dados entre etapas

As etapas compartilham um contexto, e qualquer campo pode referenciar outro com uma expressão entre chaves duplas:

ExpressãoResolve para
{{var.nome}}Uma entrada declarada, ou a variável de erro de uma etapa Tentar
{{step.<id>.status}}O status de uma etapa
{{step.<id>.output.json.items[0].name}}Um campo da saída, navegando dentro do JSON
{{step.<id>.error}}A mensagem de erro de uma etapa
{{item.<alias>}}O elemento da iteração em curso
{{trigger.<campo>}}A carga tipada do evento que o disparou
{{secret.NOME}}Um secret guardado. Terminal: não se navega dentro dele

Mais treze filtros encadeáveis: lines, first, last, trim, upper, lower, length, json, default, split, join, date, replace. Assim, a primeira linha da saída de um comando é {{step.sh.output.stdout | lines | first | trim}}.

Os argumentos dos filtros são sempre escritos entre aspas, como em replace:"a":"b". Uma expressão que não resolve devolve string vazia de propósito, para que uma referência a uma etapa de um ramo que não rodou não derrube a execução.

Confiabilidade: retries, timeouts e o que fazer ao falhar

Cada etapa de ação aceita uma política de retry (com espera fixa, linear ou exponencial e um limite para essa espera) e um timeout, e todas as etapas têm uma política de o que fazer se falhar: parar a execução ou continuar.

Dois detalhes que custam caro descobrir na prática:

  • Continuar após uma falha não tinge a execução. A etapa fica vermelha com o seu erro, mas a execução sai verde — a mesma distinção que o continue-on-error faz no GitHub Actions.
  • Um timeout conta como falha. A etapa volta marcada como esgotada e, se ainda tiver tentativas, é repetida.

E uma etapa pode ser desligada sem apagá-la, que é o que você quer ao depurar, em vez de apagá-la e escrevê-la de novo.

Além disso, em vez de rodar o workflow inteiro — com os seus deploys e as suas notificações — sempre que ajusta um parâmetro, você pode testar uma etapa sozinha com os dados fixados como contexto. Uma etapa que não pode ser simulada não é simulada: o botão passa a dizer «executar esta etapa a sério» e pergunta antes. Um botão que diga «tudo certo» sem ter executado nada é pior do que não ter botão.

Permissões e secrets

Um workflow declara o que tem permissão para fazer: sair para a rede, escrever arquivos, rodar comandos, e uma lista de domínios a que pode chegar. As implementações verificam antes de tocar em nada, e a recusa diz qual permissão foi, o que ia executar e onde se muda. Um sub-workflow herda a interseção das permissões: não pode abrir o que o pai fechou.

Não é uma sandbox, e a tela diz isso: quem puder editar o workflow pode abrir o cinto. Protege do descuido — um workflow que você abriu à IA, um que alguém te mandou, ou o curl que alguém colou «só para testar» e ficou ali.

Os secrets ficam num armazenamento criptografado, por conta. Você os referencia como {{secret.NOME}} e o valor nunca mais é mostrado, nem na sua própria tela. Só são resolvidos numa execução real; o mascaramento cobre todos os valores guardados, não só os que uma etapa leu; e acontece antes de escrever no banco, não ao desenhar a tela — mascarar na hora de pintar chegaria tarde, o valor já estaria no arquivo e em qualquer backup.

Histórico de execuções que dá para inspecionar

Cada execução terminada é escrita inteira, com o resultado de cada etapa, quanto demorou, quantas tentativas precisou e o seu erro, se houve. As execuções terminadas sobrevivem ao fechamento do app; uma que ainda está em andamento quando o Android mata o processo não deixa registro, e o log de uma etapa de shell não é guardado. A aba Atividade é a visão de todos os workflows, filtrável por status, por data, por workflow e pelo texto do erro.

A retenção é você que define: 100 execuções e 30 dias por padrão, de 1 a 1.000 execuções e de 1 a 365 dias.

Compartilhar um

Um workflow viaja como um arquivo .pcwf.json. O que não viaja: o histórico, as saídas fixadas, os agendamentos e o interruptor. O que chega vem desativado e com um id novo.

Os valores de parâmetros marcados como secretos são esvaziados antes de escrever o arquivo e listados, para quem o abrir saber o que tem de preencher. Uma referência {{secret.X}} viaja: é um nome, não o secret, e esvaziá-la quebraria o workflow de forma irreparável. Todo o resto viaja exatamente como você digitou, headers HTTP e comandos incluídos, então confira o arquivo antes de compartilhar.

Descreva em linguagem natural

Se preferir não montar as etapas à mão, escreva uma frase. A resposta do modelo é corrigida onde dá, passa pelo linter, é testada em dry run, e o resultado é mostrado antes de salvar qualquer coisa. Você também pode pedir que ele altere um que já existe: a resposta é fundida por cima, mantendo id, interruptor e data, e você recebe o diff.

Se não tiver modelo configurado há um fallback heurístico local, que é a única coisa que funciona para quem ainda não pôs a sua chave. O documento enviado ao modelo não leva valores de parâmetros secretos — são substituídos por um marcador.

E ao contrário: qualquer workflow que você marque como «disponível para o agente de IA» é exposto como ferramenta no chat, e o agente pode chamá-lo. O gerador acima é grátis; pedir ao chat de IA para criar ou atualizar workflows é um recurso Pro.

A sua automação fica no seu dispositivo

Definições, histórico e agendamentos vivem num banco de dados local no seu celular. As definições podem ter backup na nuvem para restaurar (Cloud Sync, recurso Pro), mas nada é lido da nuvem para executar a sua automação: o motor roda localmente, ponto. Histórico e agendamentos não sincronizam de forma alguma: o histórico é local do dispositivo, e os agendamentos são estado do WorkManager específico de cada um.

Uma última nota de honestidade: aqui os ramos são uma árvore aninhada, não nós que se ligam numa tela. Não há switch de N saídas nem forma de unir um ramo a um nó específico mais abaixo. Também não há gatilho por webhook, e os workflows não podem ser instalados do Marketplace nem publicados nele (o botão de instalar está desativado). Compartilhar os seus é compartilhar o arquivo.

O PocketCode está a caminho do Google Play, levando um motor de automação completo — vinte e cinco gatilhos, ramificações, cron no celular, permissões e secrets — para o mesmo app onde você escreve e publica o código. Entre no pré-registro para estar entre os primeiros a testar no seu próprio dispositivo.

A ferramenta por trás deste artigo

Workflows

Pronto para experimentar o PocketCode?

Baixe o app e comece a programar pelo seu celular.