Skip to main content

Loop

Start Script no Releezy Loop

English

Como configurar o script que prepara o ambiente do agente para trabalhar no seu projeto no Releezy Loop.

Este guia explica como configurar o start script — o passo que prepara o ambiente onde o agente do Releezy Loop vai trabalhar no seu projeto. É um guia de uso: o que você configura, como o Releezy chama o seu script, e como debugar quando algo dá errado. Não descreve como o Loop funciona por dentro — você não precisa disso para tirar o máximo dele.

Contexto: o que é o “ambiente do agente”Link to this section

Toda vez que você dispara um agente no Loop (manualmente ou via webhook do seu repositório git), pense no seguinte modelo mental: o agente começa numa máquina nova e vazia, com o seu repositório já clonado, e roda o seu start script antes de começar a tarefa.

Esse ambiente é efêmero: começa do zero a cada run e some quando termina. Não persiste arquivos entre execuções, não tem o .env que você usa localmente, não tem vendor/, node_modules/, banco de dados configurado, nada disso.

O que ele tem:

  • Os arquivos commitados no Git (incluindo .env.example, composer.json, package.json, etc.)
  • As linguagens e ferramentas de base do seu projeto, mais o que você declarou na configuração do projeto
  • As variáveis de ambiente que você configurou no projeto (tokens, chaves)

O que ele não tem (e o seu script precisa providenciar):

  • Arquivos no .gitignore (.env, vendor/, node_modules/, storage/logs/*)
  • Bancos de dados criados e migrados
  • Seeds populados
  • App key gerada (Laravel) ou equivalente
  • Qualquer outro setup que normalmente seria feito por um onboarding/deploy

O start script é o ponto onde você prepara esses itens. Sem ele (ou com ele mal escrito), o agente acorda numa máquina pelada e gasta turnos tentando descobrir como botar pra rodar — quando o orçamento acaba, ele ainda nem começou a tarefa real.

Onde colocar o scriptLink to this section

No seu repositório. Convenção: scripts/loop-start.sh (ou qualquer caminho — você informa ao Releezy onde está).

Depois, no Releezy Loop, abra o seu projeto e em Settings → Start Script coloque o caminho relativo, ex: scripts/loop-start.sh. Salve. Pronto — toda nova run vai executar esse script antes do agente começar.

Como o Releezy chama o scriptLink to this section

O Releezy roda o seu script a partir da raiz do repositório clonado, de forma não-interativa. Você não precisa saber onde a pasta do repo fica nem como ela se chama. Escreva o script como se estivesse executando ele do diretório raiz do seu próprio projeto.

A saída do script (echo, erros, warnings) aparece nos logs da run no Releezy. Se algo der errado, é lá que você vai debugar.

As 4 regras inegociáveisLink to this section

1. IdempotenteLink to this section

O script roda toda run. Se reinstala tudo do zero a cada vez, você queima minutos. Cada operação cara precisa de uma checagem “já feito? então pula”:

# Sim
[ -f "vendor/autoload.php" ] || composer install --no-interaction
[ -f ".env" ] || cp .env.example .env

# Não
composer install --no-interaction   # roda sempre, mesmo desnecessário
cp .env.example .env                # sobrescreve .env existente, perde patches

Migrações (migrate, rails db:migrate, etc.) já são idempotentes por design — pode rodar à vontade.

2. Auto-localizadoLink to this section

Nunca coloque caminhos absolutos no script. O nome da pasta onde o Releezy clona o repo é dinâmico e pode mudar. Sempre derive o caminho a partir da localização do próprio script:

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"
BACKEND_DIR="${REPO_ROOT}/backend"

Assim funciona em qualquer máquina, em qualquer caminho.

3. Sem promptsLink to this section

O ambiente do agente não tem terminal interativo. Qualquer comando que pergunte alguma coisa trava o script para sempre.

Em vez deUse
composer installcomposer install --no-interaction --prefer-dist
npm installnpm ci (mais previsível e não-interativo)
php artisan migratephp artisan migrate --force --no-interaction
sudo <cmd>sudo -n <cmd> (falha rápido se pedir senha)

Se a sua ferramenta tem uma flag tipo --yes, --silent, --non-interactive, use.

4. Falhe alto em problemas reais, tolere redundânciasLink to this section

Coloque set -euo pipefail no topo. Isso garante que o script para imediatamente se algo essencial falhar.

Mas para coisas opcionais (subir um Postgres que já pode estar rodando, criar um DB que já pode existir), use || echo "aviso..." para não derrubar tudo:

# Subir Postgres é best-effort — se já tá rodando, ótimo
sudo -n service postgresql start 2>/dev/null \
  || echo "[start] postgres já está rodando, seguindo"

# Mas instalar dependências é essencial — se falhar, parar tudo
composer install --no-interaction --prefer-dist

Regra: falhe em coisas que impedem o agente de trabalhar (dependências, .env, migrations). Tolere coisas que já estão prontas (serviços no ar, DBs criados).

A ordem natural das coisasLink to this section

  1. Auto-localizar o script
  2. Subir serviços auxiliares (Postgres, Redis, etc.) — best-effort
  3. Criar databases vazios — idempotente
  4. Entrar no diretório do backend
  5. Instalar dependências (composer, npm) — só se faltando
  6. Criar .env a partir de .env.example — só se não existe
  7. Ajustar valores no .env se necessário (host do DB, drivers de cache, etc.)
  8. Gerar app key — só se vazia
  9. Rodar migrations
  10. Fazer seed — só se o banco estiver vazio
  11. Mensagem final clara: echo "=== [start] ambiente pronto ==="

Variáveis disponíveis dentro do scriptLink to this section

O Releezy expõe algumas variáveis que você pode usar:

VariávelPara que serve
$LOOP_REPO_DIRCaminho absoluto do seu repo (já clonado, na branch certa)
$LOOP_AGENT_BRANCHBranch onde o agente vai commitar
$GITHUB_TOKENToken git já configurado (pra clonar dependências privadas, se necessário)

Use elas em vez de caminhos hardcoded.

O que NÃO fazerLink to this section

  • ❌ Hardcoded /workspace/... ou caminhos absolutos do seu setup local
  • ❌ Comandos interativos que pedem confirmação ou senha
  • ❌ Reinstalar dependências do zero toda vez
  • ❌ Quebrar o bootstrap inteiro por causa de um serviço opcional que não subiu
  • ❌ Commitar o .env no repo — o script cria o .env, não depende dele já existir
  • sleep 30 “pra esperar o banco subir” — use pg_isready ou loops com timeout
  • ❌ Confiar em ferramentas globais exóticas — use o que vem no ambiente do seu projeto

Como debugar quando algo dá erradoLink to this section

A saída do start script aparece nos logs da run no Releezy. O que procurar:

SinalSignificado
Running start script: ...O script foi encontrado e iniciou
Linhas com seu prefixo (ex: [meuapp])Quais etapas executaram
WARNING: start script exited with code NO script falhou — veja a saída anterior
Ausência total dessas linhasConfiguração do script está errada (veja Onde colocar o script)

Sinais de que o agente acordou num ambiente quebrado:

  • Ele reclama de .env ausente
  • Ele tenta rodar composer install ou npm install no meio do trabalho
  • Ele tenta adivinhar credenciais de banco
  • Ele gasta vários turnos “configurando o ambiente”

Se isso acontecer, não é preguiça do agente — é o start script que falhou ou não foi configurado. Olhe os logs.

Para testar localmente antes de configurar no Releezy:

cd <raiz-do-seu-repo>
bash scripts/loop-start.sh

Se rodar do zero (sem vendor/, sem .env, sem DB) e completar sem erros, está pronto. Se na segunda execução completar em poucos segundos, está idempotente.

Template mínimo (Laravel)Link to this section

#!/bin/bash
set -euo pipefail

# Auto-localiza
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"
BACKEND_DIR="${REPO_ROOT}/backend"

cd "$BACKEND_DIR"

# Dependências
[ -f "vendor/autoload.php" ] || composer install --no-interaction --prefer-dist
[ -d "node_modules" ] || npm ci

# Env + app key
if [ ! -f ".env" ]; then
  cp .env.example .env
  php artisan key:generate --force --no-interaction
fi

# Migrations
php artisan migrate --force --no-interaction

# Seed só se vazio
USERS=$(php artisan tinker --execute="echo \App\Models\User::count();" 2>/dev/null || echo "0")
[ "$USERS" = "0" ] && php artisan db:seed --no-interaction

echo "=== [start] ambiente pronto ==="

Adapte para sua stack:

  • Rails: bundle install + rails db:migrate + rails db:seed
  • Django: pip install -r requirements.txt + python manage.py migrate + python manage.py loaddata
  • Node/Next: npm ci + npx prisma migrate deploy + script de seed

A estrutura é a mesma.

TL;DRLink to this section

  • O script roda dentro de um ambiente novo, a cada run, na raiz do seu repo
  • Sua responsabilidade: deixar o ambiente pronto (deps, .env, banco)
  • 4 regras: idempotente, auto-localizado, não-interativo, falha em problemas reais
  • Configure em Settings → Start Script no projeto Loop
  • Se o agente está perdendo turnos configurando ambiente, o problema é aqui — não nele