Criar uma ação personalizada do GitHub

Concluído

O GitHub Actions é um recurso avançado que ajuda você a ir do código à nuvem, tudo isso no conforto e na conveniência de seu repositório. Aqui você aprenderá sobre os diferentes tipos de ações do GitHub e os metadados, a sintaxe e os comandos de fluxo de trabalho para criar ações personalizadas do GitHub.

Tipos de ações do GitHub

Diagrama dos três tipos de GitHub Actions; Ações de etapas de execução do Docker, JavaScript e composição.

As ações são tarefas individuais que você pode usar para personalizar seus fluxos de trabalho de desenvolvimento. Você pode criar suas ações escrevendo código personalizado que interage com seu repositório para executar tarefas personalizadas ou usando ações compartilhadas pela comunidade do GitHub. Navegando por várias ações, você observará que há três tipos diferentes delas: ações de contêiner do Docker, ações de JavaScript e ações de etapas de execução compostas. Vamos examinar cada tipo de ação em mais detalhes.

Ações de contêiner do Docker

Os contêineres do Docker empacotam o ambiente com o código do GitHub Actions. Isso significa que a ação é executada em um ambiente consistente e confiável porque todas as suas dependências estão dentro desse contêiner. Se a ação precisar ser executada em uma configuração de ambiente específica, os contêineres do Docker serão uma boa opção, pois você pode personalizar o sistema operacional e as ferramentas. A desvantagem é que, como o trabalho precisa criar e recuperar o contêiner, as ações de contêiner do Docker geralmente são mais lentas do que as ações de JavaScript.

Antes de criar uma ação de contêiner do Docker, você deve ter um entendimento básico de como usar as variáveis de ambiente e o sistema de arquivos de contêiner do Docker. As etapas para criar uma ação de contêiner do Docker são mínimas e diretas:

  1. Crie um Dockerfile para definir os comandos a fim de montar a imagem do Docker.
  2. Crie um arquivo de metadados action.yml para definir as entradas e saídas da ação. Defina o valor runs: using: como docker e o valor runs: image: como Dockerfile no arquivo.
  3. Crie um arquivo entrypoint.sh para descrever a imagem do Docker.
  4. Confirme e efetue push da sua ação para o GitHub com os seguintes arquivos: action.yml, entrypoint.shDockerfile e README.md.

Ações de JavaScript

As ações de JavaScript podem ser executadas diretamente no computador executor e separar o código de ação do ambiente usado para executar a ação. Por isso, o código de ação é simplificado e pode ser executado mais rápido do que as ações em um contêiner do Docker.

Como pré-requisito para criar e usar ações de JavaScript empacotadas, você precisa baixar o Node.js, que inclui NPM. Como uma etapa opcional, mas recomendada, é usar o Kit de ferramentas do GitHub Actions Node.js, que é uma coleção de pacotes Node.js que permite a criação rápida de ações de JavaScript com mais consistência.

As etapas para criar uma ação de JavaScript são mínimas e diretas:

  1. Crie um arquivo de metadados action.yml para definir as entradas e saídas da ação, além de informar ao executor da ação como começar a executar essa ação de JavaScript.
  2. Crie um arquivo index.js com informações de contexto sobre os pacotes do kit de ferramentas, o roteamento e outras funções da ação.
  3. Confirme e efetue push da sua ação para o GitHub com os seguintes arquivos: action.yml, index.jsnode_modules, package.json, package-lock.json e README.md.

Ações de etapas de execução compostas

As ações de etapas de execução compostas permitem reutilizar ações usando scripts de shell. Você pode até mesmo misturar várias linguagens de shell dentro da mesma ação. Se você tiver muitos scripts de shell para automatizar diversas tarefas, poderá transformá-los facilmente em uma ação e reutilizá-los em diferentes fluxos de trabalho. Às vezes, é mais fácil apenas escrever um script de shell do que usar o JavaScript ou encapsular seu código em um contêiner do Docker.

Ação de composição empacotada

As ações de composições empacotadas agrupam várias etapas em uma unidade reutilizável. Essas ações são definidas em um repositório e podem ser referenciadas em fluxos de trabalho em repositórios diferentes. Empacotar uma ação de composição simplifica os fluxos de trabalho, reduz a duplicação e melhora a manutenção.

Ao criar uma ação de composição empacotada, as etapas são definidas em um único arquivo action.yml. Esse arquivo especifica as entradas, as saídas e a sequência de comandos ou ações a serem executadas. As ações de composições empacotadas são particularmente úteis para automatizar tarefas repetitivas ou combinar vários comandos de shell em uma única ação reutilizável.

Criar uma ação composta

1. Configurar um diretório para a ação composta

Você deve colocar a sua ação composta em seu próprio diretório dentro do repositório.

Estrutura de diretório de exemplo:

.github/actions/my-composite-action/
├── action.yml
└── scripts/
    └── my-script.sh

2. Definir o arquivo action.yml

Dentro do diretório my-composite-action, crie um arquivo action.yml.

name: "My Composite Action"
description: "A reusable composite action that checks out code and sets up Node.js"

inputs:
  node-version:
    description: "The Node.js version to use"
    required: true

runs:
  using: "composite"
  steps:
    - name: Checkout repository
      uses: actions/checkout@v4

    - name: Set up Node.js
      uses: actions/setup-node@v4
      with:
        node-version: ${{ inputs.node-version }}

Nota: O uso: do campo "composição" indica que essa ação é uma ação de composição.

3. Usar a ação de composição em um fluxo de trabalho

Apos criar a ação de composição, ela poderá ser referenciada em um fluxo de trabalho do GitHub Actions.

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Use my composite action
        uses: ./.github/actions/my-composite-action
        with:
          node-version: '18'

Se a ação de composição for compartilhada de outro repositório, faça referência a ela desta forma:

uses: owner/repository/.github/actions/my-composite-action@v1

Captura de tela de uma ação de composição usada em um fluxo de trabalho.

Adicionar saídas a uma ação de composição

As ações de composições podem definir saídas que os fluxos de trabalho podem usar para passar dados entre etapas ou trabalhos. As saídas são particularmente úteis para compartilhar resultados ou valores computados de uma ação para outra.

O exemplo a seguir demonstra como definir e usar uma saída em uma ação de composição:

Definir uma saída em action.yml

O arquivo action.yml especifica uma saída chamada script-result. Esta saída recupera o seu valor da saída result da etapa run-script. A etapa run-script executa um comando Bash para definir o valor de saída.

outputs:
  script-result:
    description: "Result from the script"
    value: ${{ steps.run-script.outputs.result }}

runs:
  using: "composite"
  steps:
    - id: run-script
      run: echo "result=Success" >> $GITHUB_OUTPUT
      shell: bash

Captura de tela da definição de uma saída em uma ação de composição.

Usar a saída em um fluxo de trabalho

Após criar a ação de composição, sua saída poderá ser acessada em um fluxo de trabalho. Veja um exemplo:

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - name: Run composite action
        id: my-action
        uses: ./.github/actions/my-composite-action

      - name: Display result
        run: echo "Script Result: ${{ steps.my-action.outputs.script-result }}"

Neste exemplo:

  • A ação de composição é invocada usando a palavra-chave uses.
  • Acesse a saída script-result usando a sintaxe steps.<step-id>.outputs.<output-name>.
  • Exiba o resultado nos logs de fluxo de trabalho.

Defina saídas em ações de composições para criar fluxos de trabalho reutilizáveis e modulares. Essa abordagem simplifica o compartilhamento de dados e melhora a manutenção.

Práticas recomendadas para ações de composições

Melhor prática Descrição
Usar controle de versão Use uma marca v1 para fazer referência à versão 1 estável.
Manter ações modulares Agrupar etapas relacionadas dentro de uma ação de composição.
Entradas e saídas de documento Adicionar descrições para entradas/saídas em action.yml.
Testar antes da publicação Valide a ação de composição em um repositório de teste.

Ação de composição em um fluxo de trabalho

As ações de composições são uma maneira poderosa de simplificar os fluxos de trabalho agrupando várias etapas em uma unidade reutilizável. Essas ações permitem definir uma sequência de comandos ou ações em um único arquivo action.yml, facilitando a manutenção e reutilização da lógica entre fluxos de trabalho.

Benefícios das ações de composições:

  • Reutilização: defina ações uma vez e use-as em vários fluxos de trabalho.
  • Manutenção: reduza a duplicação centralizando a lógica em uma única ação.
  • Modularidade: combine vários comandos de shell ou outras ações em uma única unidade.

Desenvolver uma ação para configurar uma CLI nos executores do GitHub Actions

Muitos fluxos de trabalho de CI/CD exigem uma versão específica de uma ferramenta da CLI para interagir com os serviços de nuvem, gerenciar a infraestrutura ou executar scripts. Embora os executores hospedados no GitHub venham pré-instalados com muitas ferramentas, eles podem não incluir a versão exata que seu fluxo de trabalho precisa, especialmente se for uma versão mais antiga ou sem suporte. Em vez de instalar a versão da CLI necessária em cada fluxo de trabalho, crie uma Ação do GitHub reutilizável que:

  • Garante a instalação consistente da versão da CLI necessária em todos os trabalhos.
  • Simplifica os fluxos de trabalho centralizando a lógica de instalação.
  • Otimiza o cache para uma execução mais rápida do fluxo de trabalho.

Como desenvolver uma ação de configuração da CLI

Uma ação de instalação da CLI é uma ação baseada em JavaScript que instala e configura uma CLI em um executor do GitHub.

Etapas para criar a ação:

Etapa 1: Configurar o diretório de ação

Para criar manualmente o diretório para a ação de configuração da CLI, siga estas etapas:

  1. Navegue até o repositório

Captura de tela da estrutura do repositório raiz mostrando uma ação JavaScript.

  1. Criar um novo diretório para a ação
    Crie um novo diretório nomeado my-cli-action dentro da pasta .github/actions. Isso garante que sua ação seja organizada e siga a estrutura recomendada do GitHub para ações personalizadas.

  2. Navegue até o novo diretório
    Altere para o diretório recém-criado para começar a adicionar arquivos para sua ação:

  3. Verificar a estrutura do diretório
    Após criar o diretório, a estrutura do repositório deve ter esta aparência:

your-repository/
├── .github/
│   ├── actions/
│   │   ├── my-cli-action/

Captura de tela da estrutura do diretório para uma ação JavaScript dentro de '.github/actions'.

Agora você está pronto para continuar criando o arquivo action.yml e outros arquivos necessários para a ação de instalação da CLI.

Etapa 2: Definir o arquivo de metadados action.yml

Crie um arquivo action.yml para descrever a ação.

name: "Setup MyCLI"
description: "Installs MyCLI and adds it to the PATH"
author: "Your Name"

inputs:
  version:
    description: "The CLI version to install"
    required: false
    default: "latest"

runs:
  using: "node16"
  main: "index.js"

Por que executar usar: node16? Essa ação executa o código JavaScript usando Node.js 16.

Captura de tela do arquivo de metadados YAML para uma Ação do GitHub do JavaScript.

Etapa 3: Criar um script JavaScript para instalar a CLI

No mesmo diretório, crie um arquivo chamado index.js e adicione o seguinte código:

const core = require('@actions/core');
const { execSync } = require('child_process');

async function run() {
  try {
    const version = core.getInput('version') || 'latest';
    
    console.log(`Installing MyCLI version: ${version}...`);

    execSync(`curl -fsSL https://cli.example.com/install.sh | sh`, { stdio: 'inherit' });

    console.log("MyCLI installed successfully.");
  } catch (error) {
    core.setFailed(`Installation failed: ${error.message}`);
  }
}

run();

O código JavaScript acima usa core.getInput() para recuperar a versão da CLI especificada como entrada. Em seguida, ele executa um comando curl para baixar e instalar a CLI. Se o processo de instalação falhar, a ação usará core.setFailed() para marcar o fluxo de trabalho como falha.

Captura de tela do código JavaScript para index.js em uma Ação do GitHub.

Etapa 4: Testar a ação localmente

Antes de usar a ação em um fluxo de trabalho, teste-a em um executor hospedado pelo GitHub.
Crie um arquivo de fluxo de trabalho (.github/fluxos de trabalho/test.yml) em seu repositório:

name: Test MyCLI Setup

on:
  push:
    branches:
      - main
      - feature/*

1. Disparar o fluxo de trabalho
O fluxo de trabalho é disparado em pushes para o branch principal e qualquer ramificação que corresponda ao padrão de recurso/*. Você poderá ajustar isso para corresponder à estratégia de ramificação do repositório.

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

2. Clonar o repositório
A ação actions/checkout@v4 é usada para clonar o repositório no executor. Isso garante que o fluxo de trabalho tenha acesso aos arquivos do repositório.

      - name: Install MyCLI
        uses: ./.github/actions/my-cli-action
        with:
          version: '1.2.3'

3. Executar a ação personalizada
A linha uses: ./.github/actions/my-cli-action faz referência à ação personalizada localmente. Verifique se o diretório de ação e action.yml arquivo estão configurados corretamente. A entrada de versão especifica a versão da CLI a ser instalada, nesse caso, a versão 1.2.3.

      - name: Verify CLI Installation
        run: |
          echo "Checking MyCLI version..."
          mycli --version

4. Verificar a instalação da CLI
Esta etapa executa um comando shell para verificar se a CLI foi instalada com êxito. Ele verifica a versão da CLI instalada executando mycli --version.

Captura de tela dos resultados do teste de uma Ação do GitHub do JavaScript.

Testar localmente

Para testar esse fluxo de trabalho localmente, use a ferramenta da CLI act:

act -j test

Isso simula o ambiente do GitHub Actions em seu computador local, permitindo que você depure e valide o fluxo de trabalho antes de enviar alterações por push.

Dica de otimização: cache

Para melhorar o desempenho do fluxo de trabalho, armazene em cache o diretório de instalação da CLI usando a ação actions/cache:

      - name: Cache MyCLI
        uses: actions/cache@v4
        with:
          path: ~/.mycli
          key: mycli-${{ runner.os }}-${{ inputs.version }}

Isso garante que as execuções subsequentes reutilizem a instalação da CLI armazenada em cache, reduzindo o tempo de instalação.

Melhores práticas para ações de configuração da CLI

Melhor prática Descrição
Usar controle de versão Permitir que os usuários especifiquem uma versão da CLI por meio de inputs.version.
Manipular erros corretamente Use core.setFailed() para sair com erros.
Instalação da CLI de cache Otimizar o desempenho do fluxo de trabalho usando actions/cache.
Fornecer Documentação Explique o uso e as entradas em README.md.

Solucionar problemas de ações do JavaScrip

Ao trabalhar com o GitHub Actions baseado em JavaScript, você poderá encontrar comportamentos inesperados, erros ou falhas durante a execução do fluxo de trabalho. Esta unidade fornece técnicas e ferramentas para ajudar você a identificar e resolver problemas em suas ações do JavaScript.

Cenários comuns de solução de problemas

Problema Causa possível Correção sugerida
A ação falha com um rastreamento de pilha Sintaxe ou erro de runtime em index.js Usar console.log() e verificar logs
As entradas são undefined Nome de entrada incorreto ou entrada ausente Verificar action.yml e como as entradas são passadas
Variáveis de ambiente não definidas core.exportVariable ou process.env não usado corretamente Examinar a configuração de código das variáveis
Arquivo não encontrado Caminhos relativos ausentes Usar __dirname ou caminhos completos para arquivos
O cache não foi restaurado Valores incorretos key ou path Verificar a configuração e as chaves do cache

Usar o registro em log para depuração

Registrar mensagens com core.info, core.debug e console.log

const core = require('@actions/core');

core.info("This is an info message");
core.debug("This is a debug message");
console.log("This is a raw console log");

✅ Use core.debug para logs de depuração – eles só aparecem quando ACTIONS_STEP_DEBUG é definido como true.

Habilitar o log de depuração

Você pode habilitar logs de depuração de nível de etapa definindo o seguinte segredo:

ACTIONS_STEP_DEBUG=true

Para habilitar os logs de diagnóstico do executor, defina:

ACTIONS_RUNNER_DEBUG=true

Definir segredos para depuração

  1. Acesse o seu repositório GitHub.
  2. Navegue até Configurações>Segredos e variáveis>Ações.
  3. Adicione novos segredos com os seguintes nomes e valores:
    • ACTIONS_STEP_DEBUG: true
    • ACTIONS_RUNNER_DEBUG: true

Inspecionar logs de fluxo de trabalho

Quando um fluxo de trabalho falhar, clique no trabalho com falha na guia Ações. Expanda cada etapa para:

  • Exibir logs detalhados
  • Verificar a saída padrão (StdOut)
  • Consulte o código de saída de scripts
  • Identificar exceções sem tratamento

Saída de log de exemplo 🔍

Error: Cannot find module '@actions/core'
Require stack:
- /home/runner/work/_actions/my-org/my-action/index.js

✅ Correção: execute a instalação do npm @actions/core e confirme node_modules (ou use ncc para agrupar a ação).

Testar sua ação localmente

Usar o act – uma ferramenta da CLI para executar o GitHub Actions localmente. Exemplo:

act -j test

🛠 Certifique-se de simular seu ambiente do GitHub corretamente ao testar localmente.

Manipular erros de forma eficaz

Indique exceções e falhas com mensagens úteis:

try {
  // your logic
} catch (error) {
  core.setFailed(`Action failed with error: ${error.message}`);
}

🔁 Isso garante que o GitHub pare o fluxo de trabalho no erro e forneça logs legíveis.

Melhores práticas para depurar ações do JavaScript

Prática Descrição
Usar core.debug() Ocultar logs detalhados, a menos que a depuração esteja habilitada.
Validar action.yml Verifique se as entradas e saídas estão definidas corretamente.
Código do pacote Use @vercel/ncc para compilar JavaScript em um único arquivo. Isso reduz as dependências e garante que todos os módulos necessários sejam incluídos, evitando erros de runtime causados por arquivos ausentes.
Testar com ato Simular execuções localmente para iterações mais rápidas.
Usar try/catch Impedir que os fluxos de trabalho falhem silenciosamente.

Solucionar problemas de ações de contêiner do Docker

As ações de contêiner do Docker são eficientes para encapsular ambientes e ferramentas complexas em fluxos de trabalho do GitHub Actions. No entanto, a depuração dessas ações pode ser mais desafiadora do que as ações do JavaScript devido ao ambiente de runtime isolado. Esta unidade orientará você na identificação, diagnóstico e resolução de problemas com ações baseadas no Docker.

Problemas comuns em ações de contêiner do Docker

Problema Motivo Correção sugerida
Falha ao iniciar a ação ENTRYPOINT ou CMD configurado incorretamente Confirmar se o Dockerfile usa ENTRYPOINT corretamente
Dependências ausentes Dependências não instaladas ou configuradas incorretamente Verifique se todos os pacotes estão instalados na imagem
Entradas não recebidas INPUT_ variáveis de ambiente não acessadas Usar process.env.INPUT_<INPUT_NAME> (ou equivalente do shell)
Arquivo não encontrado Caminho de arquivo incorreto dentro do contêiner Usar caminhos absolutos ou validar estrutura de diretório
Permissão negada O arquivo ou script não tem permissão de execução Adicionar RUN chmod +x <script> no Dockerfile
Falhas relacionadas à rede Serviços externos não acessíveis Validar as configurações de rede e a lógica de repetição

Entender o ciclo de vida da ação do Docker

Antes de solucionar problemas, é útil entender como as ações de contêiner do Docker são executadas.

1. Gatilho de fluxo de trabalho

Um fluxo de trabalho do GitHub Actions é iniciado em resposta a um evento configurado, como um push, pull_request ou workflow_dispatch manual.

2. Configuração do executor

O GitHub provisiona uma nova máquina virtual (o executor) para executar o fluxo de trabalho. O executor prepara o ambiente baixando definições de ação e resolvendo dependências.

3. Resolução de ações

Se a ação especificar runs.using: docker em seu arquivo action.yml, o GitHub o reconhecerá como uma ação baseada no Docker.

4. Compilação ou pull de imagem

O GitHub cria a imagem do Docker definida na ação Dockerfile ou efetua pull de uma imagem predefinida, se especificado. Essa imagem define o ambiente no qual o código de ação é executado.

5. Execução de contêiner

O executor inicia o contêiner do Docker, monta o workspace e injeta variáveis de ambiente, incluindo segredos e entradas definidos no fluxo de trabalho.

6. Execuções de ponto de entrada

O GitHub executa o comando entrypoint do Dockerfile dentro do contêiner. É aí que a lógica de ação personalizada é executada, normalmente um script ou aplicativo.

7. Tratamento de resultados

Todas as saídas definidas pela ação de contêiner são capturadas pelo executor e passadas para as etapas subsequentes no fluxo de trabalho. Depois de concluído, o contêiner é desligado e o executor é descartado.

Observação: as ações de contêiner do Docker são executadas em um ambiente limpo e isolado. O estado do sistema de arquivos, as ferramentas instaladas e as variáveis de ambiente devem ser definidos no Dockerfile.

Técnicas de depuração

1. Adicionar registro em log

Use instruções de eco, printf ou log no script do ponto de entrada:

echo "Starting Docker action..."
echo "Input VALUE: $INPUT_VALUE"

Registre todas as entradas e etapas críticas para diagnosticar onde ocorre a falha.

2. Compilar e testar localmente

Use o Docker em seu computador para simular o comportamento do contêiner:

docker build -t my-action .
docker run -e INPUT_NAME=value my-action

Verifique se as variáveis de ambiente imitam os conjuntos do GitHub.

3. Use a CLI do ato para simular fluxos de trabalho do GitHub

Instale a ação para executar seus fluxos de trabalho do GitHub localmente:

act -j test-job

Ótimo para testar ações do Docker em fluxos de trabalho sem enviar por push para o GitHub.

4. Validar a configuração do Dockerfile

Certifique-se de definir ENTRYPOINT ou CMD. Copie seus scripts para a imagem e dê a eles permissão de execução:

COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]

5. Inspecionar logs do GitHub

Clique em uma execução de fluxo de trabalho com falha, expanda cada etapa e examine:

  • Logs de build do Docker
  • Saída padrão e erro padrão do contêiner
  • Logs 🔍 de códigos de saída e rastreamentos de pilha geralmente revelam pacotes ausentes, problemas de sintaxe ou erros de permissão.

Exemplo: Erro de ponto de entrada

Error: container_linux.go:380: starting container process caused "exec: \"/entrypoint.sh\": permission denied"

✅ Correção: Adicionar RUN chmod +x /entrypoint.sh no Dockerfile.

Mapeamento de variáveis de ambiente

Entrada do GitHub Variável de ambiente do Docker
with: name: test INPUT_NAME=test
GITHUB_WORKSPACE Mapeado para /github/workspace
GITHUB_EVENT_NAME Evento que disparou o fluxo de trabalho
echo "Input was $INPUT_NAME"
echo "Working dir: $GITHUB_WORKSPACE"

Usar segredos de solução de problemas

Habilite o registro em log adicional adicionando esses segredos ao repositório ou à organização:

Segredo Descrição
ACTIONS_STEP_DEBUG Habilita o registro em log de depuração
ACTIONS_RUNNER_DEBUG Habilita o diagnóstico do executor

Melhores práticas para depuração de ação do Docker

Melhor prática Por que
Usar o registro em log generosamente Ajuda a rastrear pontos de falha
Sempre definir chmod +x Evitar erros de permissão em scripts de shell
Validar entradas em seu script Capturar entradas ausentes ou malformadas antecipadamente
Minimizar dependências de contêiner Imagens menores são mais fáceis de depurar
Testar localmente com a execução ou ação do Docker Iterações mais rápidas e comentários imediatos