Github a une fonction appelée Dependabot Saviez-vous qu'il y en a? S'il existe une ancienne dépendance (bibliothèque) utilisée dans le référentiel, c'est une fonction qui émet automatiquement une demande d'extraction mise à jour. Beaucoup d'entre vous ont peut-être vu le PR suivant dans des référentiels publics.
À l'origine un service indépendant, il a été acquis par Github et incorporé en tant que fonctionnalité native, ce qui facilite son déploiement.
Vous pouvez activer la création automatique de la mise à jour de la bibliothèque PR en plaçant simplement le fichier de configuration sous .github / dependabot.yml
.
Je vais omettre l'explication de Dependabot lui-même cette fois, mais dans le projet dans lequel je suis impliqué, j'ai commencé l'opération afin que le fichier de configuration suivant soit vérifié à 9 heures lundi.
version: 2
updates:
- package-ecosystem: "gradle"
directory: "/"
target-branch: "develop"
schedule:
interval: "weekly"
day: "monday"
time: "09:00"
timezone: "Asia/Tokyo"
reviewers:
- "ignis-ltd/with-android"
Tout d'abord, si vous souhaitez en savoir plus sur Github Dependabot, les documents et articles officiels suivants vous seront utiles.
Dependabot recevra un PR pour chaque mise à jour de bibliothèque. Étant donné que certaines mises à jour de la bibliothèque peuvent causer des problèmes, je pense que c'est la bonne forme à individualiser pour isoler le problème, mais s'il y a plusieurs mises à jour, certains problèmes subsisteront. ..
Je pense que des problèmes similaires peuvent survenir côté serveur, mais comme il s'agit d'une application Android dans mon projet, si 5 PR sont émis à la fois comme décrit ci-dessus, consultez la branche 5 fois, construisez-la et installez-la. J'ai dû vérifier l'opération.
Bien sûr, vous pouvez réduire le risque en construisant un test sur CI et en l'automatisant, mais dans le cas d'une application, vous êtes toujours inquiet de l'effondrement de l'interface utilisateur, alors j'aimerais vérifier visuellement l'opération une fois avant la fusion. .. Ou si vous déployez chaque branche avec CI, vous n'avez pas à vérifier, mais c'est toujours un peu difficile de simplement télécharger, installer et démarrer 5 fois.
En tant qu'approche à laquelle j'ai pensé, j'ai envisagé une méthode de ** fusion des branches de chaque PR émis par Dependabot en une seule branche, en construisant à partir de CI, et en laissant un lien vers le binaire comme commentaire pour chaque PR **. .. Je vais vous présenter la méthode actuelle ci-dessous.
Tout d'abord, construisons un script Ruby qui extrait et intègre toutes les branches Git mises à jour.
dependabot /
**(Le pouvoir rubis est en bas, alors ne le manquez pas: priez :)
Gemfile
source 'https://rubygems.org'
gem 'git'
merge_dependabot_branchs.rb
require "git"
dependabotBranchs = []
git_client = Git.open(Dir.pwd)
git_client.fetch
git_client.branches.each do |branch|
if branch.name.start_with?('dependabot/')
dependabotBranchs.append(branch)
end
end
return if dependabotBranchs.size <= 0
dependabotBranchs.each do |dependabotBranch|
system("git format-patch -1 #{dependabotBranch.gcommit} --unified=0")
end
system("git apply 0001-*.patch --unidiff-zero")
La clé ici est de savoir comment créer et appliquer un fichier de correctif.
Je génère un fichier de patch avec git format-patch
, mais ** généralement les changements dans les 3 lignes avant et après sont également inclus dans Diff **.
En d'autres termes, s'il y a déjà des changements dans les 3 lignes avant et après, comme lorsque les lignes de la bibliothèque mise à jour sont côte à côte, cela sera jugé comme un conflit et ne sera pas automatiquement intégré.
Les conflits ne devraient pas se produire si seules les modifications de la mise à niveau de version par Dependabot sont extraites, donc même s'il y a des modifications dans la ligne proche, nous aimerions que vous les intégriez sans les considérer comme des conflits.
Par conséquent, en ajoutant le paramètre --unified = 0
, les lignes précédente et suivante sont ajustées pour ne pas être incluses dans le Diff. ([Référence](https://git-scm.com/docs/git-format-patch#Documentation/git-format-patch.txt --- unifiedltngt))
De plus, j'ai utilisé une astuce lors de l'application d'un fichier de correctif avec git apply
, et ** normalement l'appliquer avec un fichier de correctif qui n'inclut pas les lignes précédentes et suivantes (avec --unified = 0
spécifié). Echouera **, donc le paramètre --unidiff-zero
est ajouté afin que les lignes précédentes et suivantes soient ignorées et appliquées. (Référence)
Le traitement dans ce domaine était insuffisant avec ruby-git que j'utilisais au début, donc je me fie à l'appel système.
À ce stade, vous devriez avoir une branche avec des mises à jour de bibliothèque intégrées, donc si vous construisez dans cet état, vous pouvez générer un binaire intégré.
En supposant qu'un binaire est généré sur CI et qu'une URL de lien est également émise, construisons un script Ruby qui laisse un commentaire sur le PR généré par le Dependabot original. Cette fois, utilisez l 'API Github au lieu de Git pour extraire.
dependabot /
dans la requête d'extraction actuellement ouverte **(Code inférieur de puissance Ruby)
comment_dependabot_prs.ruby
require 'net/http'
require 'uri'
require 'json'
uri = URI.parse("https://api.github.com/repos/ignis-ltd/with_android/pulls")
request = Net::HTTP::Get.new(uri)
request["Accept"] = "application/vnd.github.v3+json"
request["Authorization"] = "token #{ENV['GITHUB_API_TOKEN']}"
req_options = {
use_ssl: uri.scheme == "https",
}
response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
http.request(request)
end
dependabotPullRequests = []
responseBodyJson = JSON.parse(response.body, symbolize_names: true)
responseBodyJson.each do |pull|
if pull[:head][:ref].start_with?('dependabot/')
dependabotPullRequests.append(pull)
end
end
dependabotPullRequests.each do |pull|
uri = URI.parse("https://api.github.com/repos/ignis-ltd/with_android/issues/#{pull[:number]}/comments")
request = Net::HTTP::Post.new(uri)
request.body = JSON.dump({
"body" => "Deployed a binary that merged the following branches\n" + dependabotPullRequests.map { |pull| pull[:html_url] }.join(" ") + "\n\n#{ENV['INSTALL_PAGE_URL']}"
})
request["Accept"] = "application/vnd.github.v3+json"
request["Authorization"] = "token #{ENV['GITHUB_API_TOKEN']}"
req_options = {
use_ssl: uri.scheme == "https",
}
response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
http.request(request)
end
end
Fondamentalement, il est simplement implémenté directement à l'aide de l 'API Github.
Les variables d'environnement suivantes sont requises pour exécuter le script Ruby ci-dessus. Veuillez modifier l'URL de l'API Github le cas échéant N'incluez pas directement les informations de jeton Github, mais utilisez des variables d'environnement secrètes CI.
Si vous pouvez atteindre ce stade, vous pouvez laisser les commentaires suivants dans la demande d'extraction émise par Dependabot. Vous pourrez vous référer à la branche que vous avez intégrée et au binaire intégré à partir de toute Pull Request.
Dans mon projet, Dependabot s'exécute à 9h00 le lundi, j'ai donc ajusté le CI contenant ce script pour qu'il s'exécute à 10h00 le lundi. Voici un exemple de configuration dans Bitrise. Veuillez ajuster cette zone à votre convenance.
Le script qui intègre la première branche Dependabot est basé sur les informations de la branche de Git, mais le script pour les commentaires ultérieurs recherche basé sur PullRequest, donc (je ne pense pas que ce soit fondamentalement) PullRequest S'il existe une branche Dependabot non publiée, ou si vous apportez des modifications à la branche ou au PR pendant la construction, le contenu du commentaire et l'état réel du binaire seront différents.
De plus, comme le nom de la branche est recherché pour une correspondance de préfixe avec la chaîne de caractères dependabot /
, il ne fonctionnera pas correctement lorsque la branche correspondante est créée manuellement, il peut donc être nécessaire de fournir une logique de jugement légèrement plus stricte. (Une sensation d'usure horizontale)
C'était tout à fait une compétence, mais je pense que cela entraînera une réduction des coûts car vous pouvez vérifier l'opération une fois par semaine. Je ne pense pas qu'il y ait autant de bibliothèques dans un petit programme, donc vous ne ressentirez peut-être pas le besoin de le faire, mais si l'échelle dépasse 100 000 lignes, le nombre de bibliothèques installées sera énorme et le coût du contrôle de fonctionnement sera élevé. Ne peut pas être ridicule, donc en prenant de telles mesures, il est devenu possible de tirer le meilleur parti de Dependabot.
Aussi, cette fois, nous parlons d'intégrer Dependabot sur CI, mais comme on peut difficilement parler du côté CI uniquement de la partie de l'écriture d'un script et de son intégration avec l'esprit, je voudrais parler quelque part. ..
Recommended Posts