Adicionando IA ao CI/CD: três formas de criar GitHub Actions inteligentes
No desenvolvimento de software da era da IA, o pipeline de CI/CD também precisa de um upgrade. Não basta mais ter testes automatizados e deploy contínuo — os workflows podem se tornar inteligentes, revisando issues, analisando código e sugerindo melhorias com ajuda de modelos de linguagem.
Neste tutorial, vamos explorar três formas de injetar capacidades de IA em GitHub Actions, usando um requisito concreto: quando uma issue é etiquetada como bug, um modelo de IA revisa a descrição e determina se há informações suficientes para reproduzir o problema.
Pré-requisitos
| Componente | Mínimo | Recomendado |
|---|---|---|
| GitHub | Conta gratuita | GitHub Pro ou Team |
| GitHub Models | Acesso ao catálogo público | Modelos GPT-5, Mistral |
| Conhecimento | YAML básico | Experiência com GitHub Actions |
| Tempo | 15 min (método 1) | 1h (método 3 completo) |
Método 1: Ação integrada actions/ai-inference
O GitHub fornece uma ação built-in chamada actions/ai-inference. É o caminho mais rápido — você especifica um modelo do catálogo GitHub Models e pronto.
name: Bug Report Reproduction Check
on:
issues:
types: [opened]
permissions:
contents: read
issues: write
models: read
jobs:
reproduction-steps-check:
runs-on: ubuntu-latest
steps:
- name: Fetch Issue
id: issue
uses: actions/github-script@v7
with:
script: |
const issue_number = context.issue.number
const issue = await github.rest.issues.get({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number
})
core.setOutput('title', issue.data.title)
core.setOutput('body', issue.data.body)
- name: Analyze Issue For Reproduction
if: contains(join(github.event.issue.labels.*.name, ','), 'bug')
id: analyze-issue
uses: actions/ai-inference@v1
with:
model: mistral-ai/ministral-3b
system-prompt: |
Dado um título e corpo de bug report para uma aplicação web,
retorne 'pass' se houver informação suficiente para reproduzir
o problema (passos claros, comportamento esperado vs real,
ambiente). Se algo estiver faltando, retorne uma descrição
amigável do que está ausente.
prompt: |
Title: ${{ steps.issue.outputs.title }}
Body: ${{ steps.issue.outputs.body }}
- name: Comment On Issue
if: contains(join(github.event.issue.labels.*.name, ','), 'bug') && steps.analyze-issue.outputs.response != 'pass'
uses: actions/github-script@v7
env:
AI_RESPONSE: ${{ steps.analyze-issue.outputs.response }}
with:
script: |
const issue_number = context.issue.number
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number,
body: process.env.AI_RESPONSE
})Prós: Zero configuração além do YAML. Ideal para validar ideias rapidamente. Modelos gerenciados pelo GitHub. Sem dependências externas.
Contras: Flexibilidade limitada — você fica preso aos parâmetros expostos pela ação. Sem controle fino sobre temperatura, top_p ou outros hiperparâmetros. Modelos disponíveis são apenas os do catálogo GitHub Models.
Método 2: Extensão gh models
O gh é o sistema CLI do GitHub e suporta extensões. O gh models é a extensão para GitHub Models, oferecendo mais controle sobre como você invoca os modelos.
name: Bug Report Reproduction Check (GH Models)
on:
issues:
types: [opened]
permissions:
contents: read
issues: write
models: read
jobs:
reproduction-steps-check:
runs-on: ubuntu-latest
steps:
- name: Fetch Issue
id: issue
uses: actions/github-script@v7
# ... (mesmo do Método 1)
- name: Install gh-models extension
if: contains(join(github.event.issue.labels.*.name, ','), 'bug')
run: gh extension install https://github.com/github/gh-models
env:
GH_TOKEN: ${{ github.token }}
- name: Analyze Issue For Reproduction
if: contains(join(github.event.issue.labels.*.name, ','), 'bug')
id: analyze-issue
run: |
{
printf '%s\n' "Dado um título e corpo de bug report..."
printf 'Title: %s\n' "$ISSUE_TITLE"
printf 'Body: %s\n' "$ISSUE_BODY"
} > bug-report-prompt.md
response="$(gh models run openai/gpt-5 < bug-report-prompt.md)"
{
echo 'response<> "$GITHUB_OUTPUT"
env:
GH_TOKEN: ${{ github.token }}
ISSUE_TITLE: ${{ steps.issue.outputs.title }}
ISSUE_BODY: ${{ steps.issue.outputs.body }} Prós: Mais flexível que o método 1 — você controla exatamente como o prompt é construído. Pode usar qualquer modelo do catálogo, incluindo GPT-5. Permite lógica condicional complexa no shell script.
Contras: O maior problema é reusabilidade. Outras pessoas (e até você em outros projetos) não conseguem reutilizar facilmente. Cada workflow duplica a lógica de prompt e chamada ao modelo. Scripts em Bash inline são frágeis e difíceis de testar.
Método 3: Custom Action com JavaScript
Para transformar a capacidade em algo reutilizável e compartilhável, o caminho é desenvolver uma custom action. Você encapsula toda a lógica em JavaScript, empacota com ncc e publica no GitHub Marketplace.
Estrutura do projeto:
src/
├── checkBugReport.js # Lógica de IA
├── index.js # Entry point
└── main.js # Integração com GitHub ActionsCore: checkBugReport.js
const OpenAI = require("openai");
const endpoint = "https://models.github.ai/inference";
const model = "openai/gpt-5";
const systemPrompt =
"Dado um título e corpo de bug report para uma aplicação web, " +
"retorne 'pass' se houver informação suficiente para reproduzir " +
"o problema. Se algo estiver faltando, descreva o que falta.";
async function checkBugReport({ title, body, token }) {
const client = new OpenAI({ baseURL: endpoint, apiKey: token });
const completion = await client.chat.completions.create({
model,
messages: [
{ role: "system", content: systemPrompt },
{ role: "user", content: `Title: ${title}\nBody: ${body || ""}` },
],
});
const response = completion.choices[0]?.message?.content?.trim();
if (!response) {
throw new Error("GitHub Models retornou resposta vazia.");
}
return response;
}
module.exports = { checkBugReport };Integração: main.js
const { checkBugReport } = require("./checkBugReport");
const core = require("@actions/core");
async function run() {
try {
const title = core.getInput("title", { required: true });
const body = core.getInput("body");
const token = core.getInput("token", { required: true });
const response = await checkBugReport({ title, body, token });
core.setOutput("response", response);
} catch (error) {
core.setFailed(error instanceof Error ? error.message : String(error));
}
}
module.exports = { run };Entry point: index.js
const { run } = require("./main");
run();Empacotamento e declaração:
# Build
ncc build src/index.js -o dist
# action.yml
name: "Bug Reproduction Check Action"
description: "Verifica se um bug report tem informações suficientes"
inputs:
title:
description: "Título do bug report"
required: true
body:
description: "Corpo do bug report"
required: false
default: ""
token:
description: "Token para GitHub Models API"
default: ${{ github.token }}
outputs:
response:
description: "Resposta da IA sobre a reprodutibilidade"
runs:
using: node24
main: dist/index.jsUso no workflow:
name: Bug Report Reproduction Check (Custom Action)
on:
issues:
types: [opened]
permissions:
contents: read
issues: write
models: read
jobs:
reproduction-steps-check:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Fetch Issue
id: issue
uses: actions/github-script@v7
# ... (mesmo dos métodos anteriores)
- name: Analyze Issue For Reproduction
if: contains(join(github.event.issue.labels.*.name, ','), 'bug')
id: analyze-issue
uses: ./
with:
title: ${{ steps.issue.outputs.title }}
body: ${{ steps.issue.outputs.body }}
token: ${{ github.token }}Outros repositórios podem usar sua ação com uses: owner/repo@ref — basta referenciar o repositório onde ela está publicada.
Comparação dos três métodos
| Critério | actions/ai-inference | gh models | Custom Action |
|---|---|---|---|
| Velocidade de setup | ⚡ Instantâneo | 🔧 ~5 min | 🏗️ ~1h |
| Flexibilidade | ⚠️ Baixa | ✅ Média | ✅✅ Alta |
| Reusabilidade | ❌ Nenhuma | ❌ Nenhuma | ✅✅ Total |
| Modelos disponíveis | Catálogo GitHub | Catálogo GitHub | Qualquer API |
| Testabilidade | ❌ Só no workflow | ❌ Só no workflow | ✅ Testes unitários |
| Manutenção | ✅ GitHub mantém | ⚠️ Você mantém script | ⚠️ Você mantém código |
Casos de uso além do bug report
- Revisão de PR: IA analisa o diff e sugere melhorias de código, cobertura de testes ou potenciais bugs
- Geração de changelog: IA resume commits desde a última release em linguagem natural
- Classificação de issues: IA categoriza e prioriza issues automaticamente com base no conteúdo
- Validação de documentação: IA verifica se mudanças no código têm documentação correspondente atualizada
- Análise de segurança: IA revisa dependências atualizadas e sinaliza vulnerabilidades conhecidas
Qual escolher?
Se você quer testar rapidamente IA em um único projeto, os métodos 1 e 2 são suficientes. Se você quer produtizar e modularizar a capacidade para reutilização em múltiplos projetos no longo prazo — especialmente em times que mantêm dezenas de repositórios — investir em uma custom action é o caminho que escala.
O código completo dos três métodos está disponível no repositório github.com/baoqger/demo-models-in-actions.
Descubra mais sobre noticiAI
Assine para receber nossas notícias mais recentes por e-mail.



