Contact salesFree trial
Blog

Erstellen Sie Ihre erste GitHub-Aktion: Schritt-für-Schritt-Anleitung

GitHubCI/CDDevOpsAutomatisierungPräsentationSymfonyCon
Teilen Sie

Video-Transkript

Wir haben ChatGPT verwendet, um die Grammatik und Syntax des Transkripts zu verbessern.

In Ordnung, herzlich willkommen. Mein Name ist Paul und ich arbeite bei Platform.sh, und wir sind stolz darauf, Gastgeber der SymfonyCon zu sein. Ich bin heute hier, um über GitHub-Aktionen zu sprechen . In meinen Präsentationen gebe ich gerne eine Reihe von Warnungen ab. Für diejenigen unter Ihnen, die zuhören, habe ich eine Animation eines roten Lichts, das blinkt, um Ihnen eine Vorwarnung zu geben, und in diesem Fall werde ich meine Präsentation mit einigen Warnungen beginnen.

Die erste ist, dass ich keineswegs ein Experte für GitHub-Aktionen bin. In den letzten 18 Monaten war ich jedoch für den Aufbau und die Pflege einer großen Sammlung von benutzerdefinierten Aktionen und Workflows verantwortlich, um einen Großteil der Aufgaben meines Teams zu automatisieren. In dieser Zeit bin ich auf viele frustrierende und verwirrende Bereiche der Plattform gestoßen, und das war der Grund für diese Präsentation. Mein Ziel bzw. meine Hoffnung ist es, Ihnen dabei zu helfen, sich in diesen verwirrenden Bereichen zurechtzufinden und Ihnen den Weg zur Automatisierung innerhalb von GitHub zu ebnen.

Die nächste Warnung, die ich Ihnen gebe, ist, dass ich erwarte, dass Sie mit mir interagieren. Ich werde während des Vortrags viele Fragen stellen, und ich möchte, dass Sie mir antworten. Die letzte Warnung ist, dass ich sehr schnell sprechen werde, da dies eigentlich ein dreistündiger Workshop ist, den ich versuche, auf 35 Minuten zu verkürzen.

Was ich also in diesen kurzen 35 Minuten abdecken möchte, ist Folgendes: Ich möchte über die Aktionsplattform sprechen und darüber, was sie ist. Dann möchte ich die verschiedenen Komponenten und Teile von GitHub Actions vorstellen, die Sie für die Erstellung Ihrer Automatisierung verwenden werden. Ich werde dann über eines dieser Teile, den Workflow, sprechen, und wir werden uns den Workflow genauer ansehen und über die Teile des Workflows sprechen, die erforderlich sind und die Sie nutzen werden. Dann werden wir gemeinsam unseren ersten Workflow erstellen - das ist ein Hinweis darauf, dass Sie hier mit mir interagieren müssen. Als Nächstes befassen wir uns mit Aktionen und der Erstellung von benutzerdefinierten Aktionen, wobei wir über die Bestandteile einer benutzerdefinierten Aktion und die Dinge sprechen, die Sie für die Erstellung einer benutzerdefinierten Aktion benötigen.

Ich muss nach rechts gehen - Entschuldigung, gehen Sie weiter nach rechts, ich muss ganz nach rechts gehen. Okay, ist das besser? In Ordnung, tut mir leid, ich laufe gerne, deshalb wusste ich nicht, dass ich hier drüben bleiben muss. Auf dem Weg dorthin - oh, Entschuldigung - werden wir dann gemeinsam unsere erste benutzerdefinierte Aktion erstellen und sehen, wie sie eingesetzt wird. Im weiteren Verlauf werde ich Ihnen weitere Warnungen, einige Vorbehalte und Probleme geben - Dinge, auf die Sie achten sollten. Zum Schluss werde ich Ihnen zeigen, wie all diese Dinge zusammenkommen, um eine echte, lebensnahe Automatisierung zu entwickeln.

Zunächst einmal: Was ist GitHub Actions? Nun, GitHub Actions ist ein Service von GitHub. Es handelt sich um eine Plattform für kontinuierliche Integration und kontinuierliche Bereitstellung, mit der Sie Dinge rund um Ihre Codebasis automatisieren können, sei es das Erstellen oder Bereitstellen oder Testen. Es gibt Ihnen die Möglichkeit, zu automatisieren, und das muss nicht nur codebezogen sein. Es könnte auch das Projektmanagement sein. Also alles, was Sie tun müssen, wenn etwas mit Ihrer Codebasis passiert, können wir mit dieser Plattform automatisieren.

Was sind also die Teile, die Sie verwenden werden? Nun, Sie werden mit Dingen arbeiten, die Workflows genannt werden. Wir haben Ereignisse, Läufer, Jobs, Schritte und GitHub-Aktionen (aber mit kleinem "a"). Wenn Sie gerade zuhören, sagt ein Herr: "Moment, was?" Ja, also GitHub Actions mit einem großen "A" bezieht sich auf die Plattform - die gesamte Automatisierungsplattform. Wenn Sie GitHub-Aktionen mit einem kleinen "a" sehen, bezieht sich das auf ein einzelnes modulares, in sich geschlossenes Stück Automatisierung, das Sie in Ihrer Automatisierung verwenden können. Manchmal werden sie auch als benutzerdefinierte Aktionen bezeichnet - siehe dort - und manchmal einfach als Aktionen. Aber seien Sie sich bewusst, dass dies vorkommt. Die gesamte Plattform - es ist bedauerlich, wie GitHub sich entschieden hat, bestimmte Dinge zu benennen - verwendet oft ein Wort, und je nachdem, wo das Wort verwendet wird, hat es eine andere Bedeutung. Wenn Englisch nicht Ihre erste Sprache ist, ist das besonders schwierig. Ein Beispiel ist "Status" versus "Checks" versus "Status Checks", und das sind drei verschiedene Dinge, die nicht unbedingt miteinander zusammenhängen.

Wenn Sie sich also in einer Situation befinden, in der das, was Sie sehen - muss ich noch einmal rübergehen? Es tut mir leid - wenn das, was Sie sehen, nicht mit dem übereinstimmt, was Sie in den Unterlagen lesen, sind Sie vielleicht in eine dieser ähnlichen Situationen geraten. Gut, wir haben also Workflows, Läufer, Jobs, Schritte und Aktionen. Wie passen all diese Teile zusammen? Nun, wir konfigurieren unsere Automatisierung in einer Workflow-Datei - dort definieren wir die gesamte Automatisierung, die wir durchführen wollen. Diese Workflows, diese Automatisierungsteile, werden durch ein Ereignis ausgelöst - etwas, das mit unserer Codebasis geschieht -, das dann eine Reihe von Aufträgen in Gang setzt. In Jobs definieren wir eine Reihe von Schritten, und diese Schritte führen unsere Geschäftslogik aus, sei es, dass sie andere Shell-Befehle oder Shell-Skripte aufrufen, oder dass sie eine der Aktionen aufrufen, die ich bereits erwähnt habe.

Ich möchte nun auf jede dieser Komponenten eingehen und sie definieren und ein wenig näher erläutern. Also, der Workflow - icherwähnte, dass der Workflow selbst die Automatisierung ist. Wir konfigurieren ihn in einer so genannten Workflow-Datei. Eine Workflow-Datei muss eine YAML-Dateisein - ihrName spielt keine Rolle, sie muss einfach nur eine YAML-Datei sein -, aber sie muss in einem Verzeichnis .github/workflows im Stammverzeichnis Ihres Repositorys enthalten sein. Ihr Repository selbst kann nun mehrere Workflows enthalten. Sie können einen Workflow für dasselbe Ereignis auslösen, Sie können eine Menge Workflows für dasselbe Ereignis auslösen, sie können jeweils für verschiedene Ereignisse ausgelöst werden, ein Workflow kann durch mehrere Ereignisse ausgelöst werden, was auch immer Ihre spezielle Situation ist - es muss nur YAML sein und in diesem Verzeichnis liegen.

Ein Ereignis ist dann eine Aktivität, die in Ihrer Codebasis auftritt, sei es ein Push, ein Pull Request, es könnte jemand sein, der etwas kennzeichnet - was auch immer, es ist einfach etwas, das auftritt. Sie haben einen ganzen Haufen - ich werde ganz schnell umblättern - Sie haben einen ganzen Haufen von Ereignissen, und die habe ich hier. Sie sehen hier auf der rechten Seite eine ganze Reihe von Ereignissen, mit denen Sie genau steuern können, wann diese Workflows ausgelöst werden sollen. Ich möchte erwähnen, dass in der Dokumentation gelegentlich nicht mehr das Wort "Ereignis", sondern "Workflow-Trigger" verwendet wird. Wenn Sie also einen Workflow-Auslöser sehen, ist das genau das Gleiche wie ein Ereignis.

Ein Runner ist einfach eine virtuelle Serverinstanz, auf der Ihre Automatisierung ausgeführt wird, wenn dieser Workflow ausgelöst wird. Sie können entweder die öffentlichen Runner nutzen, die GitHub bereitstellt, oder, wenn Sie einen ganz speziellen Anwendungsfall haben, können Sie auch Ihren eigenen, selbst gehosteten Runner einrichten. Wenn Sie sich für die öffentlichen Runner entscheiden, können Sie zwischen macOS, Windows und Ubuntu in verschiedenen Versionen wählen. Eine Sache, auf die Sie bei den öffentlichen Runnern achten sollten, ist, dass sie öffentlich sind, d. h., wenn Sie Ihren Workflow ausführen möchten, kann es sein, dass dies nicht sofort geschieht, weil Sie in eine Warteschlange gestellt werden, bis ein öffentlicher Runner verfügbar wird. Seien Sie sich dessen also bewusst.

Ein Job ist dann einfach eine Sammlung von Schritten - hier definieren wir unsere gesamte Geschäftslogik und Automatisierung, die wir durchführen wollen. Sie werden in diesem Runner ausgeführt - und zwar im selben Runner. Es wird also nicht ein Schritt in einem Runner und der nächste in einem anderen Runner ausgeführt - sie werden immer im selben Runner ausgeführt. Wir teilen der GitHub Actions-Plattform über die runs-on-Eigenschaft des Auftrags mit, auf welchem Runner er ausgeführt werden soll. Wir sagen also, wir haben diesen Job und ich möchte, dass er auf macOS 10.12 läuft. Standardmäßig werden Aufträge innerhalb Ihres Workflows parallel ausgeführt, d. h. sie werden alle genau zur gleichen Zeit ausgeführt. Bei Bedarf können wir Abhängigkeiten zwischen diesen Aufträgen definieren, aber es ist wichtig, daran zu denken, dass alle Aufträge standardmäßig zur gleichen Zeit starten, bis Sie diese Abhängigkeit einrichten. Technisch gesehen kann ein Workflow eine unbegrenzte Anzahl von Aufträgen haben. Neben dem Wort "unbegrenzt" steht ein Sternchen, denn es gibt Grenzen dafür, wie lange ein Auftrag laufen kann und wie viele Aufträge parallel ausgeführt werden können, so dass eine wirklich unbegrenzte Anzahl nicht möglich ist.

Ein Step ist also einfach ein Shell-Skript oder ein Aufruf zu einer Aktion, die wir ausführen lassen wollen. Sie werden der Reihe nach ausgeführt - sie laufen nicht parallel -, aber sie werden nacheinander ausgeführt und sind voneinander abhängig. Wenn also ein früherer Schritt fehlschlägt, werden standardmäßig auch alle anderen Schritte in diesem Auftrag fehlschlagen. Auch hier können wir bei Bedarf dieses Standardverhalten ändern, aber so funktioniert es standardmäßig. Und auch hier gilt, dass alle diese Schritte - und das ist wichtig - in demselben Läufer ausgeführt werden. Es ist nicht möglich, den ersten Schritt in Ubuntu und den zweiten Schritt woanders auszuführen - das wird nicht passieren. Wir können Aufträge so einrichten, dass sie auf mehreren Versionen von Runnern ausgeführt werden, aber standardmäßig werden diese Schritte alle auf genau demselben Runner ausgeführt.

Wie ich bereits erwähnt habe, ist eine Aktion einfach ein in sich geschlossenes Stück Automatisierung, wie ein Legostein, den wir dann mit anderen Aktionen kombinieren können, um komplexe Automatisierungsaufgaben zu erstellen. Wenn man sich also die Konfiguration dieser Workflow-Datei ansieht, gibt es einige Dinge, die man braucht, um diese Automatisierung zu erstellen. Sie müssen ein Ereignis haben. In der Workflow-Datei müssen wir also mindestens ein Ereignis definieren, um der Plattform mitzuteilen, wann oder wie dieser Workflow ausgelöst werden soll. Darin muss mindestens ein Auftrag definiert sein, und dieser Auftrag muss mindestens einen Schritt enthalten. Die Schritte selbst müssen entweder einen Shell-Befehl ausführen oder eine Aktion nutzen.

Wir werden also unseren ersten Workflow erstellen. Wenn Sie das Skript nicht sehen können, lassen Sie es mich bitte wissen, und ich werde versuchen, die Schrift ein wenig zu vergrößern. Was ist also eines der Dinge, die wir brauchen? Ein Ereignis. Okay, also werde ich das Schlüsselwort on verwenden. An dieser Stelle möchte ich JetBrainsein Lob aussprechen , weil sie eine wunderbare Sammlung von IDEs entwickelt haben. Ich habe ein Plugin, das mir bei der Erstellung von Workflows hilft. Sie sehen also, sobald ich das Schlüsselwort einsetze, wird es automatisch vorausgefüllt, und jetzt habe ich eine Menge verschiedener Ereignisse, die ich nutzen kann. Für den heutigen Tag werde ich den workflow_dispatch verwenden . Mit workflow_dispatch kann ich einen Workflow manuell ausführen, so dass ich ihn bei Bedarf selbst auslösen kann, anstatt ein bestehendes Ereignis neu zu erstellen. Was brauchen wir noch? Wir brauchen einen Läufer. Aber wo definieren wir den Auslöser? Was ist das? Ich glaube, ich habe es gehört - Jobs. Okay, ich werde also Jobs machen, und ich muss einen Job schaffen. Ich werde also sagen, dass dieser Job "Hallo sagen" heißt, und was sagen Sie dann - wir brauchen einen Läufer? Also, ich sage runs-on, in diesem Fall werde ich ubuntu-latest sagen. Was brauche ich dann noch innerhalb des Jobs? Schritte. Ich werde also ein paar Schritte definieren, und in diesem Fall sage ich run: echo "hello there" - nicht"Jello there", wie wäre es mit "hello there"? Ja, da haben wir's. Also gut.

Um Ihre Aktionen auszuführen - hoppla, das ist die falsche Registerkarte. Versuchen wir es mit dieser - na also - die ist auch die falsche. Hey, da haben wir's! Um diese Aktionen auszuführen, müssen Sie sie auf der Registerkarte "Aktionen" in Ihrem Repository ausführen. Wenn Sie Ihren Computer aus haben und das sehen möchten, ist das Repository selbst hier oben in meinem Profil angeheftet. Mein Profil befindet sich unter github.com/gillo-mein Nachname. Ich habe einen ungewöhnlichen Nachnamen. In diesem Repository habe ich eine Registerkarte "Aktionen", auf der alle meine verschiedenen Aktionen - hier auf der linken Seite - definiert werden. Wir haben gerade eine mit dem Namen "Erste" erstellt. Ich werde sie jetzt nicht ausführen, weil ich nicht auf einen öffentlichen Läufer warten will, aber ich zeige Ihnen, wie sie ausgeführt wird. Standardmäßig wird der Name des Workflows in der Datei angezeigt, und dann werden alle Aufträge aufgelistet, also auch der Auftrag "say hello". Wenn wir dann weiter nach unten gehen, werden die Schritte aufgelistet, die ausgeführt werden - wir haben gerade einen ausgeführt, der "Hallo" sagt. Kein Beifall - juhu! Wir haben es geschafft! Wir haben unseren ersten Workflow erstellt - fantastisch.

Lassen Sie uns nun ein wenig tiefer einsteigen, denn ich habe einige Elemente verwendet, über die ich noch nicht gesprochen habe. Eines davon ist die Auftragskennung. Jeder Auftrag muss also eine Auftragskennung haben. In dem Beispiel, das wir gerade gemacht haben, habe ich ihn "saycore hello" genannt. Das liegt daran, dass sie aus alphanumerischen Zeichen, Bindestrichen oder Unterstrichen bestehen muss. Sie müssen innerhalb des Workflows eindeutig sein. Wir können also so viele Aufträge haben, wie wir wollen, aber sie müssen alle eindeutige IDs haben, und sie müssen entweder mit einem Buchstaben oder einem Unterstrich beginnen. Innerhalb der Schritte, die wir haben, handelt es sich wiederum nur um ein Array von Aufgaben - jede einzelne, die wir ausführen wollen. Es ist wichtig, daran zu denken, dass jeder Schritt innerhalb seines eigenen Prozesses ausgeführt wird. Wenn Sie also einen Unterprozess in einem Shell-Befehl erstellen, wird dieser in einem eigenen Prozess ausgeführt oder eine neue Sitzung gestartet - jeder Schritt wird in einem eigenen Prozess ausgeführt. Aber sie haben alle Zugriff auf dasselbe Dateisystem, da sie auf demselben Läufer laufen. Wenn also ein früherer Schritt in eine Datei schreibt, kann ein späterer Schritt auf diese Datei zugreifen, da er Zugriff auf das Dateisystem hat.

Jeder einzelne Schritt muss dann entweder die uses-Eigenschaft enthalten, die besagt: "Hey, GitHub Actions, ich möchte eine bestehende Aktion verwenden - ich möchte, dass du sie heranziehst und ausführst", oder, wie wir es getan haben, die run-Eigenschaft verwenden, die besagt: "Hey, ich möchte diesen Shell-Befehl ausführen" oder "Ich möchte dieses Shell-Skript ausführen." Gut, schauen wir uns also unseren zweiten Arbeitsablauf an. Blättern Sie hierher zurück - und das sollte - hoppla, rutschen Sie rüber, ich bin beim falschen - da haben wir's. Also, in diesem Fall habe ich mein Ereignis, also auf workflow_dispatch, habe ich genau denselben Auftrag, "say hello", aber beachten Sie, dass ich ihm einen Namen gegeben habe. Eines der Elemente, die Sie in Ihren Workflows verwenden können, ist, dass Sie dem Workflow einen Namen geben können, damit er auf der Registerkarte "Aktionen" eine schöne Bezeichnung hat. Sie können jedem Auftrag eine Namenseigenschaft geben, so dass Sie auch hier einen schönen Auftragsnamen anstelle der ID haben - Sie können sogar Ihre Schritte benennen. In diesem Fall führe ich ein "Hallo" aus und sage dann: "Hey, benutze eine Aktion". Ich zeige Ihnen diese Aktion, weil GitHub Actions im Gegensatz zu GitLab standardmäßig Ihr Repository nicht in den Runner auscheckt, wenn Sie ihn starten. Wenn Sie Zugriff auf den Code Ihres Repositorys benötigen, müssen Sie die Checkout-Aktion verwenden, um zu sagen: "Check out my repository into this file system." In diesem Fall habe ich also dieses Repository in das Dateisystem ausgecheckt, was es mir ermöglicht, im dritten Schritt diese Liste von Dateien zu katalogisieren - und dann im vierten Schritt einfach auszuführen - "Ich bin Schritt vier." Schauen wir uns das also mal an. Kommen Sie hierher zurück - ich werde zu meinen Aktionen zurückkehren. Beachten Sie, dass auf der linken Seite "Willkommen zur Party" steht, die zweite auf der linken Seite. Wenn ich darauf klicke, sehe ich, dass der Job nicht mehr die Job-ID ist, sondern diese nette Bezeichnung. Und jetzt habe ich hier drinnen meine vier Schritte, wobei der dritte Schritt diese nette, besser lesbare Bezeichnung hat. Sie sind ein hartes Pflaster - kein Applaus für jeden dieser Schritte - wow, alles klar. Mann, das ist es, wonach ich gesucht habe.

Vielleicht fragen Sie sich jetzt: "Okay, Paul, wir haben die Hälfte der Präsentation hinter uns, und bisher haben Sie die Hälfte über Arbeitsabläufe gesprochen. Ich dachte, es ginge hier um Aktionen - warum ist das so? Hat sich das irgendjemand gefragt? Ja, okay, also selbst wenn wir am Anfang eine Aktion erstellen, können Sie eine Aktion nicht direkt verwenden, sondern nur über einen Workflow. Wenn Sie also nicht wissen, wie Arbeitsabläufe funktionieren, können Sie keine Aktionen verwenden. Der zweite Teil ist, dass eine Aktion - eine zusammengesetzte Aktion, über deren verschiedene Typen wir gleich noch sprechen werden - fast genauso funktioniert wie ein Workflow mit dem Ereignis workflow_dispatch. Sie sind sich sehr ähnlich - sie haben viele Dinge gemeinsam, wie zum Beispiel die Eingaben. Während Sie also arbeiten und Ihre Geschäftslogik entwickeln, ist eine der Ideen hinter einer Aktion, dass sie wiederverwendbar ist, richtig? Sie können sie in mehreren Instanzen verwenden. Es ist also sehr wahrscheinlich, dass Sie in der Lage sein müssen, Informationen in diese Aktion aufzunehmen oder zu akzeptieren, und dafür sind die Eingaben gedacht. Aber auch workflow_dispatch kanndiese verwenden. Wir können also entweder Inputs in einem workflow_dispatch oder innerhalb unserer Aktion verwenden und alle gewünschten Inputs definieren. Und genau wie bei den Jobs müssen sie eindeutige IDs haben, und auch hier müssen sie alphanumerisch sein.

Innerhalb einer Aktion selbst gibt es einige Unterschiede. Einer davon ist, dass Sie für jede Eingabe innerhalb einer Aktion eine Beschreibung einfügen müssen. workflow_dispatch können Sie einfügen, aber Sie müssen es nicht - aber in einer Aktion ist es erforderlich. Ein weiteres Element, das Sie verwenden können, ist die Eigenschaft required - ob die Eingabe für die Ausführung des Workflows oder der Aktionen erforderlich ist oder nicht. Und schließlich können Sie einige Standardwerte einrichten, d. h., wenn dieser Wert oder ein Wert für diese bestimmte Eingabe nicht bereitgestellt wird, können Sie einen bekannten guten Wert als Standard festlegen. Der Zugriff auf die Eingaben erfolgt über einen so genannten "Kontext", auf den ich als Nächstes eingehen werde. Schauen wir uns also eine Eingabe an. Blättern Sie also zurück - da haben wir's. Beachten Sie, dass ich hier ein: workflow_dispatch habe. Jetzt habe ich eine inputs-Eigenschaft. In der input-Eigenschaft habe ich einem dieser Eingänge einen Namen gegeben, die Beschreibung festgelegt und auch gesagt, dass sie wahr ist. Ich habe bereits erwähnt, dass wir auf diese Eingabe über einen Kontext zugreifen werden - das ist dieses kleine Stück hier unten. Hier steht: "Hey, geh zurück zu den Eingaben - hol dir jetzt den Wert aus der ID der Eingabe - dem Namen." Macht das Sinn? Gut, sehen wir es uns in Aktion an.

Kommen Sie also zurück - ich gehe zurück zur dritten Eingabe. In diesem Fall werde ich diesen ausführen. Ich habe bereits erwähnt, dass Sie Workflows über diesen workflow_dispatchausführen können -so wird diese kleine Schaltfläche auf der rechten Seite angezeigt. Und siehe da - was steht da? "Wie ist Ihr Name?" Das ist die Eingabe, und wenn ich versuche, sie auszuführen - was - hey, danke, danke - wenn ich also versuche, sie auszuführen, was sollte passieren? Es schlägt fehl, ja - es sagt: "Nein, das ist erforderlich." Also sage ich: "Jerome - hallo, Jerome - juhu!" Also werde ich den Arbeitsablauf durchlaufen - hoffentlich gibt es schnell einen öffentlichen Läufer. Kommt schon, ihr öffentlichen Läufer - ich werde wissen, dass ein öffentlicher Läufer ihn ausführt, weil sich das kleine Häkchen in einen Punkt verwandelt - hey, da war's! Ich kann jetzt da reingehen - mein Job ist aufgelistet - er läuft gerade oder wartet - da, er fordert an - komm schon, mach fertig, mach fertig - hey! Alles klar, das war's, danke, danke an alle.

In Ordnung, also, Kontext-Kontexte sind die Art und Weise, wie Ihre Aktionen, Ihre Workflows Informationen von der Aktionsplattform erhalten, sei es über Läufer, über den Job, den Workflow selbst, die auftretenden Ereignisse - es ist die Art und Weise, wie diese Informationen an Ihre Codebasis zurückgegeben werden. Es gibt 12 Arten von Kontexten - ich zeige sie Ihnen hier. Hier auf der rechten Seite sehen Sie, dass wir 12 verschiedene Typen haben. Also noch einmal, die Läufer, die Schritte, die Eingaben, die Bedürfnisse, die Matrix, die Geheimnisse, die Variablen usw. - alles verschiedene Arten von Informationen, die Ihnen zur Verfügung stehen. Es ist jedoch zu beachten, dass nicht alle Zusammenhänge in allen Situationen verfügbar sind. Deshalb gibt es eine so genannte "Matrix", die Sie verwenden können. Wenn Sie keine Matrix verwenden, ist der Matrixkontext nicht verfügbar. Machen Sie sich also klar, dass Ihnen nicht alle Kontexte jederzeit zur Verfügung stehen. Um auf einen Kontext zuzugreifen, wenn Sie irgendetwas verwenden, das keine JavaScript-basierte benutzerdefinierte Aktion mit dem GitHub-Toolkit ist, greifen Sie auf diese Kontexte mit dem Dollarzeichen zu - den, wie nennt man sie, schicken Klammern - den schicken geschweiften Klammern, ich weiß nicht, wie sie wirklich heißen, wie auch immer sie heißen - dem Kontextnamen, dem Namen der gewünschten Eigenschaft. Dann können die Eigenschaften selbst entweder die gesuchten String-Werte sein oder andere Objekte, und Sie können immer weiter und weiter und weiter nach unten gehen, bis Sie den Kontext finden, den Sie brauchen, z. B. den Zugriff auf einen Schritt-Kontext, bei dem ich auf eine bestimmte ID eines Schritts zugreife, dann ziele ich auf seine Ausgaben, über die wir gleich sprechen werden - ich ziele auf seinen Ausgabe-Kontext, um den in der Ziel-URL-ID enthaltenen Wert zu erhalten.

Wenn Sie JavaScript verwenden, gibt es dieses nette kleine Toolkit, das diese verschiedenen Kontexte über Methoden zugänglich macht. Jetzt gibt es eine kurze Warnung, und das ist eine wichtige Warnung - bitte, wenn Sie sich an nichts anderes über diese Präsentation erinnern, merken Sie sich das - die Kontexte, die von der Benutzereingabe kommen, sind nicht pre-escaped - sie sind nicht darauf vorbereitet, dass Sie sie innerhalb von Shell-Befehlen oder Ihrem Code direkt verwenden können. Ist das klar? Das bedeutet, dass sie reif für Code-Injection sind. Wenn ich zum Beispiel versuchen würde, eine Shell-Variable gleich einem Anfragetitel zu setzen - einem Pull-Request-Titel - die Pull-Request-Titel kommen von den Nutzern - was würde passieren, wenn sie einen Pull-Request-Titel namens a"; erstellen, und wenn ich dann title="a"; setze, was passiert dann? Das ist ein kompletter Shell-Befehl, richtig? Das Semikolon sagt: "Dies ist das Ende eines Befehls - hier ist der nächste". Am Ende würde ich diesen Befehl ausführen. Seien Sie sich also bewusst, dass Sie diese nicht direkt verwenden können.

In Ordnung, also Ausgaben - wenn Sie eine Eingabe akzeptiert haben und diese Informationen verarbeitet haben, müssen Sie möglicherweise Informationen ausgeben. Wenn Sie einen komplexen Arbeitsablauf aufbauen, wird einer dieser Schritte wahrscheinlich irgendwann etwas tun, auf das ein anderer Schritt zugreifen kann. Bei Ausgaben handelt es sich also einfach um Daten oder Informationen, die Sie von einer Aktion zurück an den aufrufenden Workflow oder von einem Schritt an den nächsten Schritt senden möchten. Es sind also nur Informationen, die wir später wiederverwenden können. Um eine Ausgabe zu setzen - wiederum von allem, was nicht das JavaScript-Toolkit verwendet -, wird die ID mit dem Wert gleichgesetzt und dann an die GitHub-Ausgabe-Umgebungsvariable gesendet. Wenn Sie das JavaScript-Toolkit verwenden, steht Ihnen eine schöne setOutput-Methode zur Verfügung, mit der Sie diese Werte festlegen können. Wie wir vorhin gesehen haben, müssen Sie, um diese Werte zu verwenden, auf einen Kontext zugreifen - die Schritte - höchstwahrscheinlich die Schritte - die Schritt-ID, die das Objekt von hier oben ausgibt, und dann die ID, die wir möglicherweise festgelegt haben.

Wollen Sie das in Aktion sehen? Juhu, es geht los! In Ordnung, ich wollte sagen, dass Sie jetzt sehr wach sein sollten. In Ordnung, wir haben hier einen weiteren Arbeitsablauf - oh, ich werde nach oben scrollen, weil ich die Schrift ein wenig größer gemacht habe. Beachten Sie, dass ich im dritten Schritt, dem zweiten Schritt, entschuldigen Sie, dem zweiten Schritt, den aktuellen Zeitstempel des Datums nehme, diesen auf eine ID von currentTime setze, an die Ausgabe sende und dann im dritten Schritt auf den Wert zugreifen kann, den ich über den Schrittkontext gesetzt habe - ich gehe zurück nach oben, um die Zeit zu erhalten, greife mir currentTime, um sie auszugeben. Und ich zeige Ihnen das in Aktion. Blättern Sie hier rüber, gehen Sie zurück zu meiner Registerkarte "Aktionen" - höre ich da ein Gähnen? Ich bin doch nicht so langweilig, oder? Meine Güte, ihr seid aber fleißig. Äh, mal sehen - ist das die dritte - ich habe vergessen, welche - oh, da ist sie. Also, greifen Sie hier zu - hier ist mein "say load"-Job, und nehmen Sie auch die Zeit. Hier können Sie sehen, dass ich die Zeit gesetzt habe und sie an die Ausgabe weitergegeben habe. Lassen Sie mich hier meinen Zeiger nehmen. Ich setze also currentTime= das Datum, und im vierten Schritt gebe ich das über diesen Kontext aus. Juhu, das ist genau das, wonach ich gesucht habe.

In Ordnung, jetzt sind wir vorbereitet. Wir haben alle Werkzeuge, wir haben alles Wissen, das wir brauchen. Wir sind bereit, benutzerdefinierte Aktionen zu erstellen - oh, nur keine Aktionen mit einem großen "A" - wir müssen Aktionen mit einem kleinen "a" erstellen, merken Sie sich das. Nun gut, es gibt drei Arten von Aktionen, die Sie erstellen können. Wir haben Zugriff auf eine Aktion vom Typ Docker, eine JavaScript-Aktion und eine zusammengesetzte Aktion. Der Unterschied besteht darin, dass Sie mit Docker die Umgebung, in der Ihre Geschäftslogik ausgeführt wird, sehr genau festlegen können. Wenn Sie also sehr strenge Anforderungen haben, müssen Sie wahrscheinlich Ihr eigenes Docker-Image anstelle eines der öffentlichen Runner verwenden. Eine JavaScript-basierte zusammengesetzte Aktion ist gut, weil Sie den Aktionscode - die Geschäftslogik - vom Aktionsdienst selbst trennen können und leichter - nein, leichter - leichter - ich bin etwas durcheinander geraten - leichter die Umgebung nachbilden und den Code außerhalb der GitHub Actions-Plattform testen können, und sie läuft normalerweise etwas schneller als eine Docker-basierte benutzerdefinierte Aktion. Das Problem bei einer JavaScript-basierten benutzerdefinierten Aktion ist, dass Sie die öffentliche Aktion eines anderen nicht nutzen oder wiederverwenden können, es sei denn, sie haben diese Aktion auch als JavaScript-Paket veröffentlicht. Dafür gibt es die dritte Möglichkeit, die Composite genannt wird und die es Ihnen ermöglicht, die Aktionen anderer in Ihrer eigenen Aktion zu verwenden, wodurch Sie wiederum die Modularität von Legosteinen nutzen können, um etwas Komplexeres zusammenzustellen.

Die Aktionen selbst müssen in einem eigenen Repository gespeichert werden, oder wenn Sie sie in einem bestehenden Repository speichern wollen, müssen sie sich in einem eigenen Verzeichnis befinden. Nun gibt es einige Teile von Aktionen, die man haben muss - entschuldigen Sie - und der erste ist, dass sie alle eine Metadaten-Datei haben müssen. Diese Metadaten-Datei muss eine YAML-Datei mit dem Namen action.yml sein und im Stammverzeichnis des Repositorys des Verzeichnisses gespeichert werden, in dem Ihre Aktion gespeichert ist. Sie muss mindestens drei Eigenschaften enthalten - technisch gesehen vier. Sie muss einen Namen, eine Beschreibung und die Eigenschaft runs mit der Untereigenschaft runs-using haben. Sie muss alle diese Eigenschaften haben. Die runs-using-Eigenschaft teilt der Action-Plattform mit, welchen Typ wir verwenden werden - also runs-using: docker, runs-using: composite. Je nachdem, welche Art von Aktion Sie wählen, gibt es weitere Eigenschaften, die innerhalb der Eigenschaft runs erforderlich sind. Außerdem werden in der Metadatendatei die Ein- und Ausgänge definiert.

Ein Beispiel für eine Aktion - und dies ist eine vollständige Aktionsdatei - ist also: Ich habe die Eigenschaft " Name", "Begrüßt den Benutzer" und eine Beschreibung: Begrüße den Benutzer auf der GitHub-Aktionsplattform, dann habe ich die Eigenschaft runs mit einer Untereigenschaft using, und ich verwende node:20, um eine JavaScript-basierte benutzerdefinierte Aktion zu bezeichnen. Da es sich um eine JavaScript-basierte benutzerdefinierte Aktion handelt, muss ich die Eigenschaft main haben und sie auf meine Bootstrap- oder Kickoff-Datei für meine Geschäftslogik innerhalb dieses JavaScript-Pakets verweisen.

Bei den drei verschiedenen Arten von zusammengesetzten Aktionen oder drei verschiedenen Arten von Aktionen gibt es einige Warnungen. Wenn Sie die runs-using-Eigenschaft für Docker und Composite verwenden, benutzen Sie die Wörter "Docker" und "Composite", aber für JavaScript benutzen Sie nicht das Wort "JavaScript", sondern die Node-Version, die Sie verwenden möchten. Derzeit sind nur die Versionen 16 und 20 für Node innerhalb einer benutzerdefinierten Aktion gültig - Version 16 ist seit dem 24. Oktober veraltet. Es gibt noch keinen Ersatz, so dass die einzige Version, auf die Sie wirklich Zugriff haben, 20 ist. Ich glaube, dass Node 22 im kommenden Frühjahr veröffentlicht wird, und höchstwahrscheinlich werden sie dann Node 22 als Option hinzufügen. Die andere Herausforderung bei einer JavaScript-basierten benutzerdefinierten Aktion ist, dass Sie das gesamte Verzeichnis node_modules oder alle Ihre JavaScript-Abhängigkeiten in das Repository übertragen müssen, um sie zu verwenden, oder etwas wie Vercels NCC verwenden, um alle Ihre Abhängigkeiten in einer einzigen JavaScript-Datei zu bündeln.

Die Warnung bei der Composite-basierten benutzerdefinierten Aktion ist, dass die Binärdateien und Programme in den Läufern möglicherweise nicht die Version sind, die Sie benötigen. Und wenn Sie den Großteil Ihrer benutzerdefinierten Aktion - der zusammengesetzten Aktion - damit verbringen, Abhängigkeiten zu aktualisieren, kann das der Punkt sein, an dem Sie zu einer Docker-basierten Aktion wechseln müssen. Sind Sie also bereit, eine benutzerdefinierte Aktion zu erstellen? Juhu, es geht los - das höre ich gerne.

In Ordnung, was muss ich also haben - oh, oh, du bist gut - in Ordnung, für eine Aktion, was müssen wir haben, um die Aktion zu erstellen? Eine Metadaten-Datei - was brauchen wir? Einen Namen - okay, ich habe also meinen Namen. Was noch? Eine Beschreibung - was noch? Läuft-verwendet. In Ordnung, ich habe also Composite. In diesem Fall wird Composite andere Aktionen nutzen, also wird es eine Anforderung von Schritten haben. In diesem Fall - ich vergaß, das zu erwähnen - baue ich diese Aktion hier im Verzeichnis .github/actions auf, und dann hat sie ein eigenes Verzeichnis. Es muss nicht unbedingt "actions" heißen - das habe ich einfach so gemacht - es machte einfach Sinn für mich - ich wollte sie alle an einem ähnlichen Ort speichern, aber meine Metadaten-Datei befindet sich dort im Stammverzeichnis.

Was muss ich also tun, um das Repository, das wir vorhin gesehen haben, nutzen zu können? Oh, ich muss es auschecken, richtig-oops, ich habe einen Schritt übersprungen-oh, ich habe den ganzen Weg übersprungen-es tut mir leid, ich habe meine Schritte übersprungen. Wir werden das also nicht... wir werden das im Workflow machen, tut mir leid. Wir versuchen also unter anderem, diese Aktion in den Workflow einzubauen, den wir vorhin gemacht haben. Ich möchte also dasselbe tun - ich möchte jemandem "Hallo" sagen, also werde ich eine Eingabe machen. Diesmal nenne ich sie who_to_greet und lege die Beschreibung fest. Wir können den Typ überspringen - jeder Typ innerhalb einer Aktion ist ein String. Innerhalb von Workflows gibt es mehrere Typen, also habe ich das in diesem Fall einfach wiederverwendet. In meinem Schritt habe ich ihm einen Namen und eine ID gegeben - in diesem Fall habe ich gesagt, dass ich die Bash-Shell anstelle eines anderen Shell-Typs verwenden möchte, und dann werde ich Folgendes ausführen: echo "Hello" ${{ inputs.who_to_greet }}.

Können wir diese Aktion nun direkt ausführen? Nein, was brauchen wir dafür? Einen Workflow - alles klar. Und was brauchen wir innerhalb des Workflows? Ein Ereignis. Gut, das ist also mein Ereignis - was noch? Jobs. Also, da ist mein Job - was noch? Schritte. Da ich diese Aktion im Repository selbst gespeichert habe, muss ich nun das Repository auschecken, um diese Aktion verwenden zu können. Dann kann ich sagen: "In Ordnung, ich möchte die Aktion verwenden, die in diesem Repository gespeichert ist", aber diese Aktion, die wir gerade erstellt haben, hat eine - hat eine was? Eine Eingabe. Ich verwende also das Schlüsselwort with, und dann verwende ich dieselbe Eingabe-ID und gebe ihr einen Wert. Da ich dies als Dispatch ausführen möchte, muss ich wahrscheinlich eine Eingabe bereitstellen, also werde ich auch eine Eingabe in den Workflow selbst aufnehmen. Der Workflow wird also ausgeführt, er wird eine Eingabe haben, und ich werde dann die Eingabe nehmen und sie an die soeben erstellte Aktion senden.

Sind Sie bereit, das in Aktion zu sehen? Sind Sie bereit? Gut, gehen wir also zurück zu meiner Registerkarte "Aktionen" und sagen wir "V, eine Aktion" und klicken auf Ausführen. Beachten Sie, wen wir begrüßen sollten - ich sage wieder "SymfonyCon 2023", aber ich werde hier noch ein paar Ausrufezeichen einfügen - nein, genau da - oh, gehen Sie ganz rüber - warum lässt es mich nicht auswählen? Und los geht's - wir sagen: "Super aufgeregt" - führen Sie diesen Workflow aus - kommt schon, öffentliche Teilnehmer - denn ich weiß, dass ich knapp in der Zeit liege - kommt schon, kommt schon, kommt schon - da haben wir's - klicken Sie darauf. Das ist unser Workflow - wir gehen in den Workflow hinein - wir sehen, dass er unser Repository ausgecheckt hat - er hat dann unseren Begrüßungsbenutzer ausgeführt - und wenn ich das ausführe, sollte ich das haben - und los geht's! Juhu!

Gut, was haben wir also behandelt? Wir haben die Aktionsplattform behandelt, richtig? Wir haben über die verschiedenen Komponenten der Aktionsplattform gesprochen, die wir verwenden können. Wir haben über die Workflow-Datei gesprochen und darüber, wie wir die Workflow-Datei definieren und welche Teile dafür erforderlich sind. Dann haben wir gemeinsam unseren ersten Workflow erstellt. Wir sprachen über benutzerdefinierte Aktionen und die Teile, die dafür erforderlich sind. Dann haben wir diese Aktion zusammen mit dem Workflow erstellt und über einige Warnungen gesprochen, richtig? Aber Hallo-Welten sind immer ein bisschen, ähm, nicht ganz so nützlich, richtig? Lassen Sie uns also alles zusammenfügen. Lassen Sie uns das alles in einem realen Beispiel zusammenfassen. Und das Ziel ist - in diesem speziellen Fall war es ein echtes Ziel -, dass wir bei jeder Pull-Anforderung einen visuellen Regressionstest durchführen können müssen. Ist jeder mit visuellen Regressionstests vertraut, bei denen man einen Screenshot der Produktionsseite und einen Screenshot einer anderen Seite macht und dann vergleicht, ob es irgendwelche Regressionen in diesem visuellen Aspekt gibt, richtig? Gut, ja? Okay, sehen wir uns also die Aktion an - hoppla, scrollen Sie rüber - ist das die Aktion? Nein, das ist nicht die Aktion. Ah, da ist die Aktion - Entschuldigung, die falsche.

In Ordnung, was sind also die zwei Dinge, die ich für einen visuellen Regressionstest mindestens brauche? Zwei - ich brauche einen Screenshot - ich brauche die Produktions-URL - eine Produktionsseite - und eine Testseite. Hier habe ich also meinen Namen und meine Beschreibung - die müssen wir haben. Ich habe Eingaben - eine ist die Test-URL, also geben Sie mir eine URL, die Sie mit neuen Dingen testen wollen. Die Referenz-URL ist die Produktionsseite. Lassen Sie mich scrollen, damit Sie das sehen können - ich habe die Durchläufe, die verwendet werden: Composite und Run-Steps. Der erste ist, dass ich wahrscheinlich sicherstellen möchte, dass die URL - der String, der mir gegeben wurde - wie eine URL aussieht, und ich möchte wahrscheinlich sicherstellen, dass die Site antwortet. In diesem Fall verwende ich also eine Aktion - das ist sie - ich habe eine Aktion, der ich die Test-URL sende, und diese Aktion sagt nur: "Sieht das wie eine URL aus? Jetzt rufe ich die Website an und prüfe, ob sie antwortet." Ich mache das also einmal mit der Test-URL und dann einmal mit der Referenz-URL.

Dann verwende ich ein Paket namens Backstop. Backstop ist ein visuelles Regressionstool, das ich also installiere. In einer Minute muss ich die Konfiguration von Backstop ändern, um ihm diese neuen URLs zu geben. Dazu muss ich jq verwenden , eine JSON-Abfrage innerhalb der Shell, aber die Version, die mit dem Public Runner geliefert wurde, war 1.6, und ich brauchte 1.7. Jetzt kann ich also eine andere Aktion innerhalb meiner Aktion verwenden, um jq innerhalb des Runners zu aktualisieren. Dann aktualisiere ich die Konfiguration von Backstop, um meine neuen URLs einzubinden, und führe die Referenz von Backstop aus, die dann die Screenshots macht. Dann kann ich den Test starten.

Was macht ein Test normalerweise, wenn er fehlschlägt? Er schlägt fehl, es gibt einen - aber was noch? Er erstellt einen Bericht, richtig? Also, zwei Dinge: Erstens, er schlägt fehl - und ich sagte bereits, dass die einzelnen Schritte immer voneinander abhängig sind - wenn einer fehlschlägt, fällt alles andere aus. Das soll nicht passieren. In diesem Fall habe ich also continue-on-error: truegesetzt -das heißt: "Nicht abbrechen, wenn einer dieser Schritte fehlschlägt." Ich unterdrücke die Meldung und erfasse sie - hier ist sie - test_results=$? Und dann gehe ich nach unten und - ups, es ist nicht auf dem Bildschirm - lassen Sie mich ein wenig nach unten scrollen - ich setze die Ausgabe des Tests selbst auf eine andere Umgebungsvariable, die ich dann weiter unten verwenden kann.

Ich habe vorhin gesagt, dass jeder der Schritte abhängig ist - in diesem Fall haben Sie auch Bedingungen für die Schritte. Ich kann sagen: "Führe diesen Schritt nur aus, wenn diese Umgebungsvariable auf false gesetzt wurde." Wenn der Test zuvor fehlgeschlagen ist, verwende ich jetzt eine weitere Aktion, um den Bericht zu speichern und ihn an den aufrufenden Workflow anzuhängen, so dass jemand, der dies in einem Pull Request verwendet, den Fehler sehen und den visuellen Regressionstest tatsächlich verwenden oder anzeigen kann. Wenn der Test fehlschlägt, werde ich ihn mit einem Wert ungleich Null beenden, so dass der Schritt im aufrufenden Workflow fehlschlägt, und dann werden die restlichen Schritte in diesem Job fehlschlagen.

Um das zu sehen, blättern Sie hier rüber - hier ist der angehängte Workflow, der dazu gehört. Jetzt werde ich also sagen, dass ich bei einer Pull-Anfrage auf main ziele - wenn es also eine Pull-Anfrage gegen main gibt, werde ich die neueste Version von Ubuntu verwenden. Ich werde dann - oh, fast hätte ich es vergessen - eines der großartigen Dinge an Platform und Upsun ist, dass wir diese Integrationen mit GitHub haben, und eines der Dinge, die es tut, ist, dass es, wenn Sie eine Pull-Request erstellen, tatsächlich Ihre Produktionsumgebung klont. Dann wird der PR-Code in diese Umgebung eingefügt und dann hochgeladen. Mit der Integration kontaktiert es GitHub und sagt: "Hey, ich habe das erfolgreich abgeschlossen - hier ist die URL deiner neuen ephemeren PR-Umgebung." Und das ist es, was diese erste Aktion macht - sie sagt: "Hey, hast du schon einen Erfolg erhalten, GitHub? Oh, hast du? Okay, dann gib mir jetzt die URL", und sie sendet eine Ausgabe namens target_url. Der zweite Schritt ist dann die Ausführung der Aktion, die ich Ihnen gerade gezeigt habe, wobei die URL gesendet wird, die wir von der ersten Aktion erhalten haben. Und dann habe ich - da sich die Produktions-URL normalerweise nicht ändert - diese als Repository-Variable in GitHub gespeichert und weitergegeben.

Um das in Aktion zu sehen, lassen Sie mich zurückblättern, denn ich weiß, dass ich nicht viel Zeit habe. Wo ist mein Pull Request - nein, das ist der Kontext - hier ist er - hier ist mein Pull Request. Sie können unten sehen, dass die Integration erfolgreich war und meine URL zurückgegeben hat. Ich habe einige andere Tests laufen lassen, dann den Workflow für den Pull - die visuellen Regressionstests liefen, aber wie Sie sehen können, sind sie fehlgeschlagen. Wenn ich die Details aufrufe, steht dort: "Visuelle Regressionstests sind fehlgeschlagen". Wenn ich dann in der Zusammenfassung nachsehe - wenn ich ganz nach unten scrollen kann -, sehe ich den gespeicherten visuellen Regressionstestbericht. Und jetzt kann ich einen Blick auf diesen Bericht werfen und sehen, dass zwei Tests bestanden und zwei fehlgeschlagen sind - oh Gott, ja, das war definitiv nicht gut. Oh, es sieht so aus, als hätte sich die Schriftgröße geändert oder so - oh ja. Und jetzt weiß ich in meinem Pull-Request: "Hey, da stimmt was nicht - ich muss nachsehen, was passiert ist."

Ich danke euch allen. In Ordnung, ich glaube, ich habe keine Zeit mehr - vielleicht habe ich zwei, drei - ich weiß nicht, ob ich noch Zeit habe oder nicht - ich habe nicht gesehen, wie spät es ist. Nun, hier sind meine Kontaktdaten. Ich bin ziemlich leicht zu finden - es gibt nicht viele Gilzows auf der Welt. Aber der beste Weg, mich zu finden, ist linktr.ee/gilzow - dortsind alle meine Social-Media-Accounts zu finden - jeder einzelne, Profile überall, und ich bin fast immer "gilzow" bei allem. Sie können mich also gerne kontaktieren - ich werde auch den Rest des Tages am Stand sein. Ich liebe es, über dieses Thema zu sprechen, und würde mich freuen, wenn Sie mir jetzt oder später Fragen stellen.

Ihr größtes Werk
steht vor der Tür

Kostenloser Test
Discord
© 2025 Platform.sh. All rights reserved.