Pular para o conteúdo principal

Configuração de Pipeline CI/CD no Cursor: Um Guia Completo

Pipeline CI/CD no Cursor

Pipelines de Integração Contínua e Entrega Contínua (CI/CD) automatizam o processo de build, teste e release, permitindo que as equipes entreguem código de forma segura e frequente. CI/CD moderno abrange múltiplas plataformas — GitHub Actions para projetos hospedados no GitHub, GitLab CI para repositórios GitLab, e Jenkins para pipelines auto-hospedados e altamente personalizáveis. O Cursor, com seu assistente de IA integrado e modelo de extensão compatível com VS Code, é um excelente editor para criar e manter configurações de pipeline. Ele pode gerar workflows a partir de prompts em linguagem natural, validar sintaxe YAML e refatorar pipelines conforme seu projeto evolui.

Este guia cobre o workflow completo de CI/CD no Cursor: configuração de GitHub Actions, GitLab CI e Jenkins, integração de testes automatizados, aproveitamento de IA para gerar e otimizar configurações de pipeline e seguimento de melhores práticas para automação segura e confiável.

Configurando Ferramentas de CI/CD no Cursor​

Extensões Essenciais​

O Cursor herda o ecossistema de extensões do VS Code. Instale estas para agilizar a criação de pipelines:

  1. YAML (da Red Hat) — validação de schema para GitHub Actions, GitLab CI e arquivos Docker Compose.
  2. GitHub Actions — destaque de sintaxe e snippets para arquivos de workflow.
  3. GitLab Workflow — validação GitLab CI e gerenciamento de MR.
  4. Docker — criação de Dockerfile e auxiliares de build de imagem.
dica

A extensão YAML baixa automaticamente schemas JSON para tipos de arquivo conhecidos. Quando você cria .github/workflows/deploy.yml, o Cursor valida a estrutura contra o schema oficial do GitHub Actions e oferece autocompletar para cada campo.

Estrutura de Projeto para CI/CD​

Um projeto pronto para CI/CD normalmente inclui:

project/
├── .github/
│ └── workflows/
│ ├── ci.yml
│ └── deploy.yml
├── .gitlab/
│ └── ci/
│ └── templates.yml
├── .jenkins/
│ └── Jenkinsfile
├── src/
├── tests/
├── Dockerfile
├── docker-compose.yml
└── package.json

GitHub Actions​

Criando Seu Primeiro Workflow​

O GitHub Actions usa arquivos YAML em .github/workflows/. Um workflow de CI básico é executado a cada push e pull request:

# .github/workflows/ci.yml
name: CI

on:
push:
branches: [main, develop]
pull_request:
branches: [main]

permissions:
contents: read

jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 20
cache: npm

- name: Install dependencies
run: npm ci

- name: Lint
run: npm run lint

- name: Type check
run: npm run type-check

- name: Run tests
run: npm test -- --coverage

- name: Upload coverage
if: always()
uses: actions/upload-artifact@v4
with:
name: coverage-report
path: coverage/
retention-days: 14
dica

Use npm ci em vez de npm install em CI. O comando ci instala versões exatas do lockfile, produzindo builds reproduzíveis e falhando rapidamente em caso de desvio do lockfile.

Builds em Matriz​

Teste em múltiplas versões do Node.js e sistemas operacionais com uma matriz:

jobs:
test:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
node-version: [18, 20, 22]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: npm
- run: npm ci
- run: npm test

Cache de Dependências​

Acelere workflows armazenando dependências e saídas de build em cache:

- name: Cache npm
uses: actions/cache@v4
with:
path: |
~/.npm
node_modules
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-
aviso

Chaves de cache baseadas apenas no hash do package-lock.json falharão quando o lockfile mudar. Inclua o OS e a versão do Node na chave para evitar contaminação cruzada entre ambientes de runner.

Workflows Reutilizáveis​

Divida workflows grandes em componentes reutilizáveis:

# .github/workflows/reusable-test.yml
name: Reusable Test

on:
workflow_call:
inputs:
node-version:
required: true
type: string

jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ inputs.node-version }}
cache: npm
- run: npm ci
- run: npm test

Chame-o de outro workflow:

jobs:
test:
uses: ./.github/workflows/reusable-test.yml
with:
node-version: 20

Workflow de Deployment​

Um job de deployment que é executado apenas no branch main:

# .github/workflows/deploy.yml
name: Deploy

on:
push:
branches: [main]

jobs:
deploy:
runs-on: ubuntu-latest
needs: test
environment:
name: production
url: https://app.example.com
steps:
- uses: actions/checkout@v4

- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::123456789012:role/github-deploy
aws-region: us-east-1

- name: Login to ECR
uses: aws-actions/amazon-ecr-login@v2

- name: Build and push
uses: docker/build-push-action@v6
with:
context: .
push: true
tags: |
123456789012.dkr.ecr.us-east-1.amazonaws.com/app:latest
123456789012.dkr.ecr.us-east-1.amazonaws.com/app:${{ github.sha }}

- name: Deploy to ECS
run: |
aws ecs update-service --cluster app-cluster --service app-service --force-new-deployment
aviso

Use GitHub Environments com revisores obrigatórios para deployments de produção. Isso adiciona um portão de aprovação manual antes da execução do job de deployment, evitando releases acidentais.

GitLab CI​

Configurando .gitlab-ci.yml​

O GitLab CI usa um único .gitlab-ci.yml na raiz do repositório:

# .gitlab-ci.yml
stages:
- lint
- test
- build
- deploy

variables:
NODE_VERSION: "20"
IMAGE_TAG: $CI_COMMIT_SHORT_SHA

cache:
key:
files:
- package-lock.json
paths:
- node_modules/

lint:
stage: lint
image: node:${NODE_VERSION}
script:
- npm ci
- npm run lint
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"

test:
stage: test
image: node:${NODE_VERSION}
script:
- npm ci
- npm test -- --coverage
artifacts:
reports:
coverage_report:
coverage_format: cobertura
path: coverage/cobertura-coverage.xml
coverage: '/Lines\s*:\s*(\d+\.\d+)%/'

build:
stage: build
image: docker:24
services:
- docker:24-dind
script:
- docker build -t $CI_REGISTRY_IMAGE:$IMAGE_TAG .
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- docker push $CI_REGISTRY_IMAGE:$IMAGE_TAG
rules:
- if: $CI_COMMIT_BRANCH == "main"

deploy:production:
stage: deploy
image: registry.gitlab.com/gitlab-org/cloud-deploy/aws-ecs:latest
script:
- ecs update-task-definition --cluster app-cluster --service app-service --image $CI_REGISTRY_IMAGE:$IMAGE_TAG
environment:
name: production
url: https://app.example.com
rules:
- if: $CI_COMMIT_BRANCH == "main"
when: manual
dica

A palavra-chave rules do GitLab CI substitui a antiga sintaxe only/except. Use rules com condições if para controle granular de quando os jobs são executados e combine com changes para acionar jobs apenas quando arquivos relevantes são modificados.

Templates do GitLab CI​

Divida pipelines complexos em arquivos de inclusão:

# .gitlab/ci/test.yml
.test-template:
stage: test
image: node:${NODE_VERSION}
before_script:
- npm ci
script:
- npm test

Inclua-os:

include:
- local: .gitlab/ci/test.yml

unit-test:
extends: .test-template
script:
- npm run test:unit

Jobs Paralelos e em Matriz​

test:
stage: test
image: node:${NODE_VERSION}
parallel:
matrix:
- NODE_VERSION: ["18", "20", "22"]
OS: ["alpine", "slim"]
script:
- npm ci
- npm test

Jenkins​

Escrevendo um Jenkinsfile​

Pipelines do Jenkins usam uma DSL baseada em Groovy em um Jenkinsfile:

// Jenkinsfile
pipeline {
agent {
docker {
image 'node:20-alpine'
args '-v $HOME/.npm:/root/.npm'
}
}

environment {
NODE_ENV = 'production'
DOCKER_IMAGE = "registry.example.com/app:${env.BUILD_NUMBER}"
}

options {
timeout(time: 30, unit: 'MINUTES')
disableConcurrentBuilds()
buildDiscarder(logRotator(numToKeepStr: '20'))
}

stages {
stage('Checkout') {
steps {
checkout scm
}
}

stage('Install') {
steps {
sh 'npm ci'
}
}

stage('Lint') {
steps {
sh 'npm run lint'
}
}

stage('Test') {
steps {
sh 'npm test -- --coverage'
}
post {
always {
junit 'reports/junit.xml'
publishHTML(target: [
reportDir: 'coverage/lcov-report',
reportFiles: 'index.html',
reportName: 'Coverage Report'
])
}
}
}

stage('Build') {
steps {
sh 'npm run build'
}
}

stage('Deploy') {
when {
branch 'main'
}
steps {
sh "docker build -t ${DOCKER_IMAGE} ."
sh "docker push ${DOCKER_IMAGE}"
sh "kubectl rollout restart deployment/app -n production"
}
}
}

post {
failure {
emailext subject: "Build failed: ${env.JOB_NAME} #${env.BUILD_NUMBER}",
body: "Check the build at ${env.BUILD_URL}",
}
success {
slackSend channel: '#deploys',
message: "Build succeeded: ${env.JOB_NAME} #${env.BUILD_NUMBER}"
}
}
}
aviso

Jenkinsfiles são executados com as permissões do controlador Jenkins. Nunca use sh para invocar comandos que incluem entrada não confiável e sempre cite variáveis interpoladas para prevenir injeção de shell.

Pipeline Declarativo vs Scriptado​

O exemplo acima usa sintaxe declarativa. Para lógica complexa, mude para blocos scriptados:

stage('Conditional Deploy') {
steps {
script {
def env = params.ENVIRONMENT
if (env == 'production') {
input(message: 'Approve production deployment?', ok: 'Deploy')
}
sh "./deploy.sh ${env}"
}
}
}

Bibliotecas Compartilhadas do Jenkins​

Para lógica de pipeline reutilizável, defina uma biblioteca compartilhada:

// vars/npmPipeline.groovy
def call(Map config = [:]) {
pipeline {
agent any
stages {
stage('Install') {
steps {
sh 'npm ci'
}
}
stage('Test') {
steps {
sh 'npm test'
}
}
stage('Build') {
steps {
sh 'npm run build'
}
}
}
}
}

Use-a em um Jenkinsfile:

@Library('my-shared-lib') _

npmPipeline(nodeVersion: '20')

Testes Automatizados em Pipelines​

Testes Unitários​

- name: Run unit tests
run: npm run test:unit -- --reporter=junit --outputFile=reports/junit.xml

Publique os resultados no GitHub Actions:

- name: Publish test results
uses: dorny/test-reporter@v1
if: always()
with:
name: Unit Tests
path: reports/junit.xml
reporter: java-junit

Testes de Integração​

Execute testes de integração contra um contêiner de serviço de banco de dados:

jobs:
integration:
runs-on: ubuntu-latest
services:
postgres:
image: postgres:16
env:
POSTGRES_PASSWORD: test
POSTGRES_DB: app_test
ports:
- 5432:5432
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
- run: npm ci
- run: npm run test:integration
env:
DATABASE_URL: postgresql://postgres:test@localhost:5432/app_test
dica

Contêineres de serviço no GitHub Actions fornecem bancos de dados descartáveis para testes de integração. Sempre inclua verificações de saúde (--health-cmd) para que seus testes não comecem antes que o banco de dados esteja pronto.

Testes de Ponta a Ponta​

Execute testes E2E do Playwright em CI:

e2e:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
- run: npm ci
- name: Install Playwright browsers
run: npx playwright install --with-deps
- name: Run E2E tests
run: npx playwright test
- name: Upload report
if: always()
uses: actions/upload-artifact@v4
with:
name: playwright-report
path: playwright-report/

Análise de Segurança​

Adicione análise de dependências e código:

- name: Run audit
run: npm audit --audit-level=high

- name: CodeQL analysis
uses: github/codeql-action/init@v3
with:
languages: javascript-typescript

- name: Perform analysis
uses: github/codeql-action/analyze@v3

- name: Trivy container scan
uses: aquasecurity/trivy-action@master
with:
image-ref: app:latest
severity: CRITICAL,HIGH

Configuração de Pipeline Assistida por IA​

Gerando Workflows a partir de Prompts​

A IA do Cursor gera arquivos de pipeline completos a partir de descrições. Abra Ctrl+K em um novo arquivo .yml e insira o prompt:

Create a GitHub Actions workflow that: runs on push to main and on PRs,
sets up Node 20, installs dependencies with npm ci, runs lint, type-check,
and tests with coverage, builds a Docker image, pushes it to GitHub
Container Registry, and deploys to a Kubernetes cluster using kubectl.
Use caching and environment protections.

O Cursor produz um workflow completo e válido. Revise as permissões e segredos, depois refine pedindo testes em matriz ou notificações Slack.

dica

Ao inserir prompts para configuração de CI/CD, especifique a plataforma e versão exatas. "GitHub Actions com Node 20 e Docker buildx" produz uma saída muito melhor do que "um pipeline CI para meu app Node".

Otimizando Pipelines Existentes​

O Cursor pode analisar e otimizar pipelines lentos. Destaque o arquivo de workflow e insira o prompt:

Analyze this GitHub Actions workflow and suggest optimizations to reduce
runtime. Identify: missing cache opportunities, jobs that could run in
parallel, oversized images, and unnecessary steps.

Otimizações comuns que a IA sugere:

  • Adicionar cache de dependências.
  • Dividir lint, teste e build em jobs paralelos.
  • Usar cache de camadas Docker.
  • Cancelar execuções obsoletas para o mesmo branch.

Gerando Testes de Pipeline​

Use act para executar o GitHub Actions localmente antes de fazer push:

# Install act
brew install act

# Run a specific workflow locally
act -j test -W .github/workflows/ci.yml

Insira o prompt no Cursor: "Gere um conjunto de eventos de teste e segredos simulados para executar este workflow localmente com act."

Gerenciamento de Segredos​

Segredos do GitHub Actions​

Armazene segredos nas configurações do repositório ou ambiente, nunca no código:

- name: Deploy
env:
API_KEY: ${{ secrets.API_KEY }}
DATABASE_URL: ${{ secrets.DATABASE_URL }}
run: ./deploy.sh
aviso

O GitHub mascara valores de segredo nos logs, mas logging estruturado pode vazá-los se um segredo aparecer como parte de uma string maior. Evite registrar corpos de requisição completos que possam conter tokens e use o contexto secrets apenas em env ou with — nunca em scripts run onde podem ser ecoados.

Variáveis do GitLab CI​

deploy:
variables:
DATABASE_URL: $CI_DATABASE_URL
script:
- ./deploy.sh

Marque variáveis como "mascaradas" e "protegidas" na interface do GitLab para que apareçam apenas em branches protegidos.

Credenciais do Jenkins​

Use o Credentials Store em vez de variáveis de ambiente:

withCredentials([string(credentialsId: 'api-key', variable: 'API_KEY')]) {
sh './deploy.sh'
}

Melhores Práticas de CI/CD no Cursor​

Mantenha os Pipelines Rápidos​

  • Armazenar dependências e saídas de build em cache.
  • Executar jobs independentes em paralelo.
  • Usar cache de camadas Docker para builds de imagem.
  • Cancelar execuções em andamento quando um novo commit é feito push.
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

Falhe Rápido e Alto​

  • Executar lint e type-check antes dos testes.
  • Usar fail-fast: true em jobs de matriz onde uma falha invalida os demais.
  • Enviar notificações em caso de falha (Slack, email, Teams).

Fixar Versões de Actions​

# EVITAR — latest pode quebrar inesperadamente
- uses: actions/checkout@v4

# PREFERIR — fixar em um SHA de commit para reprodutibilidade
- uses: actions/[email protected]
dica

Fixe actions de terceiros em um SHA de commit completo, não em uma tag. Tags podem ser movidas por mantenedores, o que é um risco de segurança da cadeia de suprimentos. Fixação por SHA garante o código exato que é executado.

Usar Environments para Promoção​

O GitHub Environments fornece regras de proteção, revisores obrigatórios e rastreamento de deployment:

deploy:staging:
environment: staging

deploy:production:
needs: deploy:staging
environment:
name: production
url: https://app.example.com

Depurando Pipelines​

Reexecutar Jobs Falhados​

O GitHub Actions permite reexecutar apenas jobs falhados, economizando tempo e recursos computacionais:

gh run rerun <run-id> --failed

Ativar Logging de Depuração​

- name: Debug step
env:
ACTIONS_STEP_DEBUG: true
run: echo "Detailed logs enabled"

Defina o segredo do repositório ACTIONS_STEP_DEBUG como true para logs detalhados do runner.

Validar YAML Localmente​

Use a extensão YAML do Cursor para validar a sintaxe enquanto digita. Para validação mais profunda, use actionlint:

brew install actionlint
actionlint .github/workflows/*.yml
dica

O Cursor pode executar actionlint ao salvar com uma configuração de tarefas. Adicione uma entrada .vscode/tasks.json que executa actionlint no arquivo atual e exibe erros no painel de Problemas.

Armadilhas Comuns e Como Evitá-las​

Caches Desatualizados​

Um cache que nunca é invalidado pode mascarar mudanças de dependências. Sempre inclua o hash do lockfile na chave:

key: ${{ runner.os }}-npm-${{ hashFiles('**/package-lock.json') }}

Crescimento Ilimitado de Jobs​

Sem rotação de logs, builds antigos se acumulam. Configure a retenção:

# GitHub: configurar nas configurações do repositório
# Jenkins:
options {
buildDiscarder(logRotator(numToKeepStr: '20'))
}

Falta de if: always() em Artefatos​

Artefatos de um job falhado não são carregados por padrão. Adicione if: always() para capturar relatórios de teste e cobertura mesmo em caso de falha.

aviso

Tenha cuidado com if: always() em etapas de deployment — você não quer fazer deploy após um teste falhado. Use condições específicas como if: success() && github.ref == 'refs/heads/main'.

Segredos em Logs​

Nunca faça echo de segredos. Mesmo mascarados, vazamentos parciais ocorrem quando segredos são substrings de outras saídas. Use ferramentas de análise de segredos e revise os logs manualmente no primeiro deployment.

Resumo​

O Cursor é um editor poderoso para criar e manter pipelines CI/CD no GitHub Actions, GitLab CI e Jenkins. A extensão YAML fornece validação de schema, contêineres de serviço permitem testes de integração, e o assistente de IA gera, otimiza e depura configurações de pipeline a partir de prompts em linguagem natural. Comece scaffoldando um workflow de CI, adicione testes automatizados e análises de segurança, e deixe a IA do Cursor lidar com a configuração repetitiva enquanto você se concentra em entregar deployments confiáveis, rápidos e seguros.