Bienvenido a la página pública de Dependabot.
Dependabot-Core es la biblioteca central de las actualizaciones de versión/seguridad de Dependabot.
Úselo para generar solicitudes de extracción automatizadas que actualicen dependencias para proyectos escritos en Ruby, JavaScript, Python, PHP, Dart, Elixir, Elm, Go, Rust, Java y .NET. También puede actualizar submódulos de git, archivos Docker y archivos Terraform. Las características incluyen:
La mayoría de la gente está familiarizada con el servicio Dependabot que se ejecuta en GitHub.com y GitHub Enterprise. Habilitarlo es tan simple como verificar un archivo de configuración dependabot.yml
en el directorio .github
de su repositorio.
Sin embargo, si desea ejecutar una versión personalizada de Dependabot o ejecutarlo en otra plataforma, no se quedará atrás. Este repositorio proporciona la lógica necesaria para alojar su propio Dependabot independiente. Actualmente admite la apertura de solicitudes de extracción en repositorios alojados en GitHub, Github Enterprise, Azure DevOps, GitLab, BitBucket y AWS CodeCommit.
Dependabot-Core es una biblioteca, por lo que necesitará algún tipo de script de punto de entrada. A continuación se muestran algunos ejemplos que le ayudarán a empezar.
Nota: Si desea ejecutar Dependabot localmente con fines de desarrollo/depuración, consulte la Guía de desarrollo.
El repositorio dependabot-script proporciona una colección de scripts de ejemplo para configurar la biblioteca Dependabot-Core. Está pensado como punto de partida para que los usuarios avanzados ejecuten una versión autohospedada de Dependabot dentro de sus propios proyectos.
Nota: Recientemente refactorizamos la imagen monolítica de la ventana acoplable utilizada en la biblioteca Dependabot Core en una imagen por ecosistema. Desafortunadamente, eso rompió los scripts de dependabot y aún no hemos tenido tiempo de actualizarlos. Somos conscientes del problema y esperamos poder ofrecer una solución pronto.
La CLI de Dependabot es una herramienta más nueva que eventualmente puede reemplazar dependabot-script
para casos de uso independientes. Si bien crea diferencias de dependencia, actualmente falta la lógica para convertir esas diferencias en relaciones públicas reales. Sin embargo, puede resultar útil para usuarios avanzados que busquen ejemplos de cómo hackear Dependabot.
En un entorno como GitHub donde Dependabot se ejecuta en un contenedor, si desea cambiar su proceso de compilación o instalación dependiendo de si Dependabot está verificando, puede determinarlo mediante la existencia de la variable de entorno DEPENDABOT
.
¿Quiere darnos su opinión sobre Dependabot o contribuir? Eso es genial, ¡muchas gracias!
La mayoría de los informes de errores deben ir acompañados de un enlace a un repositorio público que reproduzca el problema. Los informes de errores que no se pueden reproducir en un repositorio público mediante la herramienta CLI o el script de prueba pueden cerrarse como "no se pueden reproducir".
Nuestro rastreador de problemas es bastante activo y, como resultado, es muy probable que alguien ya haya presentado el mismo problema. Si es así, vote a favor de ese problema, porque usamos? reacciones sobre problemas como una señal para medir el impacto de una solicitud de función o un error.
Sin embargo, no deje comentarios que no aporten nada nuevo a la discusión. Para obtener más información, consulte https://github.com/golang/go/wiki/NoPlusOne. Esto es de código abierto, si ve algo que desea arreglar, estaremos encantados de asesorarlo contribuyendo con una solicitud de extracción para solucionarlo.
El rastreador de problemas está destinado únicamente a problemas relacionados con la lógica de actualización del Dependabot. En cambio, los problemas relacionados con las alertas de seguridad o el gráfico de dependencia deben presentarse como una discusión sobre seguridad del código.
Una buena regla general es que si tiene preguntas sobre la diferencia en un PR, debe consultarlas aquí.
Si cree que ha encontrado una vulnerabilidad de seguridad en Dependabot, revise nuestra política de seguridad para obtener detalles sobre cómo divulgarla al programa GitHub Bug Bounty, para que podamos trabajar para resolver el problema antes de que se divulgue públicamente.
¿Quieres contribuir a Dependabot? Eso es genial, ¡muchas gracias!
Flujo de trabajo de contribución:
Consulte las pautas de CONTRIBUCIÓN para obtener más información.
Si está interesado en contribuir con apoyo para un nuevo ecosistema, consulte las pautas de contribución para obtener más información.
El primer paso para depurar un problema o escribir una nueva característica es poner en marcha un entorno de desarrollo. Proporcionamos un shell de desarrollador personalizado basado en Docker que integra todas las dependencias necesarias. En la mayoría de los casos, esta es la mejor manera de trabajar con el proyecto.
El shell del desarrollador utiliza montajes de volumen para incorporar sus cambios locales al código fuente de Dependabot. De esta manera, puede editar localmente usando su editor favorito y los cambios se reflejan inmediatamente dentro del contenedor acoplable para realizar ensayos o ejecutar pruebas. Nota: consulte la advertencia sobre la edición de los scripts auxiliares del administrador de paquetes nativo.
El script para iniciar el shell del desarrollador crea las imágenes de la ventana acoplable desde cero si no puede encontrarlas localmente. Esto puede llevar un tiempo.
Evite la espera extrayendo la imagen prediseñadas para el ecosistema en el que desea trabajar. El nombre de la imagen utiliza el nombre del ecosistema YAML para especificar el ecosistema. Por ejemplo, para los módulos Go, el nombre YAML es gomod
:
$ docker pull ghcr.io/dependabot/dependabot-updater-gomod
Nota: Las imágenes prediseñadas actualmente solo están disponibles para la arquitectura AMD64/Intel. Se ejecutarán en ARM, pero entre 2 y 3 veces más lento que si crea manualmente imágenes específicas de ARM.
A continuación, ejecute el shell del desarrollador, especificando el ecosistema deseado utilizando el nombre del directorio de nivel superior del ecosistema en este proyecto . Por ejemplo, para Go Modules, el directorio de nivel superior se denomina go_modules
:
$ bin/docker-dev-shell go_modules
= > running docker development shell
[dependabot-core-dev] ~ $ cd go_modules && rspec spec # to run tests for a particular package
Normalmente, todo lo que necesita es el inicio rápido, pero ocasionalmente necesitará reconstruir las imágenes subyacentes.
Por ejemplo, aunque todavía no publicamos imágenes específicas de ARM, si está trabajando en una plataforma basada en ARM, le recomendamos crear las imágenes manualmente porque los contenedores resultantes se ejecutan mucho más rápido.
El shell del desarrollador se ejecuta dentro de una imagen acoplable de Dependabot Development, que se construye sobre una imagen del ecosistema.
diagrama de flujo LR
A["docker-dev-shell script"] --> B("Imagen acoplable de Dependabot Development")
B --> C("Imagen acoplable del ecosistema Dependabot Updater (específica del ecosistema)")
C --> D("Imagen acoplable de Dependabot Updater Core")
Los cambios en los archivos de la ventana acoplable para cualquiera de estas imágenes requieren la compilación de una o más imágenes localmente para que se reflejen en el shell de desarrollo.
La forma sencilla pero lenta es eliminar las imágenes existentes y luego ejecutar bin/docker-dev-shell
que genera automáticamente las imágenes faltantes.
La forma más rápida es extraer todas las imágenes prediseñadas que dependen de la imagen que realmente necesita crear. Para (re)construir uno específico:
La imagen principal del Actualizador:
$ docker pull ghcr.io/dependabot/dependabot-updater-core # OR
$ docker build -f Dockerfile.updater-core . # recommended on ARM
La imagen del ecosistema Updater:
$ docker pull ghcr.io/dependabot/dependabot-updater-gomod # OR
$ script/build go_modules # recommended on ARM
El contenedor de desarrollo que utiliza el indicador --rebuild
:
$ bin/docker-dev-shell go_modules --rebuild
Varios paquetes de Dependabot utilizan 'ayudantes nativos', pequeños ejecutables en su idioma anfitrión.
Los cambios realizados en estos archivos no se reflejan automáticamente dentro del contenedor de desarrollo.
Una vez que haya realizado modificaciones en los archivos auxiliares, ejecute el script de compilación apropiado para actualizar la versión instalada con los cambios de esta manera:
$ bin/docker-dev-shell bundler
= > running docker development shell
$ bundler/helpers/v2/build
$ bin/dry-run.rb bundler dependabot/demo --dir= " /ruby "
Para ver los registros y la salida estándar de los asistentes del administrador de paquetes nativo, consulte Depuración de asistentes nativos.
El primer paso para la depuración es ejecutar el entorno de desarrollo.
Dentro del entorno de desarrollo, tiene dos opciones para simular un trabajo de actualización de dependencia: puede usar la herramienta CLI recientemente desarrollada o el script de ejecución en seco original.
La CLI de Dependabot es una herramienta recientemente desarrollada que incorpora GitHub Credentials Proxy para simular de manera más realista lo que sucede dentro del servicio Dependabot-at-GitHub cuando se habla con registros privados.
Tiene una guía de depuración dedicada, que incluye soporte para ingresar al depurador Ruby.
Nota: Antes de ejecutar el script de prueba, deberá ejecutar el entorno de desarrollo.
Puede utilizar el script bin/dry-run.rb
para simular un trabajo de actualización de dependencia, imprimiendo la diferencia que se generaría en la terminal. Se necesitan dos argumentos posicionales: el administrador de paquetes y el nombre del repositorio de GitHub (incluida la cuenta):
$ bin/docker-dev-shell go_modules
= > running docker development shell
$ bin/dry-run.rb go_modules rsc/quote
= > fetching dependency files
= > parsing dependency files
= > updating 2 dependencies
...
El script Dry-Run admite muchas otras opciones, todas las cuales están documentadas en la parte superior del código fuente del script. Por ejemplo:
LOCAL_GITHUB_ACCESS_TOKEN="fake-GitHub-PAT"
permite especificar un token de acceso personal (PAT) de GitHub para evitar la limitación de velocidad.--dir="path/to/subdir/containing/manifest
es necesario si el archivo de manifiesto está ubicado en un subdirectorio.--dep="dep-name-that-I-want-to-test"
permite especificar un único departamento para intentar actualizar y todos los demás se ignoran.--cache=files
permite almacenar en caché archivos de almacenamiento remoto localmente para realizar reejecuciones más rápidas al probar cambios lógicos locales.--updater-options=feature_flag_name
permite pasar indicadores de características.Aquí hay un ejemplo de cómo unir todos estos
LOCAL_GITHUB_ACCESS_TOKEN=github_pat_123_fake_string
bin/dry-run.rb docker jeffwidman/secrets-store-driver
--dir " /manifest_staging/charts/secrets-store-provider "
--cache=files
--dep= " secrets-store "
--updater-options=kubernetes_updates
Puede agregar una declaración debugger
en cualquier parte del código Ruby, por ejemplo:
def latest_resolvable_version
debugger
latest_version_finder . latest_version
end
Cuando ejecute el trabajo, se abrirá el depurador de Ruby. Debería verse así:
[ 11 , 20 ] in ~/ go_modules / lib / dependabot / go_modules / update_checker . rb
11 | module GoModules
12 | class UpdateChecker < Dependabot :: UpdateCheckers :: Base
13 | require_relative "update_checker/latest_version_finder"
14 |
15 | def latest_resolvable_version
=> 16 | debugger
17 | latest_version_finder . latest_version
18 | end
19 |
20 | # This is currently used to short-circuit latest_resolvable_version,
=> #0 Dependabot::GoModules::UpdateChecker#latest_resolvable_version at ~/go_modules/lib/dependabot/go_modules/update_checker.rb:16
#1 Dependabot::GoModules::UpdateChecker#latest_version at ~/go_modules/lib/dependabot/go_modules/update_checker.rb:24
# and 9 frames (use `bt' command for all frames)
( rdbg )
En este mensaje, puede ejecutar comandos del depurador para navegar o ingresar métodos y variables para ver qué contienen. Intente ingresar dependency
para ver en qué dependencia está trabajando actualmente el Dependabot.
Nota Mientras esté en el depurador, los cambios realizados en el código fuente no se recogerán. Tendrá que finalizar su sesión de depuración y reiniciarla.
Cuando estás depurando un problema, a menudo necesitas echar un vistazo al interior de estos scripts que se ejecutan en un proceso separado.
Imprima todas las declaraciones de registro de los ayudantes nativos usando DEBUG_HELPERS=true
:
DEBUG_HELPERS=true bin/dry-run.rb bundler dependabot/demo --dir= " /ruby "
Pause la ejecución para depurar una única función auxiliar nativa usando DEBUG_FUNCTION=<function name>
. La función se asigna a un nombre de función auxiliar nativa, por ejemplo, una de las funciones en bundler/helpers/v2/lib/functions.rb
.
Cuando se ejecuta esta función, se inserta un debugger
que pausa la ejecución del script bin/dry-run.rb
, esto deja el directorio tmp
de actualizaciones actual en su lugar, lo que le permite cd
al directorio y ejecutar la función auxiliar nativa directamente:
DEBUG_FUNCTION=parsed_gemfile bin/dry-run.rb bundler dependabot/demo --dir= " /ruby "
= > fetching dependency files
= > dumping fetched dependency files: ./dry-run/dependabot/demo/ruby
= > parsing dependency files
$ cd /home/dependabot/dependabot-core/tmp/dependabot_TEMP/ruby && echo " { " function " : " parsed_gemfile " , " args " :{ " gemfile_name " : " Gemfile " , " lockfile_name " : " Gemfile.lock " , " dir " : " /home/dependabot/dependabot-core/tmp/dependabot_TEMP/ruby " }} " | BUNDLER_VERSION=1.17.3 BUNDLE_GEMFILE=/opt/bundler/v1/Gemfile GEM_HOME=/opt/bundler/v1/.bundle bundle exec ruby /opt/bundler/v1/run.rb
Copie y ejecute el comando cd...
:
cd /home/dependabot/dependabot-core/tmp/dependabot_TEMP/ruby && echo " { " function " : " parsed_gemfile " , " args " :{ " gemfile_name " : " Gemfile " , " lockfile_name " : " Gemfile.lock " , " dir " : " /home/dependabot/dependabot-core/tmp/dependabot_TEMP/ruby " }} " | BUNDLER_VERSION=1.17.3 BUNDLE_GEMFILE=/opt/bundler/v1/Gemfile GEM_HOME=/opt/bundler/v1/.bundle bundle exec ruby /opt/bundler/v1/run.rb
Esto debería cerrar la sesión de la salida de la función parsed_gemfile
:
{ "result" : [ { "name" : "business" , "requirement" : "~> 1.0.0" , "groups" : [ "default" ] , "source" : null , "type" : "runtime" } , { "name" : "uk_phone_numbers" , "requirement" : "~> 0.1.0" , "groups" : [ "default" ] , "source" : null , "type" : "runtime" } ] }
Tenga en cuenta que, a diferencia de los cambios en el código fuente de Ruby, los cambios en su máquina host en el código fuente de los asistentes nativos no se sincronizan con el contenedor de desarrollo. Entonces tienes dos opciones para editar el asistente nativo:
vi /opt/bundler/v1/lib/functions/file_parser.rb
. Y luego vuelva a ejecutar el comando cd...
Esta es la forma más rápida de depurar, pero los cambios no se guardarán fuera del contenedor. La mayoría de los ecosistemas compatibles con Dependabot-Core ignore
las condiciones que permiten a un usuario especificar nombres o versiones de dependencia para excluirlas de las actualizaciones. Los documentos del servicio Dependabot en GitHub describen la función con más detalle.
La CLI del Dependabot admite pasar condiciones de ignorar como parte de la definición del trabajo. Vea el ejemplo.
El script de ejecución en seco admite pasar una o más condiciones de ignorar a través de la var env IGNORE_CONDITIONS
:
IGNORE_CONDITIONS= ' [{"dependency-name":"*","update-types": ["version-update:semver-major"]}] '
bin/dry-run.rb docker test_org/test-dependabot `
Muchos de los ecosistemas de Dependabot-Core admiten actualizaciones de seguridad. Se trata de una forma especial de actualización de versión en la que se pasa un nombre de dependencia y un rango de versiones vulnerables. Dependabot-Core intentará actualizar cualquier instancia de esa dependencia a la versión mínima no vulnerable. Esto contrasta con una actualización de versión normal que intenta actualizar a la última versión.
La var de entorno SECURITY_ADVISORIES
permite pasar una o más notificaciones de alerta de seguridad al script de ejecución en seco para simular una actualización de seguridad:
SECURITY_ADVISORIES= ' [{"dependency-name":"buffer","patched-versions":[],"unaffected-versions":[],"affected-versions":["<= 2.0.0"]}] '
bin/dry-run.rb pub dart-lang/pub-dev --dir " /app " --cache=files --dep= " buffer "
Hay soporte integrado para aprovechar la capacidad de Visual Studio Code para depurar dentro de un contenedor Docker. Después de instalar la extensión Dev Containers
recomendada, simplemente presione Ctrl+Shift+P
( ⇧⌘P
en macOS) y seleccione Dev Containers: Reopen in Container
. También puede acceder al menú desplegable haciendo clic en el botón verde en la esquina inferior izquierda del editor. Si la imagen de desarrollo de Docker no está presente en su máquina, se creará automáticamente. Una vez que haya terminado, inicie la configuración Debug Dry Run
(F5)
y se le pedirá que seleccione un administrador de paquetes y un repositorio para realizar una ejecución en seco. Siéntase libre de colocar puntos de interrupción en el código.
También hay soporte para depurar ejecuciones de pruebas individuales ejecutando la configuración Debug Tests
(F5)
y se le pedirá que seleccione un ecosistema y proporcione una ruta rspec.
Clone Repository ...
de la extensión Remote Containers actualmente les faltan algunas funciones y, por lo tanto, no son compatibles. Debe clonar el repositorio manualmente y usar el comando Reopen in Container
o Open Folder in Container...
Una vez que tenga el entorno de desarrollo para un ecosistema en particular, ejecute las pruebas para ese ecosistema ejecutando rspec spec
dentro de la carpeta de ese ecosistema, por ejemplo
$ cd go_modules
$ rspec spec
También puedes limitar las pruebas solo al archivo en el que estás trabajando, o solo a las pruebas que fallaron anteriormente, por ejemplo:
$ rspec spec/dependabot/file_updaters/elixir --only-failures
El estilo lo impone RuboCop. Para comprobar si hay violaciones de estilo, simplemente ejecute rubocop
en cada uno de los paquetes, por ejemplo
$ cd go_modules
$ rubocop
Puede crear un perfil de ejecución en seco pasando el indicador --profile
al ejecutarlo, o etiquetar una prueba rspec
con :profile
. Esto generará un archivo stackprof-<datetime>.dump
en la carpeta tmp/
, y puedes generar un flamegraph a partir de esto ejecutando:
stackprof --d3-flamegraph tmp/stackprof- < data or spec name > .dump > tmp/flamegraph.html
Dependabot-Core es una colección de paquetes Ruby (gemas), que contienen la lógica para actualizar dependencias en varios idiomas.
dependabot-common
El paquete common
contiene todas las funciones compartidas/de uso general. Por ejemplo, el código para crear solicitudes de extracción para las diferentes plataformas compatibles se encuentra aquí, al igual que la mayor parte de la lógica para manejar las dependencias de Git (ya que la mayoría de los lenguajes admiten dependencias de Git de una forma u otra). También hay clases base definidas para cada una de las principales preocupaciones necesarias para implementar el soporte para un lenguaje o administrador de paquetes.
dependabot-{package-manager}
Hay una joya para cada administrador de paquetes o idioma que admite Dependabot. Como mínimo, cada una de estas gemas implementará las siguientes clases:
Servicio | Descripción |
---|---|
FileFetcher | Recupera los archivos de dependencia relevantes para un proyecto (por ejemplo, Gemfile y Gemfile.lock ). Consulte el archivo LÉAME para obtener más detalles. |
FileParser | Analiza un archivo de dependencia y extrae una lista de dependencias para un proyecto. Consulte el archivo LÉAME para obtener más detalles. |
UpdateChecker | Comprueba si una dependencia determinada está actualizada. Consulte el archivo LÉAME para obtener más detalles. |
FileUpdater | Actualiza un archivo de dependencia para usar la última versión de una dependencia determinada. Consulte el archivo LÉAME para obtener más detalles. |
MetadataFinder | Busca metadatos sobre una dependencia, como su URL de GitHub. Consulte el archivo LÉAME para obtener más detalles. |
Version | Describe la lógica para comparar versiones de dependencia. Vea la clase Versión hexadecimal para ver un ejemplo. |
Requirement | Describe el formato de un requisito de dependencia (por ejemplo, >= 1.2.3 ). Consulte la clase de requisito hexadecimal para ver un ejemplo. |
El flujo de alto nivel se ve así:
dependabot-omnibus
Esta es una "meta" joya, que simplemente depende de todas las demás. Si desea incluir automáticamente soporte para todos los idiomas, puede incluir esta joya y obtendrá todo lo que necesita.
Para muchos ecosistemas, Dependabot-Core admite registros privados. A veces, esto sucede al pasar las credenciales del registro privado directamente a los administradores de paquetes nativos ( npm
, pip
, bundler
, etc.), otras veces sucede dentro del código Ruby de Dependabot-Core.
diagrama de secuencia
Credenciales de registro privado->>Dependabot-Core:<br />
Dependabot-Core->>Administradores de paquetes nativos:<br />
Administradores de paquetes nativos->>Registros de paquetes:<br />
Dependabot-Core->>Registros de paquetes:<br />
Si bien es simple y directo, esto representa un riesgo de seguridad para los ecosistemas que permiten ejecutar código que no es de confianza dentro de sus archivos de manifiesto. Por ejemplo, setup.py
y .gemspec
permiten ejecutar código nativo Python y Ruby. Si un paquete en el árbol de dependencia es pirateado, un atacante podría enviar un manifiesto malicioso que obligue al administrador de paquetes nativo a exponer los créditos.
Para protegerse contra esto, para el servicio Dependabot que ejecuta Github, envolvemos Dependabot-Core con un proxy de credenciales para que esos secretos de registro privados nunca queden expuestos a Dependabot-Core.
diagrama de secuencia
Dependabot-Core->>Proxy de credenciales: todas las solicitudes no están autenticadas
Proxy de credenciales->>Registros de paquetes: el proxy inyecta las credenciales
Nota a la izquierda de Dependabot-Core: El servicio Dependabot<br /> que ejecuta GitHub
Registros de paquetes->>Proxy de credenciales: el proxy elimina las credenciales
Proxy de credenciales->>Dependabot-Core: Dependabot-Core nunca ve las credenciales de registro privadas
Esto también significa que si Dependabot-Core alguna vez tiene una vulnerabilidad de seguridad, esos créditos aún no corren riesgo de quedar expuestos.
Este proyecto puede contener marcas comerciales o logotipos de proyectos, productos o servicios. El uso autorizado de las marcas comerciales o logotipos de GitHub está sujeto y debe seguir los logotipos y el uso de GitHub. El uso de marcas comerciales o logotipos de GitHub en versiones modificadas de este proyecto no debe causar confusión ni implicar patrocinio de GitHub. Cualquier uso de marcas comerciales o logotipos de terceros está sujeto a las políticas de dichos terceros.
Dependabot y dependabot-core comenzaron su vida como Bump y Bump Core, cuando @hmarr y @greysteil trabajaban en GoCardless.
¡Dependabot se convirtió en parte de GitHub en 2019!
Publique una nueva versión en RubyGems ejecutando el flujo de trabajo Gems - Bump Version
y siguiendo las instrucciones en el resumen del trabajo.
En pocas palabras el proceso será:
v1.2.3
. El resumen del trabajo contiene una URL rellenada previamente con la versión correcta del título y la etiqueta.