¿Alguna vez ha empujado accidentalmente los secretos a un repositorio?O tal vez ha empujado el código no formatado, solo para tener que crear un compromiso de seguimiento?Todos hemos estado allí.Estos pequeños errores pueden conducir a tuberías fallidas de CI / CD y retrasos frustrantes, todo debido a cheques que podrían haber sido ejecutados localmente.
Los ganchos de Git son una poderosa herramienta para prevenir estos problemas ejecutando scripts antes de comprometerse o empujar. sin embargo, compartir y estandarizar estos ganchos en un equipo o proyecto puede ser un reto.
Pre-commit es un marco fácil de usar para gestionar y compartir ganchos de git multilingües, ayudándote a capturar problemas antes de que incluso salgan de tu estación de trabajo.
Comenzar: la configuración correcta
Antes de poder aprovechar el poder de precommit, debe instalarlo y configurarlo para sus proyectos.
Instalación
Hay varias maneras de instalar precommit:
- Mac OS y Linux:
brew install pre-commit
- Python/Pip (Cross-Platform) es un lenguaje de programación.
pip install pre-commit
- Otros Métodos: Para las instalaciones utilizando Conda o en Windows, consulte la Documentación Oficial.
Configuración específica del proyecto (la forma estándar)
Este es el enfoque más común para permitir el precompromiso en un proyecto específico:
-
Create a Configuration File: In the root of your repository, create a file named
.pre-commit-config.yaml
. This file will define the hooks pre-commit should run. (We’ll cover how to populate this file in the next section).
-
Install Hooks: Navigate to your repository’s root directory in your terminal and run:
pre-commit install
- Este comando instala los ganchos git en el directorio .git/hooks de su repositorio. A partir de ahora, pre-commit ejecutará automáticamente sus cheques antes de cada comité que realice en este repositorio específico.
Global Setup (Método “Set It and Forget It”)
Si frecuentemente inicia nuevos proyectos o clona repositorios y desea que el precomitente esté activo por defecto (si existe una configuración), puede configurarlo globalmente.init.templateDir
Características de .
-
A Configuration File: All your repository must have a
.pre-commit-config.yaml
. This file will define the hooks that pre-commit should run. The best would be to use a template repository with a minimal pre-commit file.
-
Configure Git’s Template Directory: Tell Git to use a specific directory as a template for new repositories:
git config --global init.templateDir ~/.git-template
(Puede elegir un directorio diferente si lo prefiere, solo asegúrese de que sea consistente en el siguiente paso.)
Inicializar Precommit en el directorio de plantillas: Execute el siguiente comando:
pre-commit init-templatedir ~/.git-template
(Si eligió un directorio diferente en el paso anterior, sustituye el~/.git-template
En consecuencia )
Esto tiene un gran Beneficio: Con esta configuración global, cualquier nuevo repositorio que inicialice (git init
) o un clon tendrá automáticamente instalado el gancho de precomisión. Si un repositorio no tiene un.pre-commit-config.yaml
archivo, pre-commit simplemente no hará nada, por lo que es seguro activar globalmente.
Sin embargo, me gusta ir un paso más adicional añadiendo un hook predeterminado~/.git-template/hooks/pre-commit
que sería sistemáticamente fallido si un repositorio no tenía un.pre-commit-config.yaml
Aquí está el contenido del hook.
#!/usr/bin/env bash
if [ -f .pre-commit-config.yaml ]; then
echo 'pre-commit configuration detected, but `pre-commit install` was never run' 1>&2
exit 1
fi
Crea tu configuración (.pre-commit-config.yaml)
El corazón de la precomisión es el.pre-commit-config.yaml
Este archivo, colocado en la raíz de su repositorio, dice pre-commit que cheques para ejecutar.
# https://github.com/xNok/infra-bootstrap-tools/blob/main/.pre-commit-config.yaml
repos:
# Lint all yam files
- repo: https://github.com/adrienverge/yamllint.git
rev: v1.29.0
hooks:
- id: yamllint
# Runs Ansible lint
- repo: https://github.com/ansible/ansible-lint
rev: v24.7.0
hooks:
- id: ansible-lint
args:
- "ansible"
additional_dependencies:
- ansible
Estructura del núcleo explicada
Una configuración típica implica una lista de repositorios, cada uno con hooks específicos:
- repos: Esta es una clave de nivel superior que toma una lista de mapeos de repositorio. Cada elemento en la lista especifica un repositorio de Git que contiene hooks de precomisión.
- repo: La URL del repositorio alojando los hooks (por ejemplo, https://github.com/pre-commit/pre-commit-hooks). Esta es una manera muy agradable de gestionar dependencias. Cuando sepa más sobre la herramienta, puede dirigirse al repositorio.
- Rev: Especifica la versión de los hooks a usar, pinning a una etiqueta de Git, SHA, o rama. pero se aconseja usar siempre una etiqueta específica o SHA (no una rama como el maestro) para asegurarse de que su linting no se rompa inesperadamente cuando el repositorio remoto se actualiza.
- Hooks: Una lista bajo cada entrada de repo. Cada elemento aquí define un hook específico para usar de ese repositorio.
- id: El identificador único del hook (por ejemplo, trailing-whitespace, check-yaml). Puedes encontrar los identificadores de hook disponibles en la documentación del repositorio del hook. o simplemente el .pre-commit-hooks.yaml en la raíz del repo.
Configuración de inicio práctico
Aquí hay un básico.pre-commit-config.yaml
Para este ejemplo, te aconsejo ir a Github y echar un vistazo apre-commit
el equipo ha implementado, y dónde puede encontrar elid
de cada uno de los hooks pertinentes que pueda querer utilizar.
Yo diríatrailing-whitespace
yend-of-file-fixer
Son realmente útiles, por lo que la configuración se vería así.
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.6.0 # Check for the latest stable version on the pre-commit-hooks repo!
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
# Add other repositories and their specific hooks below
# - repo: ...
# rev: ...
# hooks:
# - id: ...
Nota: Las versiones de los hooks cambian con el tiempo. Es buena práctica revisar elpre-commit-hooks
repositorio (o cualquier otro repositorio de hook que utilice) para la última etiqueta de versión estable y actualizar surev
O tener la automatización en su lugar, como Renovate o Dependabot, para actualizarlas regularmente.
Puedes encontrar una gran lista de hooks preexistentes en el.pre-commit-hooks.yaml
A ver si hay hojas disponibles.
Es bueno saber cuando usar pre-commit
Una vez que se sienta cómodo con los conceptos básicos, pre-commit ofrece características más avanzadas para ajustar su flujo de trabajo.
Correr los hooks manualmente
Mientras los hooks se ejecutan automáticamente engit commit
, es posible que desee activarlas manualmente en otros momentos:
- Ejecutar un hook específico: Para ejecutar un único hook (por ejemplo, para probar su configuración o aplicar sus cambios sin comprometerse), use:
pre-commit run <hook_id>
(reemplazo<hook_id>
con el ID real de su archivo de configuración.)
- Ejecutar en todos los archivos: Para ejecutar todos los hooks configurados en cada archivo rastreado en su repositorio (no sólo cambios en etapa), utilice:
pre-commit run --all-files
Esto es útil para una limpieza inicial o cuando se añaden nuevos ganchos a un proyecto existente.
Crea tus propios hooks locales
A veces, puede tener scripts específicos del proyecto o cheques que no forman parte de un repositorio de hook público. Precommit le permite definir hooks "locales".
- Escribe tu script: Cree tu script (por ejemplo, un script de shell, un script de Python) en tu repositorio. Para este ejemplo, digamos que creas my_custom_script.sh.
- Define en .pre-commit-config.yaml: Agregue una entrada de pestaña local a su configuración:
# .pre-commit-config.yaml
- repo: local
hooks:
- id: my-custom-check
name: My custom check
entry: ./my_custom_script.sh # Path to your script
language: script # Or python, node, etc.
files: \.(py)$ # Example: regex to run only on Python files
# verbose: true # Uncomment for more output
# args: [--custom-arg] # Optional arguments for your script
Esto dice pre-commit a corrermy_custom_script.sh
para cualquier cambio en Python (.py
Los archivos, ellanguage: script
El tipo es muy flexible; para entornos específicos como Python o Node, puede especificar aquellos para gestionar dependencias si es necesario.bash
Los Hooks.
Sin embargo, pre-commit es muy inteligente en cuanto a los entornos de trabajo, ya que crea un entorno de ejecución aislado para las herramientas y las dependencias necesarias.
No todos los ganchos, por desgracia, han aprovechado la función de dependencia, y es posible que tenga que instalar las herramientas usted mismo para poder ejecutar el gancho (estoy pensando en terraform, por ejemplo)
Precompromiso en un equipo y en el entorno CI/CD
Mientras que pre-commit brilla en las máquinas individuales de los desarrolladores, sus beneficios se multiplican cuando se integran en los flujos de trabajo del equipo y en las tuberías CI/CD. Incluso con los ganchos pre-commit instalados localmente, alguien podría comprometerse accidentalmente sin ganchos (por ejemplo, usandogit commit --no-verify
) o tienen una configuración de gancho desactualizada. su tubería CI / CD puede actuar como el guardameta final.
Al ejecutar verificaciones de precomisión en su tubería CI, se asegura de que no se fusione ningún código que viole los estándares de su proyecto.
pre-commit run --all-files
Este comando verifica todos los archivos en el repositorio, no solo los modificados, asegurando una validación completa.
Conceptual CI Pipeline Step (por ejemplo, acciones de GitHub):
# Example for a GitHub Actions workflow
# ... (other steps like checkout, setup python/node, etc.)
- name: Install pre-commit and dependencies
run: |
pip install pre-commit
# Install any other dependencies your hooks might need (e.g., linters)
# This might be minimal if your hooks install their own dependencies (common).
- name: Run pre-commit checks
run: pre-commit run --all-files
Es bueno tener un tubo conceptual que funcione con cualquier sistema CI, pero si usa acciones de GitHub, no tiene que molestar; use elAcción oficial.
jobs:
pre-commit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v3
- uses: pre-commit/action@v3.0.1
Con la integración de CI, el ciclo se completa, y se aplica la misma validación en entornos de desarrollador como en el entorno de CI. Si el tubo falla, corregirlo localmente mediante la ejecución de precommit.
Conclusión
Realizando allíTienePara ser una forma mejor que los controles manuales y los "oops", hemos explorado cómopre-commit
Transforma tu flujo de trabajo de desarrollo.
Al automatizar las verificaciones de todo, desde errores de espacio blanco y detección secreta hasta la formatación de códigos y enlaces, pre-commit actúa como su guardián local incansable de la calidad del código que puede incluso integrarse “sin problemas” en las tuberías CI/CD para servir como una puerta de acceso final a la calidad.