Guía de migración de Bzlmod

Informar un problema Ver fuente Por la noche 7.3 · 7.2 · 7.1 · 7.0 · 6.5

Debido a las carencias de WORKSPACE, Bzlmod reemplazará el sistema heredado de WORKSPACE. El archivo WORKSPACE se inhabilitará de forma predeterminada en Bazel 8 (a fines de 2024) y se quitará en Bazel 9 (a fines de 2025). Esta guía te ayuda a migrar tu proyecto a Bzlmod y a descartar WORKSPACE para recuperar dependencias externas.

WORKSPACE frente a Bzlmod

WORKSPACE y Bzlmod de Bazel ofrecen funciones similares con una sintaxis diferente. En esta sección, se explica cómo migrar desde funciones específicas de WORKSPACE a Bzlmod.

Define la raíz de un espacio de trabajo de Bazel

El archivo WORKSPACE marca la raíz de origen de un proyecto de Bazel. Esta responsabilidad se reemplaza por MODULE.bazel en la versión 6.3 de Bazel y versiones posteriores. Con la versión de Bazel anterior a la 6.3, debería haber un archivo WORKSPACE o WORKSPACE.bazel en la raíz de tu área de trabajo, tal vez con comentarios como los siguientes:

  • WORKSPACE

    # This file marks the root of the Bazel workspace.
    # See MODULE.bazel for external dependencies setup.
    

Cómo habilitar Bzlmod en tu Bazelrc

.bazelrc te permite establecer marcas que se aplican cada vez que ejecutas Bazel. Para habilitar Bzlmod, usa la marca --enable_bzlmod y aplícala al comando common para que se aplique a todos los comandos:

  • .bazelrc

    # Enable Bzlmod for every Bazel command
    common --enable_bzlmod
    

Especifica el nombre del repositorio para tu lugar de trabajo

  • Espacio de trabajo

    La función workspace se usa para especificar un nombre de repositorio para tu lugar de trabajo. Esto permite que se haga referencia a un //foo:bar objetivo en el espacio de trabajo como @<workspace name>//foo:bar. Si no se especifica, el nombre del repositorio predeterminado para tu lugar de trabajo es __main__.

    ## WORKSPACE
    workspace(name = "com_foo_bar")
    
  • Bzlmod

    Se recomienda hacer referencia a los objetivos en el mismo espacio de trabajo con la sintaxis //foo:bar sin @<repo name>. Sin embargo, si necesitas la sintaxis anterior, puedes usar el nombre del módulo especificado por la función module como nombre del repositorio. Si el nombre del módulo es diferente del nombre del repositorio necesario, puedes usar el atributo repo_name de la función module para anular el nombre del repositorio.

    ## MODULE.bazel
    module(
        name = "bar",
        repo_name = "com_foo_bar",
    )
    

Recupera dependencias externas como módulos de Bazel

Si tu dependencia es un proyecto de Bazel, deberías poder depender de ella como un módulo de Bazel cuando también adopte Bzlmod.

  • WORKSPACE

    Con WORKSPACE, es común usar las reglas del repositorio http_archive o git_repository para descargar las fuentes del proyecto Bazel.

    ## WORKSPACE
    load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
    
    http_archive(
        name = "bazel_skylib",
        urls = ["https://github.com/bazelbuild/bazel-skylib/releases/download/1.4.2/bazel-skylib-1.4.2.tar.gz"],
        sha256 = "66ffd9315665bfaafc96b52278f57c7e2dd09f5ede279ea6d39b2be471e7e3aa",
    )
    load("@bazel_skylib//:workspace.bzl", "bazel_skylib_workspace")
    bazel_skylib_workspace()
    
    http_archive(
        name = "rules_java",
        urls = ["https://github.com/bazelbuild/rules_java/releases/download/6.1.1/rules_java-6.1.1.tar.gz"],
        sha256 = "76402a50ae6859d50bd7aed8c1b8ef09dae5c1035bb3ca7d276f7f3ce659818a",
    )
    load("@rules_java//java:repositories.bzl", "rules_java_dependencies", "rules_java_toolchains")
    rules_java_dependencies()
    rules_java_toolchains()
    

    Como puedes ver, es un patrón común que los usuarios deban cargar dependencias transitivas desde una macro de la dependencia. Supongamos que bazel_skylib y rules_java dependen de platform. El orden de las macros determina la versión exacta de la dependencia platform.

  • Bzlmod

    Con Bzlmod, siempre que tu dependencia esté disponible en el registro central de Bazel o en tu registro de Bazel personalizado, puedes depender de él con una directiva bazel_dep.

    ## MODULE.bazel
    bazel_dep(name = "bazel_skylib", version = "1.4.2")
    bazel_dep(name = "rules_java", version = "6.1.1")
    

    Bzlmod resuelve las dependencias de los módulos de Bazel de forma transitiva con el algoritmo MVS. Por lo tanto, se selecciona automáticamente la versión máxima requerida de platform.

Anula una dependencia como un módulo de Bazel

Como módulo raíz, puedes anular las dependencias de los módulos de Bazel de diferentes maneras.

Para obtener más información, consulta la sección Anulaciones.

Puedes encontrar algunos ejemplos de uso en el repositorio de ejemplos.

Cómo recuperar dependencias externas con extensiones de módulo

Si tu dependencia no es un proyecto de Bazel o aún no está disponible en ningún registro de Bazel, puedes ingresarla con use_repo_rule o las extensiones de módulos.

  • Espacio de trabajo

    Descarga un archivo con la regla del repositorio http_file.

    ## WORKSPACE
    load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_file")
    
    http_file(
        name = "data_file",
        url = "http://example.com/file",
        sha256 = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
    )
    
  • Bzlmod

    Con Bzlmod, puedes usar la directiva use_repo_rule en tu archivo MODULE.bazel para crear instancias de repositorios directamente:

    ## MODULE.bazel
    http_file = use_repo_rule("@bazel_tools//tools/build_defs/repo:http.bzl", "http_file")
    http_file(
        name = "data_file",
        url = "http://example.com/file",
        sha256 = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
    )
    

    De forma interna, esto se implementa con una extensión de módulo. Si necesitas realizar una lógica más compleja que simplemente invocar una regla de repositorio, también puedes implementar una extensión de módulo por tu cuenta. Deberás mover la definición a un archivo .bzl, lo que también te permite compartir la definición entre WORKSPACE y Bzlmod durante el período de migración.

    ## repositories.bzl
    load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_file")
    def my_data_dependency():
        http_file(
            name = "data_file",
            url = "http://example.com/file",
            sha256 = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
        )
    

    Implementa una extensión de módulo para cargar la macro de dependencias. Puedes definirlo en el mismo archivo .bzl de la macro, pero para mantener la compatibilidad con versiones anteriores de Bazel, es mejor definirlo en un archivo .bzl independiente.

    ## extensions.bzl
    load("//:repositories.bzl", "my_data_dependency")
    def _non_module_dependencies_impl(_ctx):
        my_data_dependency()
    
    non_module_dependencies = module_extension(
        implementation = _non_module_dependencies_impl,
    )
    

    Para que el proyecto raíz pueda ver el repositorio, debes declarar los usos de la extensión del módulo y el repositorio en el archivo MODULE.bazel.

    ## MODULE.bazel
    non_module_dependencies = use_extension("//:extensions.bzl", "non_module_dependencies")
    use_repo(non_module_dependencies, "data_file")
    

Cómo resolver dependencias externas de conflicto con la extensión de módulo

Un proyecto puede proporcionar una macro que presente repositorios externos según las entradas de sus llamadores. Pero ¿qué sucede si hay varios llamadores en el gráfico de dependencia y estos generan un conflicto?

Supongamos que el proyecto foo proporciona la siguiente macro que toma version como argumento.

## repositories.bzl in foo {:#repositories.bzl-foo}
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_file")
def data_deps(version = "1.0"):
    http_file(
        name = "data_file",
        url = "http://example.com/file-%s" % version,
        # Omitting the "sha256" attribute for simplicity
    )
  • Espacio de trabajo

    Con WORKSPACE, puedes cargar la macro desde @foo y especificar la versión de la dependencia de datos que necesitas. Supongamos que tienes otra dependencia @bar, que también depende de @foo, pero requiere una versión diferente de la dependencia de datos.

    ## WORKSPACE
    
    # Introduce @foo and @bar.
    ...
    
    load("@foo//:repositories.bzl", "data_deps")
    data_deps(version = "2.0")
    
    load("@bar//:repositories.bzl", "bar_deps")
    bar_deps() # -> which calls data_deps(version = "3.0")
    

    En este caso, el usuario final debe ajustar cuidadosamente el orden de las macros en WORKSPACE para obtener la versión que necesita. Este es uno de los problemas más grandes de WORKSPACE, ya que no proporciona una forma sensata de resolver las dependencias.

  • Bzlmod

    Con Bzlmod, el autor del proyecto foo puede usar la extensión de módulo para resolver los conflictos. Por ejemplo, supongamos que tiene sentido seleccionar siempre la versión máxima requerida de la dependencia de datos entre todos los módulos de Bazel.

    ## extensions.bzl in foo
    load("//:repositories.bzl", "data_deps")
    
    data = tag_class(attrs={"version": attr.string()})
    
    def _data_deps_extension_impl(module_ctx):
        # Select the maximal required version in the dependency graph.
        version = "1.0"
        for mod in module_ctx.modules:
            for data in mod.tags.data:
                version = max(version, data.version)
        data_deps(version)
    
    data_deps_extension = module_extension(
        implementation = _data_deps_extension_impl,
        tag_classes = {"data": data},
    )
    
    ## MODULE.bazel in bar
    bazel_dep(name = "foo", version = "1.0")
    
    foo_data_deps = use_extension("@foo//:extensions.bzl", "data_deps_extension")
    foo_data_deps.data(version = "3.0")
    use_repo(foo_data_deps, "data_file")
    
    ## MODULE.bazel in root module
    bazel_dep(name = "foo", version = "1.0")
    bazel_dep(name = "bar", version = "1.0")
    
    foo_data_deps = use_extension("@foo//:extensions.bzl", "data_deps_extension")
    foo_data_deps.data(version = "2.0")
    use_repo(foo_data_deps, "data_file")
    

    En este caso, el módulo raíz requiere la versión de datos 2.0, mientras que su dependencia bar requiere 3.0. La extensión del módulo en foo puede resolver correctamente este conflicto y seleccionar automáticamente la versión 3.0 para la dependencia de datos.

Cómo integrar un administrador de paquetes de terceros

Siguiendo con la última sección, como la extensión del módulo proporciona una forma de recopilar información del gráfico de dependencias, realizar una lógica personalizada para resolver dependencias y llamar a las reglas del repositorio para introducir repositorios externos, esto proporciona una excelente manera para que los autores de reglas mejoren los conjuntos de reglas que integran los administradores de paquetes para lenguajes específicos.

Lee la página Extensiones de módulo para obtener más información sobre cómo usarlas.

A continuación, se muestra una lista de los conjuntos de reglas que ya adoptaron Bzlmod para recuperar dependencias de diferentes administradores de paquetes:

Hay un ejemplo mínimo que integra un pseudoadministrador de paquetes disponible en el repositorio de ejemplos.

Detecta cadenas de herramientas en la máquina anfitrión

Cuando las reglas de compilación de Bazel deben detectar qué cadenas de herramientas están disponibles en la máquina anfitrión, usan reglas de repositorio para inspeccionar la máquina anfitrión y generar información de la cadena de herramientas como repositorios externos.

  • Espacio de trabajo

    Se proporciona la siguiente regla de repositorio para detectar una cadena de herramientas de shell.

    ## local_config_sh.bzl
    def _sh_config_rule_impl(repository_ctx):
        sh_path = get_sh_path_from_env("SH_BIN_PATH")
    
        if not sh_path:
            sh_path = detect_sh_from_path()
    
        if not sh_path:
            sh_path = "/shell/binary/not/found"
    
        repository_ctx.file("BUILD", """
    load("@bazel_tools//tools/sh:sh_toolchain.bzl", "sh_toolchain")
    sh_toolchain(
        name = "local_sh",
        path = "{sh_path}",
        visibility = ["//visibility:public"],
    )
    toolchain(
        name = "local_sh_toolchain",
        toolchain = ":local_sh",
        toolchain_type = "@bazel_tools//tools/sh:toolchain_type",
    )
    """.format(sh_path = sh_path))
    
    sh_config_rule = repository_rule(
        environ = ["SH_BIN_PATH"],
        local = True,
        implementation = _sh_config_rule_impl,
    )
    

    Puedes cargar la regla del repositorio en WORKSPACE.

    ## WORKSPACE
    load("//:local_config_sh.bzl", "sh_config_rule")
    sh_config_rule(name = "local_config_sh")
    
  • Bzlmod

    Con Bzlmod, puedes introducir el mismo repositorio con una extensión de módulo, que es similar a introducir el repositorio @data_file en la última sección.

    ## local_config_sh_extension.bzl
    load("//:local_config_sh.bzl", "sh_config_rule")
    
    sh_config_extension = module_extension(
        implementation = lambda ctx: sh_config_rule(name = "local_config_sh"),
    )
    

    Luego, usa la extensión en el archivo MODULE.bazel.

    ## MODULE.bazel
    sh_config_ext = use_extension("//:local_config_sh_extension.bzl", "sh_config_extension")
    use_repo(sh_config_ext, "local_config_sh")
    

Registra cadenas de herramientas y plataformas de ejecución

Siguiendo la última sección, después de ingresar la información de la cadena de herramientas de hosting de un repositorio (p.ej., local_config_sh), es probable que desees registrar la cadena de herramientas.

  • Espacio de trabajo

    Con WORKSPACE, puedes registrar la cadena de herramientas de las siguientes maneras.

    1. Puedes registrar la cadena de herramientas en el archivo .bzl y cargar la macro en el archivo WORKSPACE.

      ## local_config_sh.bzl
      def sh_configure():
          sh_config_rule(name = "local_config_sh")
          native.register_toolchains("@local_config_sh//:local_sh_toolchain")
      
      ## WORKSPACE
      load("//:local_config_sh.bzl", "sh_configure")
      sh_configure()
      
    2. También puedes registrar la cadena de herramientas directamente en el archivo WORKSPACE.

      ## WORKSPACE
      load("//:local_config_sh.bzl", "sh_config_rule")
      sh_config_rule(name = "local_config_sh")
      register_toolchains("@local_config_sh//:local_sh_toolchain")
      
  • Bzlmod

    Con Bzlmod, las APIs de register_toolchains y register_execution_platforms solo están disponibles en el archivo MODULE.bazel. No puedes llamar a native.register_toolchains en una extensión de módulo.

    ## MODULE.bazel
    sh_config_ext = use_extension("//:local_config_sh_extension.bzl", "sh_config_extension")
    use_repo(sh_config_ext, "local_config_sh")
    register_toolchains("@local_config_sh//:local_sh_toolchain")
    

Las cadenas de herramientas y las plataformas de ejecución registradas en WORKSPACE, WORKSPACE.bzlmod y el archivo MODULE.bazel de cada módulo de Bazel siguen este orden de prioridad durante la selección de la cadena de herramientas (de la más alta a la más baja):

  1. cadenas de herramientas y plataformas de ejecución registradas en el archivo MODULE.bazel del módulo raíz
  2. plataformas de ejecución y cadenas de herramientas registradas en el archivo WORKSPACE o WORKSPACE.bzlmod.
  3. cadenas de herramientas y plataformas de ejecución registradas por módulos que son dependencias (transitivas) del módulo raíz.
  4. Cuando no se usa WORKSPACE.bzlmod: las cadenas de herramientas registradas en el sufijo WORKSPACE.

Presenta repositorios locales

Es posible que debas introducir una dependencia como un repositorio local cuando necesites una versión local de la dependencia para depurar o quieras incorporar un directorio en tu espacio de trabajo como repositorio externo.

  • WORKSPACE

    Con WORKSPACE, esto se logra con dos reglas de repositorio nativas, local_repository y new_local_repository.

    ## WORKSPACE
    local_repository(
        name = "rules_java",
        path = "/Users/bazel_user/workspace/rules_java",
    )
    
  • Bzlmod

    Con Bzlmod, puedes usar local_path_override para anular un módulo con una ruta local.

    ## MODULE.bazel
    bazel_dep(name = "rules_java")
    local_path_override(
        module_name = "rules_java",
        path = "/Users/bazel_user/workspace/rules_java",
    )
    

    También es posible introducir un repositorio local con extensión de módulo. Sin embargo, no puedes llamar a native.local_repository en la extensión del módulo, ya que hay un esfuerzo continuo para realizar una acción estándar de todas las reglas del repositorio nativo (consulta #18285 para ver el progreso). Luego, puedes llamar al local_repository de Starlark correspondiente en una extensión de módulo. También es trivial implementar una versión personalizada de la regla del repositorio local_repository si este es un problema de bloqueo para ti.

Vincula destinos

La regla bind en WORKSPACE dejó de estar disponible y no es compatible con Bzlmod. Se introdujo para asignarle un alias a un objetivo en el paquete //external especial. Todos los usuarios que dependan de esta opción deberían migrar.

Por ejemplo, si tienes

## WORKSPACE
bind(
    name = "openssl",
    actual = "@my-ssl//src:openssl-lib",
)

Esto permite que otros objetivos dependan de //external:openssl. Para migrar de esta opción, haz lo siguiente:

  • Reemplaza todos los usos de //external:openssl por @my-ssl//src:openssl-lib.

  • O bien usa la regla de compilación alias.

    • Define el siguiente destino en un paquete (p. ej., //third_party).

      ## third_party/BUILD
      alias(
          name = "openssl",
          actual = "@my-ssl//src:openssl-lib",
      )
      
    • Reemplaza todos los usos de //external:openssl por //third_party:openssl.

Recuperación en comparación con sincronización

Los comandos de recuperación y sincronización se usan para descargar repositorios externos de manera local y mantenerlos actualizados. A veces, también para permitir la compilación sin conexión con la marca --nofetch después de recuperar todos los repositorios necesarios para una compilación.

  • WORKSPACE

    La sincronización realiza una recuperación forzada de todos los repositorios o de un conjunto específico de repositorios configurados, mientras que la recuperación solo se usa para recuperar un destino específico.

  • Bzlmod

    El comando sync ya no se aplica, pero la recuperación ofrece varias opciones. Puedes recuperar un destino, un repositorio, un conjunto de repositorios configurados o todos los repositorios involucrados en la resolución de dependencias y las extensiones de módulos. El resultado de la recuperación se almacena en caché y, para forzar una recuperación, debes incluir la opción --force durante el proceso de recuperación.

Migración

En esta sección, se proporciona información útil y orientación para tu proceso de migración de Bzlmod.

Conoce tus dependencias en WORKSPACE

El primer paso de la migración es comprender qué dependencias tienes. Puede ser difícil determinar qué dependencias exactas se introdujeron en el archivo WORKSPACE, ya que las dependencias transitivas suelen cargarse con macros *_deps.

Inspecciona la dependencia externa con el archivo resuelto de Workspace

Afortunadamente, la marca --experimental_repository_resolved_file puede ser útil. Esta marca genera, en esencia, un “archivo de bloqueo” de todas las dependencias externas recuperadas en tu último comando de Bazel. Encontrarás más detalles en esta entrada de blog.

Se puede usar de dos maneras:

  1. Para recuperar información de las dependencias externas necesarias para compilar ciertos destinos.

    bazel clean --expunge
    bazel build --nobuild --experimental_repository_resolved_file=resolved.bzl //foo:bar
    
  2. Para recuperar información de todas las dependencias externas definidas en el archivo WORKSPACE.

    bazel clean --expunge
    bazel sync --experimental_repository_resolved_file=resolved.bzl
    

    Con el comando bazel sync, puedes recuperar todas las dependencias definidas en el archivo WORKSPACE, que incluyen lo siguiente:

    • bind usos
    • Usos de register_toolchains y register_execution_platforms

    Sin embargo, si tu proyecto es multiplataforma, es posible que la sincronización de Bazel falle en ciertas plataformas porque algunas reglas del repositorio solo se pueden ejecutar correctamente en plataformas compatibles.

Después de ejecutar el comando, deberías tener información de tus dependencias externas en el archivo resolved.bzl.

Inspecciona la dependencia externa con bazel query

También es posible que sepas que bazel query se puede usar para inspeccionar las reglas del repositorio con

bazel query --output=build //external:<repo name>

Si bien es más conveniente y mucho más rápido, la consulta de bazel puede mentir sobre la versión de la dependencia externa, así que ten cuidado cuando la uses. La consulta y la inspección de dependencias externas con Bzlmod se lograrán con un subcomando nuevo.

Dependencias predeterminadas integradas

Si revisas el archivo que genera --experimental_repository_resolved_file, encontrarás muchas dependencias que no están definidas en tu WORKSPACE. Esto se debe a que Bazel agrega prefijos y sufijos al contenido del archivo WORKSPACE del usuario para insertar algunas dependencias predeterminadas, que suelen requerir las reglas nativas (p.ej., @bazel_tools, @platforms y @remote_java_tools). Con Bzlmod, esas dependencias se introducen con un módulo integrado bazel_tools, que es una dependencia predeterminada para todos los demás módulos de Bazel.

Modo híbrido para la migración gradual

Bzlmod y WORKSPACE pueden funcionar en paralelo, lo que permite que la migración de dependencias del archivo WORKSPACE a Bzlmod sea un proceso gradual.

WORKSPACE.bzlmod

Durante la migración, es posible que los usuarios de Bazel deban cambiar entre compilaciones con Bzlmod habilitado y sin él. Se implementó la compatibilidad con WORKSPACE.bzlmod para que el proceso sea más fluido.

WORKSPACE.bzlmod tiene la misma sintaxis que WORKSPACE. Cuando Bzlmod está habilitado, si también existe un archivo WORKSPACE.bzlmod en la raíz del espacio de trabajo, sucede lo siguiente:

  • WORKSPACE.bzlmod se aplica y se ignora el contenido de WORKSPACE.
  • No se agregan prefijos ni sufijos al archivo WORKSPACE.bzlmod.

El uso del archivo WORKSPACE.bzlmod puede facilitar la migración por los siguientes motivos:

  • Cuando Bzlmod está inhabilitado, se vuelve a recuperar las dependencias del archivo WORKSPACE original.
  • Cuando Bzlmod está habilitado, puedes hacer un mejor seguimiento de las dependencias que quedan para migrar con WORKSPACE.bzlmod.

Visibilidad del repositorio

Bzlmod puede controlar qué otros repositorios son visibles desde un repositorio determinado. Para obtener más información, consulta Nombres de repositorios y dependencias estrictas.

A continuación, se muestra un resumen de las visibilidades de repositorios de diferentes tipos de repositorios cuando también se tiene en cuenta WORKSPACE.

Desde el repositorio principal Desde repositorios de módulos de Bazel Desde repositorios de extensiones de módulos Desde los repositorios de WORKSPACE
El repositorio principal Visible Si el módulo raíz es una dependencia directa Si el módulo raíz es una dependencia directa del módulo que aloja la extensión del módulo Visible
Repos de módulos de Bazel Dependencias directas Dependencias directas Dependencias directas del módulo que aloja la extensión del módulo Dependencias directas del módulo raíz
Repositorios de extensiones de módulos Dependencias directas Dependencias directas Las dependencias directas del módulo que alojan la extensión del módulo y todos los repositorios generados por la misma extensión del módulo Dependencias directas del módulo raíz
Repositorios de WORKSPACE Todos los visibles No visible No visible Todo visible

Proceso de migración

Un proceso de migración de Bzlmod típico puede verse de la siguiente manera:

  1. Comprende qué dependencias tienes en WORKSPACE.
  2. Agrega un archivo MODULE.bazel vacío en la raíz de tu proyecto.
  3. Agrega un archivo WORKSPACE.bzlmod vacío para anular el contenido del archivo WORKSPACE.
  4. Compila tus destinos con Bzlmod habilitado y verifica qué repositorio falta.
  5. Verifica la definición del repositorio faltante en el archivo de dependencia resuelto.
  6. Introduce la dependencia faltante como un módulo de Bazel, a través de una extensión de módulo, o déjala en WORKSPACE.bzlmod para migrarla más adelante.
  7. Regresa al paso 4 y repite el proceso hasta que todas las dependencias estén disponibles.

Herramienta de migración

Hay una secuencia de comandos auxiliar de migración de Bzlmod interactiva que puede ayudarte a comenzar.

La secuencia de comandos hace lo siguiente:

  • Genera y analiza el archivo WORKSPACE resuelto.
  • Imprime la información del repositorio del archivo resuelto en lenguaje natural.
  • Ejecuta el comando de compilación de Bazel, detecta los mensajes de error reconocidos y recomienda una manera de migrar.
  • Verifica si una dependencia ya está disponible en BCR.
  • Agrega una dependencia al archivo MODULE.bazel.
  • Agrega una dependencia a través de una extensión de módulo.
  • Agrega una dependencia al archivo WORKSPACE.bzlmod.

Para usarlo, asegúrate de tener instalada la versión más reciente de Bazel y ejecuta el siguiente comando:

git clone https://github.com/bazelbuild/bazel-central-registry.git
cd <your workspace root>
<BCR repo root>/tools/migrate_to_bzlmod.py -t <your build targets>

Publica módulos de Bazel

Si tu proyecto de Bazel es una dependencia para otros proyectos, puedes publicarlo en el Registro Central de Bazel.

Para poder registrar tu proyecto en el BCR, necesitas una URL de archivo fuente del proyecto. Ten en cuenta lo siguiente cuando crees el archivo fuente:

  • Asegúrate de que el archivo dirija a una versión específica.

    BCR solo puede aceptar archivos de origen con versión porque Bzlmod debe realizar una comparación de versiones durante la resolución de la dependencia.

  • Asegúrate de que la URL del archivo sea estable.

    Bazel verifica el contenido del archivo mediante un valor hash, por lo que debes asegurarte de que la suma de comprobación del archivo descargado nunca cambie. Si la URL es de GitHub, crea y sube un archivo de lanzamiento en la página de lanzamiento. GitHub no garantizará la suma de comprobación de los archivos fuente generados a pedido. En resumen, las URLs en forma de https://github.com/<org>/<repo>/releases/download/... se consideran estables, mientras que https://github.com/<org>/<repo>/archive/... no lo es. Consulta la Interrupción de la suma de comprobación del archivo de GitHub para obtener más información.

  • Asegúrate de que el árbol de origen siga el diseño del repositorio original.

    En caso de que tu repositorio sea muy grande y desees crear un archivo de distribución con tamaño reducido mediante la eliminación de fuentes innecesarias, asegúrate de que el árbol de fuentes quitado sea un subconjunto del árbol de fuentes original. Esto facilita que los usuarios finales anulen el módulo a una versión que no sea de lanzamiento mediante archive_override y git_override.

  • Incluye un módulo de prueba en un subdirectorio que pruebe las APIs más comunes.

    Un módulo de prueba es un proyecto de Bazel con su propio archivo WORKSPACE y MODULE.bazel, que se encuentra en un subdirectorio del archivo fuente que depende del módulo real que se publicará. Debe contener ejemplos o algunas pruebas de integración que abarquen tus APIs más comunes. Consulta el módulo de prueba para aprender a configurarlo.

Cuando tengas lista la URL del archivo fuente, sigue los lineamientos de contribución de la BCR para enviar tu módulo a la BCR con una solicitud de extracción de GitHub.

Se recomienda configurar la app de GitHub Publish to BCR para que tu repositorio automatice el proceso de envío del módulo al BCR.

Prácticas recomendadas

En esta sección, se documentan algunas prácticas recomendadas que debes seguir para administrar mejor tus dependencias externas.

Divide los destinos en diferentes paquetes para evitar recuperar dependencias innecesarias.

Marca #12835, donde las dependencias de desarrollo para pruebas se fuerzan a recuperarse de manera innecesaria para compilar destinos que no los necesitan. En realidad, esto no es específico de Bzlmod, pero seguir estas prácticas facilita la especificación correcta de las dependencias de dev.

Especifica dependencias de dev

Puedes establecer el atributo dev_dependency como verdadero para las directivas bazel_dep y use_extension para que no se propaguen a proyectos dependientes. Como módulo raíz, puedes usar la marca --ignore_dev_dependency para verificar si tus destinos aún compilan sin anulaciones ni dependencias de desarrollo.

Progreso de la migración de la comunidad

Puedes consultar el Registro central de Bazel para saber si tus dependencias ya están disponibles. De lo contrario, puedes unirte a esta discusión de GitHub para votar a favor o publicar las dependencias que bloquean tu migración.

Cómo informar problemas

Consulta la lista de problemas de GitHub de Bazel para conocer los problemas conocidos de Bzlmod. No dudes en informar nuevos problemas o solicitudes de funciones que puedan ayudarte a desbloquear tu migración.