Creación de una acción de GitHub personalizada

Completado

Acciones de GitHub es una característica eficaz que ayuda a pasar del código a la nube desde la comodidad de un repositorio propio. Aquí, obtendrá información sobre los diferentes tipos de acciones de GitHub y los metadatos, la sintaxis y los comandos de flujo de trabajo para crear acciones de GitHub personalizadas.

Tipos de acciones de GitHub

Diagrama en el que se muestran los tres tipos de Acciones de GitHub: acciones de Docker, JavaScript y paso de ejecución compuesto.

Las acciones son tareas individuales que puede usar para personalizar los flujos de trabajo de desarrollo. Puede crear acciones propias si escribe código personalizado que interactúe con el repositorio para realizar tareas personalizadas o si utiliza acciones que la comunidad de GitHub comparte. Al navegar por varias acciones, observará que hay tres tipos diferentes: acciones de contenedor de Docker, acciones de JavaScript y acciones de paso de ejecución compuesto. Ahora se analizará cada tipo de acción con más detalle.

Acciones de contenedor de Docker

Los contenedores de Docker empaquetan el entorno con el código de Acciones de GitHub. Esto significa que la acción se ejecuta en un entorno coherente y confiable porque todas sus dependencias están dentro de ese contenedor. Si la acción se tiene que ejecutar en una configuración de entorno específica, los contenedores de Docker son una buena manera de hacerlo porque permiten personalizar el sistema operativo y las herramientas. La desventaja es que, como el trabajo tiene que crear y recuperar el contenedor, las acciones de contenedor de Docker suelen ser más lentas que las acciones de JavaScript.

Antes de crear una acción de contenedor de Docker, debe tener conocimientos básicos sobre cómo usar las variables de entorno y el sistema de archivos de contenedor de Docker. Los pasos que debe seguir para crear una acción de contenedor de Docker son mínimos y sencillos:

  1. Cree un elemento Dockerfile a fin de definir los comandos para ensamblar la imagen de Docker.
  2. Cree un archivo de metadatos action.yml para definir las entradas y salidas de la acción. En el archivo, establezca el valor runs: using: en docker y el valor runs: image: en Dockerfile.
  3. Cree un archivo entrypoint.sh para describir la imagen de Docker.
  4. Confirme e inserte la acción en GitHub con los archivos siguientes: action.yml, entrypoint.sh, Dockerfile y README.md.

Acciones de JavaScript

Las acciones de JavaScript se pueden ejecutar directamente en la máquina del ejecutor y separan el código de acción del entorno que se usa para ejecutar la acción. Por este motivo, el código de acción se simplifica y se puede ejecutar más rápido que las acciones dentro de un contenedor de Docker.

Como requisito previo para crear y usar acciones de JavaScript empaquetadas, debe descargar Node.js, que incluye npm. Como paso opcional (pero recomendado), use el módulo GitHub Actions Toolkit de Node.js, que es una recopilación de paquetes de Node.js que le permite crear rápidamente acciones de JavaScript con más coherencia.

Los pasos que debe seguir para crear una acción de JavaScript son mínimos y sencillos:

  1. Cree un archivo de metadatos action.yml para definir las entradas y salidas de la acción, así como para indicarle al ejecutor de acciones cómo empezar a ejecutar esta acción de JavaScript.
  2. Cree un archivo index.js con información de contexto sobre los paquetes del kit de herramientas, el enrutamiento y otras funciones de la acción.
  3. Confirme e inserte la acción en GitHub con los archivos siguientes: action.yml, index.js, node_modules, package.json, package-lock.json y README.md.

Acciones de pasos de ejecución compuestos

Las acciones de pasos de ejecución compuestos permiten reutilizar acciones mediante scripts de shell. Incluso puede combinar varios lenguajes de shell dentro de la misma acción. Si tiene muchos scripts de shell para automatizar varias tareas, ahora puede convertirlos fácilmente en una acción y reutilizarlos para diferentes flujos de trabajo. A veces es más fácil escribir un script de shell que usar JavaScript o encapsular el código en un contenedor de Docker.

Acción compuesta empaquetada

Las acciones compuestas empaquetadas agrupan varios pasos en una unidad reutilizable. Estas acciones se definen en un repositorio y se pueden hacer referencia a ellas en flujos de trabajo en distintos repositorios. El empaquetado de una acción compuesta simplifica los flujos de trabajo, reduce la duplicación y mejora la capacidad de mantenimiento.

Al crear una acción compuesta empaquetada, los pasos se definen en un único archivo action.yml. Este archivo especifica las entradas, salidas y la secuencia de comandos o acciones que se van a ejecutar. Las acciones compuestas empaquetadas son especialmente útiles para automatizar tareas repetitivas o combinar varios comandos de shell en una sola acción reutilizable.

Creación de una acción compuesta

1. Configurar un directorio para la acción compuesta

Debe colocar la acción compuesta en su propio directorio dentro del repositorio.

Estructura de directorios de ejemplo:

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

2. Definir el archivo action.yml

Dentro del directorio my-composite-action, cree un archivo 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: El campo "composite" indica que esta acción es una acción compuesta.

3. Usar la acción compuesta en un flujo de trabajo

Una vez creada la acción compuesta, se puede hacer referencia a ella en un flujo de trabajo de Acciones de GitHub.

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

Si la acción compuesta se comparte desde otro repositorio, haga referencia a ella de la siguiente manera:

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

Recorte de pantalla de una acción compuesta usada en un flujo de trabajo.

Adición de salidas a una acción compuesta

Las acciones compuestas pueden definir salidas que los flujos de trabajo pueden usar para pasar datos entre pasos o trabajos. Las salidas son especialmente útiles para compartir resultados o valores calculados de una acción a otra.

En el ejemplo siguiente se muestra cómo definir y usar una salida en una acción compuesta:

Definición de una salida en action.yml

El archivo action.yml especifica una salida denominada script-result. Esta salida recupera su valor de la salida result del paso run-script. El paso run-script ejecuta un comando de Bash para establecer el valor de salida.

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

Recorte de pantalla de la definición de una salida en una acción compuesta.

Uso de la salida en un flujo de trabajo

Una vez creada la acción compuesta, se puede acceder a su salida en un flujo de trabajo. Este es un ejemplo:

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 }}"

En este ejemplo:

  • La acción compuesta se invoca mediante la palabra clave uses.
  • Acceda a la salida script-result mediante la sintaxis steps.<step-id>.outputs.<output-name>.
  • Muestre el resultado en los registros de flujo de trabajo.

Defina salidas en acciones compuestas para crear flujos de trabajo reutilizables y modulares. Este enfoque simplifica el uso compartido de datos y mejora la capacidad de mantenimiento.

Procedimientos recomendados para acciones compuestas

Procedimiento recomendado Descripción
Use el control de versiones Use una etiqueta v1 para hacer referencia a la versión estable 1.
Mantenga acciones modulares Agrupe los pasos relacionados dentro de una acción compuesta.
Entradas y salidas de documentos Agregue descripciones para entradas y salidas en action.yml.
Pruebe antes de publicar Valide la acción compuesta en un repositorio de pruebas.

Acción compuesta en un flujo de trabajo

Las acciones compuestas son una manera eficaz de simplificar los flujos de trabajo mediante la agrupación de varios pasos en una unidad reutilizable. Estas acciones permiten definir una secuencia de comandos o acciones en un único archivo action.yml, lo que facilita el mantenimiento y la reutilización de la lógica entre flujos de trabajo.

Ventajas de las acciones compuestas:

  • Reutilización: defina las acciones una vez y úselas en varios flujos de trabajo.
  • Capacidad de mantenimiento: reduzca la duplicación mediante la centralización de la lógica en una sola acción.
  • Modularidad: combine varios comandos de shell u otras acciones en una sola unidad.

Desarrollo de una acción para configurar una CLI en ejecutores de Acciones de GitHub

Muchos flujos de trabajo de CI/CD requieren una versión específica de una herramienta de la CLI para interactuar con servicios en la nube, administrar la infraestructura o ejecutar scripts. Aunque los ejecutores hospedados en GitHub vienen preinstalados con muchas herramientas, es posible que no incluyan la versión exacta que necesita el flujo de trabajo, especialmente si es una versión anterior o no admitida. En lugar de instalar la versión necesaria de la CLI en cada flujo de trabajo, puede crear una acción reutilizable de GitHub que:

  • Garantiza una instalación coherente de la versión de la CLI necesaria en todos los trabajos.
  • Simplifica los flujos de trabajo mediante la centralización de la lógica de instalación.
  • Optimiza el almacenamiento en caché para una ejecución de flujo de trabajo más rápida.

Cómo desarrollar una acción de configuración de la CLI

Una acción de configuración de la CLI es una acción basada en JavaScript que instala y configura una CLI en un ejecutor de GitHub.

Pasos para crear la acción:

Paso 1: Configurar el directorio de acciones

Para crear manualmente el directorio para la acción de instalación de la CLI, siga estos pasos:

  1. Vaya al repositorio

Recorte de pantalla de la estructura del repositorio raíz que se muestra para una acción de JavaScript.

  1. Creación de un directorio para la acción
    Cree un nuevo directorio denominado my-cli-action dentro de la carpeta .github/actions. Esto garantiza que la acción se organice y siga la estructura recomendada de GitHub para las acciones personalizadas.

  2. Vaya al nuevo directorio
    Cambie al directorio recién creado para empezar a agregar archivos para la acción:

  3. Comprobación de la estructura de directorios
    Después de crear el directorio, la estructura del repositorio debe tener este aspecto:

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

Recorte de pantalla de la estructura de directorios de una acción de JavaScript dentro de

Ya está listo para continuar con la creación del archivo action.yml y otros archivos necesarios para la acción de instalación de la CLI.

Paso 2: Definir el archivo de metadatos de action.yml

Cree un archivo action.yml para describir la acción.

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 qué usar: node16? Esta acción ejecuta código JavaScript mediante Node.js 16.

Recorte de pantalla del archivo de metadatos de YAML para una acción de GitHub de JavaScript.

Paso 3: Crear un script de JavaScript para instalar la CLI

En el mismo directorio, cree un archivo denominado index.js y agregue el código siguiente:

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();

El código de JavaScript anterior usa core.getInput() para recuperar la versión de la CLI especificada como entrada. A continuación, ejecuta un comando curl para descargar e instalar la CLI. Si se produce un error en el proceso de instalación, la acción usa core.setFailed() para marcar el flujo de trabajo como erróneo.

Recorte de pantalla del código JavaScript para index.js en una acción de GitHub.

Paso 4: Probar la acción localmente

Antes de usar la acción en un flujo de trabajo, pruébela en un ejecutor hospedado en GitHub.
Cree un archivo de flujo de trabajo (.github/workflows/test.yml) en el repositorio:

name: Test MyCLI Setup

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

1. Desencadenar el flujo de trabajo
El flujo de trabajo se desencadena en inserciones en la rama principal y en cualquier rama que coincida con el patrón feature/*. Puede ajustarlo para que coincida con la estrategia de bifurcación del repositorio.

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

2. Clonar el repositorio
La acción actions/checkout@v4 se usa para clonar el repositorio en el entorno de ejecución. Esto garantiza que el flujo de trabajo tenga acceso a los archivos del repositorio.

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

3. Ejecutar la acción personalizada
Los usos: ./.github/actions/my-cli-action hacen referencia a la acción personalizada localmente. Asegúrese de que el directorio de acciones y el archivo action.yml estén configurados correctamente. La entrada de versión especifica la versión de la CLI que se va a instalar, en este caso, versión 1.2.3.

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

4. Comprobación de la instalación de la CLI
Este paso ejecuta un comando de shell para comprobar que la CLI se instaló correctamente. Comprueba la versión de la CLI instalada mediante la ejecución de mycli --version.

Recorte de pantalla de los resultados de la prueba de una acción de GitHub de JavaScript.

Probar localmente

Para probar este flujo de trabajo localmente, use la herramienta de la CLI act:

act -j test

Esto simula el entorno de Acciones de GitHub en la máquina local, lo que le permite depurar y validar el flujo de trabajo antes de insertar cambios.

Sugerencia de optimización: Almacenamiento en caché

Para mejorar el rendimiento del flujo de trabajo, almacene en caché el directorio de instalación de la CLI mediante la acción actions/cache:

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

Esto garantiza que las ejecuciones posteriores vuelvan a usar la instalación de la CLI almacenada en caché, lo que reduce el tiempo de instalación.

Procedimientos recomendados para las acciones de configuración de la CLI

Procedimiento recomendado Descripción
Use el control de versiones Permita que los usuarios especifiquen una versión de la CLI a través de inputs.version.
Controlar correctamente los errores Use core.setFailed() para salir de los errores.
Instalación de la CLI de caché Optimice el rendimiento del flujo de trabajo mediante actions/cache.
Proporcionar documentación Explicar el uso y las entradas en README.md.

Solución de problemas de acciones de JavaScript

Al trabajar con acciones de GitHub basadas en JavaScript, es posible que encuentre un comportamiento, errores o errores inesperados durante la ejecución del flujo de trabajo. En esta unidad se proporcionan técnicas y herramientas que le ayudarán a identificar y resolver problemas en las acciones de JavaScript.

Escenarios habituales de solución de problemas

Problema Causa posible Corrección sugerida
Error en la acción con un seguimiento de pila Sintaxis o error en tiempo de ejecución en index.js Uso de console.log() y comprobación de registros
Las entradas son undefined Nombre de entrada incorrecto o entrada que falta Comprobación action.yml y cómo se pasan las entradas
Variables de entorno no establecidas core.exportVariable o process.env no se usa correctamente Revise la configuración del código de las variables
Archivo no encontrado Faltan rutas de acceso relativas Usar __dirname o rutas de acceso completas a archivos
No se restaura la memoria caché Incorrecto key o path valores Comprobación de la configuración y las claves de caché

Uso del registro para la depuración

Registrar mensajes con core.info, core.debug y 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 los registros de depuración; estos solo aparecen cuando ACTIONS_STEP_DEBUG se establece en true.

Habilitación del registro de depuración

Puede habilitar los registros de depuración de nivel de paso estableciendo el secreto siguiente:

ACTIONS_STEP_DEBUG=true

Para habilitar los registros de diagnóstico del ejecutor, establezca:

ACTIONS_RUNNER_DEBUG=true

Establecimiento de secretos para la depuración

  1. Vaya al repositorio de GitHub.
  2. Vaya a Configuración>>.
  3. Agregue nuevos secretos con los siguientes nombres y valores:
    • ACTIONS_STEP_DEBUG: true
    • ACTIONS_RUNNER_DEBUG: true

Inspección de registros de flujo de trabajo

Cuando se produce un error en un flujo de trabajo, haga clic en el trabajo con errores en la pestaña Acciones. Expanda cada paso para:

  • Visualización de registros detallados
  • Comprobación de la salida estándar (stdout)
  • Consulte el código de salida de los scripts
  • Identificación de excepciones no controladas

🔍 Salida del registro de ejemplo

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

✅ Corrección: ejecute npm install @actions/core y confirme node_modules (o use ncc para agrupar la acción).

Prueba local de la acción

Use act: una herramienta de la CLI para ejecutar acciones de GitHub localmente. Ejemplo:

act -j test

🛠 Asegúrese de simular el entorno de GitHub correctamente al probar localmente.

Control de errores correctamente

Detectar excepciones y producir errores con mensajes útiles:

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

🔁 Esto garantiza que GitHub detenga el flujo de trabajo en caso de error y proporcione registros legibles.

Procedimientos recomendados para depurar acciones de JavaScript

Práctica Descripción
Uso de core.debug() Oculte los registros detallados a menos que la depuración esté habilitada.
Validar action.yml Asegúrese de que las entradas y salidas están definidas correctamente.
Código de agrupación Use @vercel/ncc para compilar JavaScript en un único archivo. Esto reduce las dependencias y garantiza que se incluyen todos los módulos necesarios, lo que evita errores en tiempo de ejecución causados por archivos que faltan.
Prueba con acto Simule ejecuciones localmente para iteraciones más rápidas.
Uso de try/catch Impida que los flujos de trabajo produzcan errores de forma silenciosa.

Solución de problemas de acciones de contenedor de Docker

Las acciones de contenedor de Docker son eficaces para encapsular entornos y herramientas complejos en flujos de trabajo de Acciones de GitHub. Sin embargo, la depuración de estas acciones puede ser más difícil que las acciones de JavaScript debido a su entorno de tiempo de ejecución aislado. Esta unidad le guiará a través de la identificación, el diagnóstico y la resolución de problemas con acciones basadas en Docker.

Problemas comunes en las acciones de contenedor de Docker

Problema Causa Corrección sugerida
La acción no se puede iniciar ENTRYPOINT o CMD mal configurado Confirmación de que Dockerfile usa ENTRYPOINT correctamente
Dependencias faltantes Dependencias no instaladas o mal configuradas Asegúrese de que todos los paquetes están instalados en la imagen
Entradas no recibidas INPUT_ Variables de entorno a las que no se tiene acceso Uso process.env.INPUT_<INPUT_NAME> (o equivalente de shell)
Archivo no encontrado Ruta de acceso de archivo incorrecta dentro del contenedor Usar rutas de acceso absolutas o validar la estructura de directorios
Permiso denegado El archivo o el script carecen de permiso de ejecución Adición de RUN chmod +x <script> en Dockerfile
Errores relacionados con la red Servicios externos no accesibles Validación de la configuración de red y lógica de reintento

Descripción del ciclo de vida de la acción de Docker

Antes de solucionar problemas, resulta útil comprender cómo se ejecutan las acciones de contenedor de Docker.

1. Desencadenador de flujo de trabajo

Un flujo de trabajo de Acciones de GitHub se inicia en respuesta a un evento configurado, como push, pull_requesto workflow_dispatch manual.

2. Configuración del ejecutor

GitHub aprovisiona una máquina virtual nueva (el ejecutor) para ejecutar el flujo de trabajo. El ejecutor prepara el entorno mediante la descarga de definiciones de acción y la resolución de dependencias.

3. Resolución de acciones

Si la acción especifica runs.using: docker en su archivo action.yml, GitHub la reconoce como una acción basada en Docker.

4. Compilación o extracción de imágenes

GitHub compila la imagen de Docker definida en las acciones Dockerfile o extrae una imagen precompilada si se especifica. Esta imagen define el entorno en el que se ejecuta el código de acción.

5. Ejecución del contenedor

El ejecutor inicia el contenedor de Docker, monta el área de trabajo e inserta variables de entorno, incluidos secretos y entradas definidos en el flujo de trabajo.

6. Ejecuciones de punto de entrada

GitHub ejecuta el comando entrypoint desde el Dockerfile dentro del contenedor. Aquí es donde se ejecuta la lógica de acción personalizada, normalmente un script o una aplicación.

7. Control de resultados

El ejecutor captura las salidas establecidas por la acción del contenedor y se pasa a los pasos posteriores del flujo de trabajo. Una vez completado, el contenedor se cierra y se descarta el ejecutor.

Nota: Las acciones de contenedor de Docker se ejecutan en un entorno limpio y aislado. El estado del sistema de archivos, las herramientas instaladas y las variables de entorno deben definirse en el Dockerfile.

Técnicas de depuración

1. Agregar registro

Use instrucciones echo, printf o logging en el script de punto de entrada:

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

Registre todas las entradas y pasos críticos para diagnosticar dónde se produce el error.

2. Compilar y probar localmente

Use Docker en la máquina para simular el comportamiento del contenedor:

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

Asegúrese de que las variables de entorno imitan los conjuntos de GitHub.

3. Uso de la CLI de act para simular flujos de trabajo de GitHub

Instale act para ejecutar los flujos de trabajo de GitHub localmente:

act -j test-job

Ideal para probar acciones de Docker en flujos de trabajo sin insertar en GitHub.

4. Validación de la configuración de Dockerfile

Asegúrese de definir ENTRYPOINT o CMD. Copie los scripts en la imagen y asígneles permiso de ejecución:

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

5. Inspección de los registros de GitHub

Haga clic en una ejecución de flujo de trabajo con errores, expanda cada paso y examine:

  • Registros de compilación de Docker
  • Salida estándar y error estándar del contenedor
  • Los códigos de salida y los seguimientos 🔍 de pila suelen revelar paquetes que faltan, problemas de sintaxis o errores de permisos.

Ejemplo: error de punto de entrada

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

✅ Corrección: agregue RUN chmod +x /entrypoint.sh en el Dockerfile.

Asignación de variables de entorno

Entrada de GitHub Variable de entorno de Docker
with: name: test INPUT_NAME=test
GITHUB_WORKSPACE Asignado a /github/workspace
GITHUB_EVENT_NAME Evento que desencadenó el flujo de trabajo
echo "Input was $INPUT_NAME"
echo "Working dir: $GITHUB_WORKSPACE"

Uso de secretos de solución de problemas

Habilite el registro adicional agregando estos secretos al repositorio o a la organización:

Secreto Descripción
ACTIONS_STEP_DEBUG Habilita el registro de depuración
ACTIONS_RUNNER_DEBUG Habilita el diagnóstico del ejecutor

Procedimientos recomendados para la depuración de acciones de Docker

Procedimiento recomendado Por qué
Uso del registro generosamente Ayuda a realizar un seguimiento de los puntos de error
Establecer siempre chmod +x Evitar errores de permisos en scripts de shell
Validación de entradas en el script Captura de entradas que faltan o tienen un formato incorrecto al principio
Minimizar las dependencias de contenedor Las imágenes más pequeñas son más fáciles de depurar
Prueba local con la ejecución o la acción de Docker Iteraciones más rápidas y comentarios inmediatos