Creación de una acción de GitHub personalizada
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
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:
- Cree un elemento
Dockerfilea fin de definir los comandos para ensamblar la imagen de Docker. - Cree un archivo de metadatos
action.ymlpara definir las entradas y salidas de la acción. En el archivo, establezca el valorruns: using:endockery el valorruns: image:enDockerfile. - Cree un archivo
entrypoint.shpara describir la imagen de Docker. - Confirme e inserte la acción en GitHub con los archivos siguientes:
action.yml,entrypoint.sh,DockerfileyREADME.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:
- Cree un archivo de metadatos
action.ymlpara 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. - Cree un archivo
index.jscon información de contexto sobre los paquetes del kit de herramientas, el enrutamiento y otras funciones de la acción. - Confirme e inserte la acción en GitHub con los archivos siguientes:
action.yml,index.js,node_modules,package.json,package-lock.jsonyREADME.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
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
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-resultmediante la sintaxissteps.<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:
- Vaya al repositorio
Creación de un directorio para la acción
Cree un nuevo directorio denominadomy-cli-actiondentro de la carpeta.github/actions. Esto garantiza que la acción se organice y siga la estructura recomendada de GitHub para las acciones personalizadas.Vaya al nuevo directorio
Cambie al directorio recién creado para empezar a agregar archivos para la acción: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/
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.
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.
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.
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
- Vaya al repositorio de GitHub.
- Vaya a Configuración>>.
- Agregue nuevos secretos con los siguientes nombres y valores:
-
ACTIONS_STEP_DEBUG:
true -
ACTIONS_RUNNER_DEBUG:
true
-
ACTIONS_STEP_DEBUG:
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 |