[RUBY] Eine Geschichte, die es so einfach wie möglich machte, den Vorgang beim automatischen Erstellen eines PR für Bibliotheksaktualisierungen mit Github Dependabot zu überprüfen

Was ist Dependabot überhaupt?

Github hat eine Funktion namens Dependabot Wussten Sie, dass es gibt? Wenn im Repository eine alte Abhängigkeit (Bibliothek) verwendet wird, gibt diese Funktion automatisch eine aktualisierte Pull-Anforderung aus. Viele von Ihnen haben möglicherweise die folgende PR in öffentlichen Repositories gesehen.

スクリーンショット 2020-09-09 20.12.31.png

Ursprünglich ein unabhängiger Dienst, wurde er von Github übernommen und als native Funktion integriert, um die Bereitstellung zu vereinfachen. Sie können die automatische PR-Erstellung für Bibliotheksaktualisierungen aktivieren, indem Sie die Einstellungsdatei unter ".github / Dependabot.yml" platzieren.

Ich werde diesmal die Erklärung von Dependabot selbst weglassen, aber in dem Projekt, an dem ich beteiligt bin, habe ich den Betrieb aufgenommen, sodass die folgende Einstellungsdatei am Montag um 9 Uhr überprüft wird.

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"

Wenn Sie mehr über Github Dependabot erfahren möchten, sind zunächst die folgenden offiziellen Dokumente und Artikel hilfreich.

Betriebsprobleme von Dependabot

Dependabot erhält für jedes Bibliotheksupdate eine PR. Da einige Bibliotheksaktualisierungen Probleme verursachen können, denke ich, dass es das richtige Formular ist, um das Problem einzugrenzen. Wenn jedoch mehrere Aktualisierungen vorhanden sind, bleiben einige Probleme bestehen. ..

スクリーンショット 2020-09-09 20.12.13.png

Ich denke, ähnliche Probleme können auf der Serverseite auftreten. Da es sich jedoch um eine Android-Anwendung in meinem Projekt handelt, sollten Sie, wenn 5 PRs wie oben beschrieben gleichzeitig ausgegeben werden, den Zweig fünfmal überprüfen, erstellen und installieren. Ich musste die Operation überprüfen.

Natürlich können Sie das Risiko reduzieren, indem Sie einen Test für CI erstellen und automatisieren. Bei einer Anwendung sind Sie jedoch weiterhin besorgt über den Zusammenbruch der Benutzeroberfläche. Daher möchte ich den Vorgang vor dem Zusammenführen einmal visuell überprüfen. .. Wenn Sie jeden Zweig mit CI bereitstellen, müssen Sie nicht auschecken, aber es ist immer noch ein wenig schwierig, ihn nur fünfmal herunterzuladen, zu installieren und zu starten.

Lösung

Als einen Ansatz, über den ich nachdachte, dachte ich über eine Methode nach, ** die Zweige jedes von Dependabot ausgegebenen PR in einem Zweig zusammenzuführen, aus CI aufzubauen und einen Link zur Binärdatei als Kommentar für jeden PR ** zu hinterlassen. .. Ich werde die eigentliche Methode unten vorstellen.

Konsolidieren Sie die von Dependabot veröffentlichten Niederlassungen

Lassen Sie uns zunächst ein Ruby-Skript erstellen, das alle aktualisierten Git-Zweige extrahiert und integriert.

  1. ** Holen Sie sich eine Liste der Zweige, beginnend mit der Zeichenfolge abhängiger / **
  2. ** Erstellen Sie eine Patch-Datei für das Update-Commit aus dem aktuellen Zweig (Entwickeln) **
  3. ** Wenden Sie alle in 2. erhaltenen Patch-Dateien an. **

(Ruby Power ist ganz unten, also verpassen Sie es nicht: beten Sie :)

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")

Ein kleiner Kommentar

Der Schlüssel hier ist, wie man eine Patch-Datei erstellt und anwendet. Ich generiere eine Patch-Datei mit git format-patch, aber ** normalerweise sind die Änderungen in den 3 Zeilen davor und danach auch in Diff ** enthalten. Mit anderen Worten, wenn es bereits Änderungen innerhalb von 3 Zeilen davor und danach gibt, z. B. wenn die Zeilen der aktualisierten Bibliothek nebeneinander liegen, wird dies als Konflikt gewertet und nicht automatisch integriert. Konflikte sollten nicht auftreten, wenn nur die Änderungen des Versions-Upgrades von Dependabot extrahiert werden. Selbst wenn sich Änderungen in der nahen Zeile befinden, möchten wir, dass Sie sie integrieren, ohne sie als Konflikte zu betrachten. Durch Hinzufügen des Parameters "--unified = 0" werden daher die vorherige und die nächste Zeile so angepasst, dass sie nicht im Diff enthalten sind. ([Referenz](https://git-scm.com/docs/git-format-patch#Documentation/git-format-patch.txt --- unifiedltngt))

Außerdem habe ich beim Anwenden einer Patch-Datei mit "git apply" einen Trick angewendet und ** normalerweise mit einer Patch-Datei, die die umgebenden Zeilen nicht enthält (mit "--unified = 0" angegeben). Wird fehlschlagen **, wird der Parameter "--unidiff-zero" hinzugefügt, sodass die vorhergehenden und folgenden Zeilen ignoriert und angewendet werden. (Referenz)

Die Verarbeitung in diesem Bereich war mit ruby-git, das ich zu Beginn verwendet habe, unzureichend, daher verlasse ich mich auf den Systemaufruf.

Zu diesem Zeitpunkt sollten Sie einen Zweig mit integrierten Bibliotheksaktualisierungen haben. Wenn Sie also in diesem Status erstellen, können Sie eine integrierte Binärdatei generieren.

Fügen Sie einen Link zu der Binärdatei ein, die in die von Dependabot herausgegebene PR integriert ist

Angenommen, auf CI wird eine Binärdatei generiert und auch eine Link-URL ausgegeben. Erstellen wir ein Ruby-Skript, das einen Kommentar zu der vom ursprünglichen Dependabot generierten PR hinterlässt. Verwenden Sie dieses Mal die Github-API anstelle von Git zum Extrahieren.

  1. ** Extrahieren Sie Zweige beginnend mit der Zeichenfolge "Dependabot /" in der aktuell geöffneten Pull-Anfrage **
  2. ** Fügen Sie die Pull-Anforderungsliste, die in den Link zur Binärdatei integriert ist, als Kommentar für die extrahierte Pull-Anforderung ein **

(Ruby Power Bottom Code)

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

Ein kleiner Kommentar

Grundsätzlich wird es einfach über die Github-API implementiert.

Die folgenden Umgebungsvariablen sind erforderlich, um das obige Ruby-Skript auszuführen. Bitte ändern Sie die URL für die Github-API entsprechend Schließen Sie Github-Token-Informationen nicht direkt ein, sondern verwenden Sie geheime CI-Umgebungsvariablen.

Wenn Sie bis zu diesem Punkt aufbauen können, können Sie die folgenden Kommentare in der von Dependabot ausgegebenen Pull-Anfrage hinterlassen. Sie können aus jeder Pull-Anfrage auf den von Ihnen integrierten Zweig und die integrierte Binärdatei verweisen.

スクリーンショット 2020-09-09 20.12.44.png

Führen Sie nach dem Ausführen von Dependabot Skripte und Builds rechtzeitig in CI aus

In meinem Projekt wird Dependabot am Montag um 9:00 Uhr ausgeführt, daher habe ich das CI mit diesem Skript so angepasst, dass es am Montag um 10:00 Uhr ausgeführt wird. Das Folgende ist ein Einstellungsbeispiel in Bitrise. Bitte passen Sie diesen Bereich nach Ihren Wünschen an.

スクリーンショット 2020-09-10 2.43.58.png

Ergänzung oder Vorsicht

Das Skript, das den ersten Dependabot-Zweig integriert, basiert auf den Zweiginformationen von Git, aber das Skript für spätere Kommentare sucht basierend auf PullRequest, also (ich glaube nicht, dass es im Grunde genommen so ist) PullRequest Wenn es einen unveröffentlichten Dependabot-Zweig gibt oder wenn Sie während des Builds Änderungen am Zweig oder PR vornehmen, unterscheiden sich der Inhalt des Kommentars und der tatsächliche Status der Binärdatei.

Da der Zweigname nach dem Präfix mit der Zeichenfolge "Dependabot /" gesucht wird, kommt es auch zu Fehlfunktionen, wenn der entsprechende Zweig manuell erstellt wird. Daher kann es erforderlich sein, eine etwas strengere Beurteilungslogik bereitzustellen. (Ein Gefühl horizontaler Abnutzung)

Ende

Es war eine ziemliche Fähigkeit, aber ich denke, dass dies zu einer Kostenreduzierung führen wird, da Sie den Betrieb einmal pro Woche überprüfen können. Ich glaube nicht, dass ein kleines Programm so viele Bibliotheken enthält, sodass Sie dies möglicherweise nicht für erforderlich halten. Wenn der Maßstab jedoch 100.000 Zeilen überschreitet, ist die Anzahl der installierten Bibliotheken enorm und die Kosten für die Funktionsprüfung Kann nicht lächerlich sein, daher ist es durch solche Maßnahmen möglich geworden, Dependabot optimal zu nutzen.

Auch dieses Mal sprechen wir über die Integration von Dependabot in CI, aber da wir kaum über die CI-Seite sprechen können, nur über den Teil des Schreibens eines Skripts und dessen Integration mit Spirit, möchte ich irgendwo darüber sprechen. ..

Recommended Posts

Eine Geschichte, die es so einfach wie möglich machte, den Vorgang beim automatischen Erstellen eines PR für Bibliotheksaktualisierungen mit Github Dependabot zu überprüfen
Ich habe eine GitHub-Aktion erstellt, die es einfach macht, das Ausführungsergebnis von RSpec zu verstehen
Die Geschichte, ein Projekt zu bauen, das Maven mit Ant gebaut hat
Eine Geschichte, die es Kotlin bequem machte, dass es mühsam ist, Animationen kontinuierlich auf Android auszuführen
Erstellt eine Bibliothek, die die Handhabung von freigegebenen Android-Einstellungen erleichtert
Beim Importieren von CSV mit Rails war es wirklich einfach, den Befehl nkf zu verwenden
Die Geschichte, Sprint-Boot mit Kubernetes (GKE) auszuführen und keine Verbindung zu CloudSQL herzustellen
Eine Geschichte, nach der ich süchtig war, als ich einen Schlüssel bekam, der automatisch auf MyBatis ausprobiert wurde
Java: Eine Geschichte, in der ich mich unwohl fühlte, als mir beigebracht wurde, Strings ohne Grund mit Gleichen zu vergleichen.