1 points par GN⁺ 4 시간 전 | 1 commentaires | Partager sur WhatsApp
  • Copybara est un outil utilisé en interne chez Google pour transformer et déplacer du code source entre plusieurs dépôts, notamment afin de synchroniser des dépôts confidentiels et publics
  • Il permet de conserver une source unique de vérité en choisissant un dépôt comme dépôt d’autorité, tout en acceptant des contributions depuis n’importe quel dépôt et en permettant de créer des releases depuis n’importe lequel
  • Son principal cas d’usage est le déplacement récurrent de code, avec des flux permettant d’importer une partie du code d’un dépôt confidentiel vers un dépôt public, ou de rapatrier des changements d’un dépôt public vers le dépôt faisant autorité
  • Copybara adopte une approche stateless : au lieu de stocker son état sur un serveur séparé, il l’enregistre dans les labels des messages de commit du dépôt cible, ce qui permet à plusieurs utilisateurs ou services d’obtenir le même résultat avec la même configuration et les mêmes dépôts
  • Le type de dépôt actuellement pris en charge est Git ; la lecture depuis Mercurial est expérimentale, et son architecture extensible permet d’ajouter des origines et destinations personnalisées

Le problème que résout Copybara

  • Copybara est un outil destiné au déplacement et à la transformation de code source entre dépôts
  • Il arrive que du code source doive exister dans plusieurs dépôts ; Copybara permet de transformer et de déplacer ce code entre ces dépôts
  • Un cas représentatif est celui d’un projet maintenant synchronisés un dépôt confidentiel et un dépôt public
  • Le mode d’utilisation le plus courant consiste à déplacer du code de manière répétée d’un dépôt vers un autre
  • Il peut aussi être utilisé pour déplacer du code une seule fois vers un nouveau dépôt

Dépôt d’autorité et flux de contributions

  • Copybara exige de choisir l’un des dépôts comme authoritative repository
    • C’est une condition pour qu’il existe toujours une seule source of truth
  • Les contributions peuvent venir de n’importe quel dépôt
  • Les releases peuvent aussi être créées depuis n’importe quel dépôt
  • Lorsqu’un changement intervient dans un dépôt ne faisant pas autorité, Copybara peut le transformer et le déplacer vers l’emplacement approprié dans le dépôt d’autorité
    • L’exemple donné est un changement créé par un contributeur du dépôt public
    • Les conflits de merge sont traités de la même manière que les anciens changements dans le dépôt d’autorité

Exemples d’utilisation

  • Les exemples d’utilisation de Copybara incluent :
    • importer une partie du code d’un dépôt confidentiel vers un dépôt public
    • importer le code d’un dépôt public vers un dépôt confidentiel
    • importer des changements d’un dépôt non autoritaire vers un dépôt faisant autorité
  • Un exemple de configuration définit l’origine et la destination avec core.workflow
    • L’origine utilise git.github_origin avec la branche master de https://github.com/google/copybara.git
    • La destination utilise git.destination avec file:///tmp/foo
    • destination_files cible third_party/copybara/** et exclut README_INTERNAL.txt
    • core.replace et core.move effectuent la substitution de chemin du fichier BUILD et le déplacement de répertoire
  • Un exemple d’exécution consiste à créer un dépôt Git bare, puis à lancer copybara copy.bara.sky

Stockage de l’état et prise en charge des dépôts

  • L’une des principales caractéristiques de Copybara est son architecture stateless
  • Plus précisément, l’état est stocké dans le dépôt cible
    • L’emplacement de stockage est constitué par les labels des messages de commit
  • Cette approche permet à plusieurs utilisateurs ou services d’obtenir le même résultat avec la même combinaison de configuration et de dépôts
  • Le type de dépôt actuellement pris en charge est Git
  • La lecture depuis des dépôts Mercurial est possible, mais reste expérimentale
  • Grâce à une architecture extensible, il est possible d’ajouter des origines et destinations sur mesure pour presque tous les cas d’usage
  • La prise en charge officielle d’autres types de dépôts sera ajoutée ultérieurement

Installation et build

  • Le moyen le plus simple de démarrer consiste à utiliser une snapshot release hebdomadaire incluant des binaires précompilés
  • Pour utiliser une version non publiée, il faut builder depuis HEAD
    • Installation de JDK 11 requise
    • Installation de Bazel requise
    • Cloner les sources avec git clone https://github.com/google/copybara.git
    • Builder avec bazel build //java/com/google/copybara
    • L’uberjar exécutable est généré avec bazel build //java/com/google/copybara:copybara_deploy.jar
    • Les tests peuvent être lancés avec bazel test //...
  • Certains tests nécessitent l’installation d’outils sous-jacents comme Mercurial ou Quilt
    • Si une Pull Request ne concerne pas ces modules, ces tests peuvent être ignorés
    • La CI exécute tous les tests
  • Sous Arch Linux, le paquet aur/copybara-git est disponible

Utiliser Copybara précompilé avec Bazel

  • Les snapshot releases hebdomadaires peuvent être utilisées avec Bazel
  • Copybara est fourni avec la class file version 65.0 ; il doit donc être exécuté avec Java Runtime 21 ou plus récent
    • Il faut ajouter run --java_runtime_version=remotejdk_21 à .bazelrc
  • L’artefact de release est téléchargé avec http_jar
    • Dans WORKSPACE, utiliser load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_jar")
    • Dans MODULE.bazel, utiliser http_jar = use_repo_rule("@bazel_tools//tools/build_defs/repo:http.bzl", "http_jar")
  • Dans WORKSPACE ou MODULE.bazel, renseigner l’emplacement [version] pour désigner copybara_deploy.jar
  • Dans le fichier BUILD, déclarer un java_binary utilisant com.google.copybara.Main comme main class
  • Un exemple d’exécution est bazel run //tools:copybara -- migrate copy.bara.sky

Builder les sources comme dépôt Bazel externe

  • Des macros pratiques sont fournies pour les dépendances de Copybara
  • Ajouter http_archive à WORKSPACE et renseigner les valeurs {{ sha256sum }} et {{ commit }}
  • Ensuite, charger et appeler les macros suivantes :
    • copybara_repositories()
    • copybara_maven_repositories()
    • copybara_go_repositories()
  • Dans le workspace, il est possible de builder et d’exécuter avec bazel run @com_github_google_copybara//java/com/google/copybara -- <args...>

Utilisation avec Docker

  • Le build et l’exécution de Copybara avec Docker sont actuellement expérimentaux
  • Le build s’effectue avec docker build --rm -t copybara .
  • L’exécution se fait depuis la racine du code cible sous la forme docker run -it -v "$(pwd)":/usr/src/app copybara help
  • Des variables d’environnement peuvent être utilisées à la place des arguments d’exécution du conteneur
    • COPYBARA_SUBCOMMAND=migrate : change la commande exécutée ; valeur par défaut : migrate
    • COPYBARA_CONFIG=copy.bara.sky : indique le chemin du fichier de configuration ; valeur par défaut : copy.bara.sky à la racine
    • COPYBARA_WORKFLOW=default : indique le workflow à exécuter ; valeur par défaut : default
    • COPYBARA_SOURCEREF='' : indique la sourceref ; aucune valeur par défaut
    • COPYBARA_OPTIONS='' : indique les options Copybara ; aucune valeur par défaut
  • La configuration Git et les identifiants SSH peuvent être partagés avec le conteneur Docker
    • L’exemple consiste à monter ~/.gitconfig, ~/.ssh et SSH_AUTH_SOCK dans le conteneur

Documentation et contact

  • La documentation est encore en cours de rédaction
  • Les ressources fournies sont les suivantes :
  • Les questions peuvent être posées sur la mailing list
  • Pour voir les erreurs des tests Bazel sans faire de cat sur le fichier de logs, il est possible d’ajouter test --test_output=streamed à ~/.bazelrc

1 commentaires

 
GN⁺ 4 시간 전
Avis de Hacker News
  • C’était amusant de voir cet article paraître juste après que j’ai publié en open source un patch de prise en charge de Perforce que j’avais créé pour l’utiliser dans un studio de développement de jeux.
    Quand on sait que le principal usage de Copybara est le déploiement de code interne de Google, et que ce code se trouve dans Piper, qui a un lien avec Perforce, j’ai trouvé assez surprenant qu’il n’y ait pas de prise en charge de Perforce et seulement une prise en charge réellement significative de Git.
    Avant de créer la PR, en regardant l’historique Git, j’ai vu beaucoup de marqueurs Gerrit Change-ID, donc je me suis aussi demandé s’il existait quelque part un système de revue de code Gerrit auquel je n’ai pas accès, et si ma PR ne serait pas intégrée upstream.
    C’est aussi dommage qu’il n’y ait pas de Gerrit/Rietveld pour Perforce, mais on ne peut pas tout avoir.
    https://github.com/google/copybara/pull/347

    • L’une des raisons pour lesquelles Gerrit/Rietveld n’a pas de prise en charge de Perforce, c’est que Google n’utilise pas ces outils pour les modifications de code stockées dans Piper. À la place, ils utilisent Critique.
      https://abseil.io/resources/swe-book/html/ch19.html
      https://read.engineerscodex.com/p/how-google-takes-the-pain-...
      Parmi les outils externes, je n’ai encore rien trouvé d’aussi bon que Critique, et je suis surpris que les maigres outils de revue de PR de GitHub soient acceptés par la plupart des gens. Si quelqu’un connaît un outil d’un niveau comparable, je serais curieux d’en entendre parler.
      Quand j’ai quitté Google il y a quelques années, j’avais cherché assez minutieusement, et https://codeapprove.com/ était ce qui s’en rapprochait le plus, mais il lui manquait encore beaucoup de choses.
    • Piper n’est pas un fork de Perforce. Il est compatible avec l’API de Perforce, mais c’est une implémentation complètement différente.
    • Ce dépôt accepte les PR. Simplement, elles sont fusionnées en interne puis réexportées vers l’extérieur.
      Les projets open source comme gVisor ou Bazel, qui vivent dans le monorepo interne, fonctionnent globalement de manière similaire, même s’il y a quelques différences.
  • Parmi les autres outils intéressants dans ce domaine, Rust utilise un outil appelé Josh pour la synchronisation des commits.
    https://josh-project.dev
    Il y a aussi un billet de blog côté Rust.
    https://blog.rust-lang.org/inside-rust/2026/06/04/how-josh-h...
    Meta avait autrefois un outil open source appelé fbshipit, mais d’après le dépôt public il n’est plus utilisé.
    https://github.com/facebookarchive/fbshipit
    Existe-t-il d’autres outils dans ce domaine ?

  • Est-ce aussi pratique quand plusieurs dépôts veulent partager un peu de code, mais que ça ne vaut pas la peine d’en faire une bibliothèque séparée, d’ajouter une référence, de publier des versions et de mettre à jour les dépôts dépendants ?
    Par exemple, je me demande si on peut l’utiliser pour simplement synchroniser un dossier contenant un modèle de domaine commun depuis un dépôt principal vers d’autres dépôts.
    C’est un usage proche de la philosophie à la Go : « mieux vaut copier un peu que d’empiler les dépendances ».

    • Il sert surtout à synchroniser des projets open source externes avec le monorepo interne. La politique demande d’importer le code source plutôt que les artefacts de build, même s’il est possible d’obtenir des exceptions.
      Certains projets sont développés dans le monorepo puis exportés vers l’extérieur avec Copybara.
      Notre équipe l’utilise aussi en interne pour gérer les versions d’un ensemble de règles Starlark.
    • C’est un outil qu’on utilise quand on a un monorepo interne et qu’on veut publier une partie de son contenu en open source. Mais le code doit quand même rester dans le monorepo, donc c’est la solution.
      Avoir un dépôt public comme dépendance d’un dépôt privé interne devient assez pénible côté développement. Quand ce genre de dépendances se met à pousser en arbre, c’est vraiment un casse-tête.
    • On peut faire ce genre de chose avec Copybara, mais si on l’utilise ainsi, ça risque d’être pénible et fastidieux. Ça peut être encore plus agaçant que de séparer une bibliothèque ou de pousser quelques fichiers dans un dépôt à part.
  • Je l’utilise depuis assez longtemps, surtout quand un outil créé au sein d’un gros projet a suffisamment pris d’ampleur pour mériter une publication indépendante.
    C’est assez puissant pour gérer toute la distribution bidirectionnelle, exporter le code puis le réimporter, mais c’est tellement pénible que je m’en passe.
    Je m’en sers généralement pour un simple export ponctuel : détacher un dossier du dépôt d’origine tout en conservant l’historique. Ensuite, le développement passe dans le nouveau dépôt.
    Même si la nouvelle structure du projet est complètement différente, Git blame fonctionne, donc ça me convient.

    • Ce schéma unidirectionnel est en fait aussi celui utilisé en interne chez Google. Ils synchronisent vers l’extérieur, du monorepo vers GitHub.
      Le bidirectionnel devient vite sale, parce que des transformations comme le remappage de chemins, l’exclusion de fichiers ou la suppression d’en-têtes sont faciles dans un sens, mais ne peuvent pas toujours être inversées proprement.
      Quand les deux côtés divergent, le suivi de la ligne de base de Copybara commence à produire des résultats confus. Même des commits sémantiquement identiques produisent des SHA différents après transformation.
      À savoir : la « conservation » de l’historique n’est pas une vraie transplantation, mais consiste à cherry-picker des commits réécrits. Le contenu des fichiers et les informations d’auteur sont transférés, donc Git blame fonctionne, mais les SHA sont nouveaux.
      Copybara place le SHA d’origine dans le trailer de message de commit GitOrigin-RevId, ce qui est pratique si l’on doit plus tard faire correspondre des commits entre dépôts.
  • Plus de 52 ans de progrès, donc :-)
    Juillet 2026 : Google copybara permet de déplacer du code entre deux dépôts de production.
    Mars 1974 : IBM COPY permettait de déplacer du code entre deux jeux de données partitionnés de production. OS/MVT et OS/VS2 TSO Data Utilities COPY, FORMAT, LIST, MERGE User's Guide and Reference https://www.computinghistory.org.uk/downloads/8987

  • Chez Dagster, nous avons utilisé Copybara pour mettre en place un modèle hub-and-spoke permettant au dépôt public de vivre à l’intérieur d’un monorepo interne plus vaste ; ça a fonctionné, mais il a fallu pas mal de contournements.
    https://dagster.io/blog/monorepos-the-hub-and-spoke-model-an...

  • Si l’on a seulement besoin de synchroniser des dépôts, sans exclusions ni transformations, je ne pense pas que je l’utiliserais. Ça peut convenir aujourd’hui, mais si l’outil est archivé ou abandonné, comme kaniko ou beaucoup de produits/outils Google, ça peut devenir problématique.
    GitLab offre une méthode très simple pour faire du miroir depuis GitLab vers GitHub ou d’autres fournisseurs/serveurs Git.

    • Je pense que la probabilité que Copybara soit arrêté est vraiment faible. À ma connaissance, c’est un outil central dans la façon dont google3 maintient et vendorise de grands projets open source.
    • Oui, Copybara est plutôt un outil destiné à effectuer des transformations dans un sens ou dans les deux.
      Par exemple, convertir des fichiers bzl externes vers un format compatible avec les BUILD Blaze internes, ou passer d’imports externes à des imports internes de type third_party, et inversement.
      Pour un pur miroir, Copybara est beaucoup trop lourd.
  • Bien. Il y a environ 5 ans, j’avais moi aussi bricolé quelque chose de similaire avec des dépôts Git imbriqués et des scripts, afin de gérer à la fois des dépôts privés et publics.
    Mes scripts shell n’étaient évidemment pas à l’échelle de Google.

    • Pareil pour moi. Au début, je pensais que ce serait un wrapper autour de git subtree, mais à y regarder, ça semble faire beaucoup plus de choses.
      Par exemple, il y a aussi une fonction pour changer l’adresse e-mail de l’auteur du commit pendant la synchronisation.