Alternar tema

Desenvolvendo Composite Actions no GitHub Actions: do action.yml ao Marketplace

Easton editorial illustration: action.yml package assembled from inputs, steps, outputs, and secrets then shipped to a marketplace shelf

Voce esta olhando para o 15o log de workflow com erro na tela. Qual foi a causa? Em algum repositorio privado, o step npm install esqueceu de adicionar NODE_AUTH_TOKEN.

Esta ja e a terceira vez na semana. Existem oito repositorios, e cada um copiou e colou quase a mesma configuracao de workflow: checkout, setup-node, install, build, test. Quando voce muda um ponto, precisa sincronizar os oito repositorios. Em um dia qualquer, ao atualizar a versao do Node, cinco repositorios foram alterados, mas tres ficaram para tras.

Nesse momento, fica claro: nao da para continuar assim. As Composite Actions do GitHub Actions nasceram para isso: empacotar steps repetidos em um componente reutilizavel, que pode ser chamado em varios workflows como se fosse uma funcao. Neste artigo, vamos do desenvolvimento da primeira Composite Action ate a publicacao no Marketplace, para dominar uma habilidade central da componentizacao em CI/CD.

Capitulo 1: conceitos essenciais de Composite Actions

1.1 O que e uma Composite Action

Composite Action e um mecanismo de componentizacao oferecido pelo GitHub Actions. Ela encapsula varios steps em uma Action independente, que pode ser reutilizada em workflows diferentes.

Ao contrario de uma JavaScript Action ou Docker Action, uma Composite Action nao exige que voce escreva codigo. Voce so precisa criar uma configuracao YAML, definir uma serie de steps, e o GitHub executa tudo automaticamente. Em termos simples, uma Composite Action e um “encapsulamento de funcao” para um conjunto de steps.

A definicao oficial funciona assim: uma Composite Action usa runs.using: "composite" como identificador, e todos os steps rodam no mesmo Runner. Isso significa que voce pode acessar diretamente o diretorio de trabalho, variaveis de ambiente e ate chamar outras Actions.

1.2 Comparacao entre tres tipos de Action

O GitHub Actions suporta tres tipos de Action:

TipoForma de implementacaoCenario indicado
JavaScript ActionEscrever codigo JS/TSQuando ha logica complexa ou chamadas de API
Docker ActionEscrever um DockerfileQuando ha ambiente ou dependencias especificas
Composite ActionConfiguracao em YAML puroQuando voce combina steps existentes e quer reutilizacao rapida

A vantagem de uma Composite Action e bem direta: zero codigo, desenvolvimento rapido e manutencao simples. Voce nao precisa lidar com empacotamento, compilacao ou gerenciamento de dependencias; basta escrever YAML.

1.3 Composite Action vs reusable workflow

Este e um ponto que confunde muita gente. A primeira vista, os dois recursos parecem tratar de “reutilizacao”, mas a essencia e diferente:

Composite Action e um grupo de steps. Ela executa dentro de um Job, usa o Runner de quem a chamou e precisa receber Secrets explicitamente.

Reusable workflow e uma pipeline completa. Ele cria um Job independente, pode ter seu proprio Runner e consegue herdar Secrets automaticamente.

Um exemplo: se voce quer empacotar “instalar dependencias + rodar testes” para reutilizar, use Composite Action. Se quer padronizar todo o pipeline de “build -> teste -> deploy”, use reusable workflow. O quarto capitulo faz essa comparacao em detalhes.

Capitulo 2: desenvolvendo a primeira Composite Action

2.1 Estrutura do action.yml em detalhes

O centro de uma Composite Action e o arquivo action.yml. Ele e um arquivo de metadados que define o nome da Action, entradas, saidas e steps de execucao.

Veja primeiro um exemplo minimo:

name: 'Hello World'
description: 'A simple composite action'
runs:
  using: "composite"
  steps:
    - run: echo "Hello from composite action!"
      shell: bash

Essa Action faz apenas uma coisa: imprime uma linha de texto. Em projetos reais, porem, precisamos de parametrizacao e outputs.

2.2 Exemplo completo de action.yml

Abaixo esta uma Composite Action utilizavel na pratica, voltada a build e testes de um projeto Node.js:

name: 'Build and Test'
description: 'Install dependencies, build project, and run tests'
author: 'Your Name'

inputs:
  node-version:
    description: 'Node.js version to use'
    required: true
    default: '20'
  install-command:
    description: 'Command to install dependencies'
    required: false
    default: 'npm ci'
  build-command:
    description: 'Command to build the project'
    required: false
    default: 'npm run build'
  test-command:
    description: 'Command to run tests'
    required: false
    default: 'npm test'

outputs:
  build-path:
    description: 'Path to the build output'
    value: ${{ steps.build.outputs.path }}
  test-coverage:
    description: 'Test coverage percentage'
    value: ${{ steps.coverage.outputs.value }}

runs:
  using: "composite"
  steps:
    - name: Setup Node.js
      uses: actions/setup-node@v4
      with:
        node-version: ${{ inputs.node-version }}
        cache: 'npm'

    - name: Install dependencies
      run: ${{ inputs.install-command }}
      shell: bash

    - name: Build project
      id: build
      run: |
        ${{ inputs.build-command }}
        echo "path=dist" >> $GITHUB_OUTPUT
      shell: bash

    - name: Run tests
      id: coverage
      run: |
        ${{ inputs.test-command }}
        echo "value=85" >> $GITHUB_OUTPUT
      shell: bash

2.3 Campos em detalhes

inputs: define os parametros recebidos pela Action. Cada parametro pode especificar:

  • description: descricao do parametro, exibida no Marketplace
  • required: se o parametro e obrigatorio
  • default: valor padrao

outputs: define as saidas da Action. Elas sao passadas pela variavel de ambiente $GITHUB_OUTPUT. Atencao ao formato:

echo "name=value" >> $GITHUB_OUTPUT

runs.steps: define os steps de execucao. Eles se parecem com steps de workflows comuns, mas ha duas diferencas importantes:

  1. O shell precisa ser declarado explicitamente. Todo comando run deve ter shell: bash ou sh/pwsh. Essa e uma exigencia obrigatoria das Composite Actions.

  2. Voce pode chamar outras Actions com uses. O exemplo acima usa actions/setup-node@v4.

2.4 Armadilhas comuns

Durante o desenvolvimento, eu ja tropecei em alguns pontos:

Armadilha 1: inputs nao tem campo type

Inputs de Composite Actions aceitam apenas string. Nao da para definir type: boolean ou type: number como em reusable workflows. Se voce precisa de um booleano, so pode passar a string "true" ou "false" e avaliar isso dentro do step.

Armadilha 2: shell precisa ser declarado explicitamente

Em workflows comuns, o comando run pode omitir shell, e o GitHub escolhe automaticamente com base no Runner. Em Composite Actions, o shell precisa ser informado explicitamente; caso contrario, o workflow falha.

Armadilha 3: outputs precisam ser referenciados por step id

O campo value de uma saida precisa referenciar o output de um step:

outputs:
  my-output:
    value: ${{ steps.my-step.outputs.result }}

E o step precisa definir um id:

- id: my-step
  run: echo "result=hello" >> $GITHUB_OUTPUT

Capitulo 3: usando uma Composite Action

3.1 Referencia local

A forma mais simples de uso e referenciar a Action dentro do mesmo repositorio. Suponha que sua Action esteja em .github/actions/build-test/action.yml:

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      # Referencia local
      - uses: ./.github/actions/build-test
        with:
          node-version: '20'
          test-command: 'npm run test:ci'

O caminho comeca com ./ e e relativo a raiz do repositorio. Essa abordagem e adequada para reutilizacao interna da equipe e nao exige publicacao no Marketplace.

3.2 Referencia entre repositorios

Se voce quer compartilhar a Action entre varios repositorios, pode coloca-la em um repositorio independente e referencia-la de outro repositorio:

steps:
  # Referencia uma Action compartilhada da organizacao
  - uses: your-org/shared-actions/build@v1
    with:
      node-version: '18'

O formato do caminho e owner/repo/path@version. Nesse formato, path e o caminho relativo da Action dentro do repositorio.

Design recomendado para um repositorio organizacional de Actions:

shared-actions/
├── build/
│   └── action.yml        # Relacionado a build
├── deploy/
│   └── action.yml        # Relacionado a deploy
├── lint/
│   └── action.yml        # Verificacao de codigo
└── README.md

Assim, a referencia fica bem clara:

  • your-org/shared-actions/build@v1
  • your-org/shared-actions/deploy@v1

3.3 Uso a partir do Marketplace

Depois da publicacao no Marketplace, usuarios podem pesquisar e referenciar diretamente:

steps:
  # Supondo que sua Action tenha sido publicada como "build-test-action"
  - uses: your-org/[email protected]
    with:
      node-version: '20'

O Marketplace oferece escolha de versao, estatisticas de uso, exibicao do README e outros recursos. Ele e indicado para projetos open source ou Actions compartilhadas publicamente.

3.4 Estrategia de escolha de versao

Ao referenciar uma Action, existem tres formas de escolher a versao:

# Forma 1: commit SHA (mais seguro e imutavel)
- uses: your-org/action@a1b2c3d4e5f6...

# Forma 2: tag de versionamento semantico (recomendado)
- uses: your-org/[email protected]

# Forma 3: major tag (acompanha automaticamente a versao v1.x mais recente)
- uses: your-org/action@v1

# Nao recomendado: latest tag (pode fazer upgrade inesperado)
# - uses: your-org/action@latest

Recomendacao de seguranca:

Para ambientes de producao, usar commit SHA e a escolha mais segura. Como o SHA e imutavel, ele nao muda por causa de uma atualizacao de tag feita por quem mantem a Action.

Para projetos internos, usar uma major tag, como @v1, e uma escolha flexivel. Ela acompanha automaticamente a versao v1.x mais recente e recebe correcoes de bug e novos recursos.

Evite usar @latest. Ele pode causar upgrades inesperados e quebrar o build.

Capitulo 4: Composite Action vs reusable workflow

4.1 Tabela de comparacao funcional

Esta e a referencia central na hora de escolher:

DimensaoComposite ActionReusable workflow
Nivel de execucaoGrupo de steps dentro de um JobJob independente
RunnerUsa o Runner de quem chamaCria novo Runner ou usa o especificado
SecretsPrecisam ser passados explicitamentePodem ser herdados automaticamente
Tipos de entradaApenas stringboolean / number / string
Passagem de outputs$GITHUB_OUTPUToutputs + workflow_call
Controle de concorrenciaHerda os limites de quem chamaPode ser configurado de forma independente
Variaveis de ambienteHerdadas + adicionaveisEscopo independente
Cenario indicadoEncapsulamento de funcao unicaPadronizacao do pipeline inteiro

4.2 Matriz de decisao

Escolha a forma de reutilizacao conforme o cenario:

Use Composite Action:

  • Para empacotar steps repetidos de build, teste ou deploy
  • Quando precisa interagir com outros steps dentro do Job
  • Quando quer manter a flexibilidade do workflow e reutilizar apenas uma parte dos steps
  • Quando a passagem de Secrets deve ser controlada e a seguranca e importante

Use reusable workflow:

  • Para padronizar todo o pipeline de CI/CD
  • Quando varios projetos precisam do mesmo fluxo completo
  • Quando precisa herdar Secrets automaticamente e reduzir configuracao
  • Quando precisa de configuracoes de nivel de workflow, como if e timeout-minutes

Use os dois em conjunto:

Na pratica, a melhor abordagem e combinar os dois. Um reusable workflow pode chamar uma Composite Action:

# .github/workflows/ci.yml (reusable workflow)
on:
  workflow_call:
    inputs:
      node-version:
        type: string
        default: '20'

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      # Chama a Composite Action
      - uses: ./.github/actions/build-test
        with:
          node-version: ${{ inputs.node-version }}

Assim, voce tem a configuracao padrao em nivel de workflow e tambem a reutilizacao de steps em nivel de Action.

Capitulo 5: versionamento e publicacao

5.1 Boas praticas com Git Tags

O centro da publicacao de uma Action e o gerenciamento de Git Tags. A recomendacao e usar uma estrategia dupla: versionamento semantico + major tag.

# Cria uma tag de versionamento semantico
git tag -a v1.0.0 -m "Initial release"
git push origin v1.0.0

# Cria a major tag (acompanha a versao v1.x mais recente)
git tag -fa v1 -m "Update v1 tag to latest"
git push origin v1 --force

Ao publicar v1.1.0, atualize a major tag:

git tag -a v1.1.0 -m "Add new feature"
git push origin v1.1.0

# Atualiza a tag v1 para apontar para a versao mais recente
git tag -fa v1 -m "Update v1 tag to v1.1.0"
git push origin v1 --force

Assim, usuarios podem escolher:

  • usar @v1.1.0 para fixar uma versao especifica
  • usar @v1 para receber automaticamente atualizacoes da linha v1.x

5.2 Fluxo de publicacao no Marketplace

Para publicar no GitHub Marketplace, voce precisa:

1. Preparar o README.md

O README precisa conter:

  • nome e descricao da Action
  • explicacao de Inputs e Outputs
  • exemplos de uso
  • licenca

2. Preparar o action.yml

Confira se os campos name, description, author e branding opcional estao completos.

3. Criar uma Release

Na pagina do repositorio no GitHub:

  1. Clique em “Releases” -> “Draft a new release”
  2. Escolha uma tag, como v1.0.0
  3. Escreva as Release Notes
  4. Marque “Publish this Action to the GitHub Marketplace”
  5. Publique

O GitHub valida automaticamente o action.yml e publica a Action no Marketplace.

5.3 Workflow de publicacao automatizada

Voce pode criar um workflow para automatizar a publicacao:

name: Release Action

on:
  push:
    tags:
      - 'v*'

jobs:
  release:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Update major tag
        run: |
          # Extrai o numero da versao major
          MAJOR=$(echo $GITHUB_REF | sed 's/refs\/tags\/v\([0-9]*\).*/\1/')
          
          # Atualiza a major tag
          git config user.name github-actions
          git config user.email [email protected]
          git tag -fa v$MAJOR -m "Update v$MAJOR tag"
          git push origin v$MAJOR --force

      - name: Create GitHub Release
        uses: softprops/action-gh-release@v1
        with:
          generate_release_notes: true

Esse workflow atualiza automaticamente a major tag e cria a Release quando uma tag e enviada.

Capitulo 6: tecnicas avancadas e boas praticas

6.1 Passagem segura de Secrets

Uma Composite Action nao consegue acessar diretamente o contexto secrets. A passagem precisa ser explicita:

# No workflow
jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: ./.github/actions/deploy
        with:
          token: ${{ secrets.DEPLOY_TOKEN }}
        env:
          AWS_ACCESS_KEY: ${{ secrets.AWS_ACCESS_KEY }}
# No action.yml
inputs:
  token:
    description: 'Deploy token'
    required: true

runs:
  using: "composite"
  steps:
    - run: deploy --token ${{ inputs.token }}
      shell: bash
      env:
        AWS_ACCESS_KEY: ${{ env.AWS_ACCESS_KEY }}

Recomendacoes de seguranca:

  • Nao passe informacoes sensiveis por inputs quando houver risco de exposicao em logs
  • Use env para passar informacoes sensiveis, pois os valores sao mascarados
  • Explique claramente no README quais Secrets sao necessarios

6.2 Usar scripts locais

Logica complexa nao combina bem com YAML. Voce pode colocar arquivos de script no diretorio da Action:

.github/actions/build-test/
├── action.yml
└── scripts/
    └── build.sh

No action.yml, chame o script:

runs:
  using: "composite"
  steps:
    - run: $GITHUB_ACTION_PATH/scripts/build.sh
      shell: bash

$GITHUB_ACTION_PATH e o caminho do diretorio raiz da Composite Action.

6.3 Design de repositorio organizacional de Actions

Para equipes, vale centralizar o gerenciamento de Actions compartilhadas:

your-org/shared-actions/
├── .github/
│   └── workflows/
│       └── test.yml       # Testa todas as Actions
├── build/
│   ├── action.yml
│   └── README.md
├── deploy/
│   ├── action.yml
│   └── README.md
├── lint/
│   ├── action.yml
│   └── README.md
└── README.md

Cada subdiretorio e uma Action independente, com README e testes completos.

6.4 Armadilhas comuns e tecnicas de depuracao

Armadilha 1: limite de profundidade de aninhamento

Uma Composite Action pode chamar outra Composite Action ate a profundidade maxima de 10 niveis. Acima disso, ocorre erro. A recomendacao e nao passar de 3 niveis, porque a depuracao fica dificil.

Armadilha 2: escopo de variaveis de ambiente

O env em uma Composite Action so vale dentro do step. Se voce precisa compartilhar entre steps, use GITHUB_ENV:

steps:
  - run: echo "MY_VAR=value" >> $GITHUB_ENV
    shell: bash
  - run: echo $MY_VAR  # Pode acessar
    shell: bash

Tecnicas de depuracao:

  1. Use ACTIONS_STEP_DEBUG=true para ativar logs detalhados
  2. Adicione echo nos steps para imprimir variaveis
  3. Use a Action tmate para depuracao via SSH, mas nao em producao

Conclusao

Composite Action e uma ferramenta central para componentizar o GitHub Actions. Ela ajuda voce a deixar de repetir configuracoes e a encapsular steps de CI como se estivesse escrevendo funcoes.

Lembre-se de tres pontos:

Estrutura clara: action.yml define inputs, outputs e steps, como a assinatura de uma funcao. A parametrizacao deixa a Action mais flexivel, e os outputs permitem que quem chama obtenha resultados.

Escolha correta: Composite Action encapsula uma funcao unica, como build, teste ou deploy; reusable workflow padroniza o pipeline inteiro. A combinacao dos dois costuma trazer o melhor resultado.

Versionamento seguro: commit SHA e o mais seguro para producao. major tag e flexivel para projetos internos. Evite latest.

Proximo passo: crie a primeira Composite Action no seu projeto, empacote os steps repetidos de build-test e depois tente publicar no Marketplace para compartilhar com a equipe ou a comunidade.

Desenvolver uma Composite Action no GitHub Actions

Crie do zero uma Composite Action reutilizavel para empacotar etapas de build e teste.

⏱️ Estimated time: 30 min

  1. 1

    Step 1: Criar a estrutura de diretorios da Action

    Crie no repositorio o diretorio da Composite Action:

    • mkdir -p .github/actions/build-test
    • crie o arquivo action.yml
  2. 2

    Step 2: Escrever a configuracao do action.yml

    Defina inputs, outputs e etapas de execucao:

    • inputs definem parametros, como node-version e test-command
    • outputs definem saidas, como build-path e coverage
    • runs.steps precisa declarar shell: bash explicitamente
  3. 3

    Step 3: Testar a referencia local

    Referencie e teste no workflow:

    • uses: ./.github/actions/build-test
    • with: node-version: '20'
    • publique somente depois que o teste local passar
  4. 4

    Step 4: Criar Git Tags

    Use versionamento semantico + major tag:

    • git tag -a v1.0.0 -m 'Initial release'
    • git tag -fa v1 -m 'Update v1 tag'
    • git push origin v1.0.0 v1
  5. 5

    Step 5: Publicar no Marketplace

    Publique pela interface do GitHub:

    • Releases -> Draft a new release
    • escolha uma tag, como v1.0.0
    • marque Publish to Marketplace
    • o GitHub valida e publica automaticamente

FAQ

Qual e a diferenca entre Composite Action e reusable workflow?
Composite Action e um grupo de steps dentro de um Job, usa o Runner de quem chama e exige passagem explicita de Secrets. Reusable workflow cria um Job independente e pode herdar Secrets automaticamente. Use Composite Action para encapsular uma funcao unica e reusable workflow para padronizar o pipeline inteiro.
Por que inputs de uma Composite Action nao tem o campo type?
Inputs de Composite Actions aceitam apenas string. Nao da para definir boolean ou number como em reusable workflows. Se precisar de um booleano, passe a string 'true' ou 'false' e faca a verificacao dentro do step.
Como passar Secrets para uma Composite Action?
Composite Actions nao acessam diretamente o contexto secrets, entao a passagem precisa ser explicita. Voce pode passar por inputs, com valores mascarados nos logs, ou por env, que costuma ser mais seguro porque o valor nao aparece diretamente no log.
Ao referenciar uma Action, devo usar commit SHA ou tag?
Em producao, use commit SHA, pois e a opcao mais segura e imutavel. Em projetos internos, uma major tag como @v1 e mais flexivel e acompanha a versao mais recente. Evite @latest, que pode causar upgrades inesperados e quebrar builds.
Qual e a profundidade maxima de aninhamento de Composite Actions?
Uma Composite Action pode chamar outra Composite Action ate a profundidade maxima de 10 niveis. Na pratica, e melhor nao passar de 3 niveis, porque aninhamento profundo dificulta a depuracao.
Uma Composite Action precisa declarar shell explicitamente?
Sim. Em uma Composite Action, todo step com comando run precisa ter shell: bash, sh ou pwsh. Essa e uma exigencia obrigatoria; workflows comuns podem omitir o shell, mas Composite Actions nao.

12 min de leitura · Publicado em: 6 mai 2026 · Atualizado em: 14 jul 2026

Comentários

Entre com GitHub para comentar

Easton BlogEaston Blog