Als DevOps-Administrator oder -Entwickler können Sie benutzerdefinierte Skripts erstellen, die die Funktion von Code Stream erweitern. Mit Ihrem Skript können Sie Code Stream in Ihre eigenen CI-Tools (Continuous Integration), CD-Tools (Continuous Delivery) und APIs integrieren, die Ihre Anwendungen erstellen, testen und bereitstellen. Benutzerdefinierte Skripts sind besonders nützlich, wenn Sie Ihre Anwendungs-APIs nicht öffentlich verfügbar machen.

Ihr benutzerdefiniertes Skript kann fast alles tun, was Sie für die Integration in Ihre Build-, Test-und Bereitstellungstools benötigen. Beispielsweise kann es den Arbeitsbereich in Ihrer Pipeline dazu nutzen, CI-Aufgaben zum Erstellen und Testen Ihrer Anwendung und CD-Aufgaben zum Bereitstellen der Anwendung zu unterstützen. Es kann eine Meldung an Slack senden, wenn eine Pipeline abgeschlossen ist, und vieles mehr.

Sie schreiben Ihr benutzerdefiniertes Skript in einer der unterstützten Sprachen. Sie nehmen Ihre Geschäftslogik im Skript auf und definieren Ein- und Ausgaben. Ausgabetypen können Zahl, Zeichenfolge, Text und Kennwort enthalten. Sie können mehrere Versionen eines benutzerdefinierten Skripts mit unterschiedlicher Geschäftslogik, Eingaben und Ausgaben erstellen.

In der Pipeline wurde eine Version des Skripts in einer benutzerdefinierten Aufgabe ausgeführt. Die von Ihnen erstellten Skripts befinden sich in Ihrer Code Stream-Instanz.

Wenn eine Pipeline eine benutzerdefinierte Integration verwendet und Sie versuchen, die benutzerdefinierte Integration zu löschen, wird eine Fehlermeldung angezeigt, die besagt, dass Sie sie nicht löschen können.

Beim Löschen einer benutzerdefinierten Integration werden alle Versionen des benutzerdefinierten Skripts entfernt. Wenn Sie über eine vorhandene Pipeline mit einer benutzerdefinierten Aufgabe verfügen, die eine beliebige Version des Skripts verwendet, schlägt diese Pipeline fehl. Damit vorhandene Pipelines nicht fehlschlagen, können Sie die nicht mehr zu verwendende Version des Skripts als veraltet einstufen und zurückziehen. Wenn diese Version von keiner Pipeline verwendet wird, können Sie sie löschen.

Tabelle 1. Vorgehensweisen nach dem Schreiben des benutzerdefinierten Skripts
Vorgehensweise... Weitere Informationen zu dieser Aktion...

Hinzufügen einer benutzerdefinierten Aufgabe zu Ihrer Pipeline.

Die benutzerdefinierte Aufgabe:

  • Wird auf demselben Container wie andere CI-Aufgaben in Ihrer Pipeline ausgeführt.
  • Enthält Eingabe- und Ausgabevariablen, die Ihr Skript auffüllt, bevor die Pipeline die benutzerdefinierte Aufgabe ausführt.
  • Unterstützt mehrere Datentypen und verschiedene Arten von Metadaten, die Sie als Eingaben oder Ausgaben in Ihrem Skript definieren.

Auswählen Ihres Skripts in der benutzerdefinierten Aufgabe.

Sie deklarieren die Eingabe- und Ausgabeeigenschaften im Skript.

Speichern, Aktivieren und Ausführen Ihrer Pipeline.

Bei Ausführung der Pipeline ruft die benutzerdefinierte Aufgabe die Version des angegebenen Skripts auf und führt die darin enthaltene Geschäftslogik aus, die von Ihrem Build-, Test- und Bereitstellungstool in Code Stream integriert wird.

Anzeigen der Ausführungen nach dem Ausführen Ihrer Pipeline.

Vergewissern Sie sich, dass die Pipeline die erwarteten Ergebnisse bereitgestellt hat.

Wenn Sie eine benutzerdefinierte Aufgabe verwenden, die eine Version der benutzerdefinierten Integration aufruft, können Sie benutzerdefinierte Umgebungsvariablen als Name/Wert-Paare auf der Registerkarte Arbeitsbereich der Pipeline einbeziehen. Wenn das Builder-Image den Arbeitsbereichscontainer erstellt, der die CI-Aufgabe ausführt und Ihr Image bereitstellt, übergibt Code Stream die Umgebungsvariablen an diesen Container.

Beispiel: Wenn Ihre Code Stream-Instanz einen Web-Proxy benötigt und Sie einen Docker-Host zum Erstellen eines Containers für eine benutzerdefinierte Integration verwenden, führt Code Stream die Pipeline aus und übergibt die Variablen der Web-Proxy-Einstellungen an diesen Container.

Tabelle 2. Beispiel für Name/Wert-Paare der Umgebungsvariable
Name Wert
HTTPS_PROXY http://10.0.0.255:1234
https_proxy http://10.0.0.255:1234
NO_PROXY 10.0.0.32, *.dept.vsphere.local
no_proxy 10.0.0.32, *.dept.vsphere.local
HTTP_PROXY http://10.0.0.254:1234
http_proxy http://10.0.0.254:1234
PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

Name/Wert-Paare werden auf der Benutzeroberfläche folgendermaßen angezeigt:

In diesem Beispiel wird eine benutzerdefinierte Integration erstellt, die Code Stream mit Ihrer Slack-Instanz verbindet und eine Nachricht an einen Slack-Kanal sendet.

Voraussetzungen

  • Um Ihr benutzerdefiniertes Skript zu schreiben, stellen Sie sicher, dass Sie über eine der folgenden Sprachen verfügen: Python 2, Python 3, Node.js oder eine der folgenden Shell-Sprachen: Bash, sh oder zsh.
  • Generieren Sie mithilfe der installierten Node.js- oder Python-Laufzeit ein Container-Image.

Prozedur

  1. Erstellen Sie die benutzerdefinierte Integration.
    1. Klicken Sie auf Benutzerdefinierte Integrationen > Neu und geben Sie einen entsprechenden Namen ein.
    2. Wählen Sie die bevorzugte Laufzeitumgebung aus.
    3. Klicken Sie auf Erstellen.
      Ihr Skript wird geöffnet und zeigt den Code an, der die erforderliche Laufzeitumgebung enthält. Beispiel: runtime: "nodejs". Das Skript muss die Laufzeit enthalten, die vom Builder-Image verwendet wird, sodass die benutzerdefinierte Aufgabe, die Sie zu Ihrer Pipeline hinzufügen, bei Ausführung der Pipeline erfolgreich ausgeführt wird. Andernfalls schlägt die benutzerdefinierte Aufgabe fehl.
    Die YAML-Hauptbereiche Ihrer benutzerdefinierten Integration umfassen die Laufzeiteigenschaften, Code sowie Eingabe- und Ausgabeeigenschaften. In diesem Verfahren werden verschiedene Typen und die Syntax erläutert.
    YAML-Schlüssel der benutzerdefinierten Integration Beschreibung
    runtime

    Laufzeitumgebung der Aufgabe, in der Code Stream den Code ausführt, der eine der folgenden Zeichenfolgen ohne Unterscheidung der Groß-/Kleinschreibung darstellen kann:

    • nodejs
    • python2
    • python3
    • shell

    Wenn kein Wert vorhanden ist, wird „Shell“ als Standardeinstellung übernommen.

    code Benutzerdefinierte Geschäftslogik, die als Teil der benutzerdefinierten Aufgabe durchgeführt wird.
    inputProperties Array der Eingabeeigenschaften, die im Rahmen der Konfiguration der benutzerdefinierten Aufgabe erfasst werden. Diese Eigenschaften werden in der Regel im Code verwendet.
    outputProperties Array der Ausgabeeigenschaften, die aus der benutzerdefinierten Aufgabe exportiert und an die Pipeline weitergegeben werden können.
  2. Deklarieren Sie die Eingabeeigenschaften in Ihrem Skript unter Verwendung der verfügbaren Datentypen und Metadaten.
    Die Eingabeeigenschaften werden als Kontext an Ihr Skript im Abschnitt code: der YAML übergeben.
    YAML-Eingabeschlüssel der benutzerdefinierten Aufgabe Beschreibung Erforderlich
    type Anzuzeigende Eingabetypen:
    • text
    • textarea
    • number
    • checkbox
    • password
    • select
    Ja
    name Name oder Zeichenfolge der Eingabe für die benutzerdefinierte Aufgabe, die in den YAML-Code der benutzerdefinierten Integration eingefügt wird. Muss für jede Eingabeeigenschaft, die für eine benutzerdefinierte Integration definiert wird, eindeutig sein. Ja
    title Bezeichnung der Textzeichenfolge der Eingabeeigenschaft für die benutzerdefinierte Aufgabe auf der Arbeitsfläche des Pipeline-Modells. Wenn kein Wert angegeben ist, wird standardmäßig name verwendet. Nein
    required Gibt an, ob ein Benutzer die Eingabeeigenschaft beim Konfigurieren der benutzerdefinierten Aufgabe eingeben muss. Legen Sie diesen Wert auf „true“ oder „false“ fest. Bei einem Wert von „true“ verbleibt der Status der Aufgabe bei „Nicht konfiguriert“, wenn ein Benutzer beim Konfigurieren der benutzerdefinierten Aufgabe auf der Pipeline-Arbeitsfläche keinen Wert bereitstellt. Nein
    placeHolder Standardtext für den Eingabebereich der Eingabeeigenschaft, wenn kein Wert vorhanden ist. Ist dem HTML-Platzhalterattribut zugeordnet. Wird nur für bestimmte Typen von Eingabeeigenschaften unterstützt. Nein
    defaultValue Standardwert, mit dem der Eingabebereich der Eingabeeigenschaft befüllt wird, wenn die benutzerdefinierte Aufgabe auf der Seite des Pipeline-Modells ausgeführt wird. Nein
    bindable Legt fest, ob die Eingabeeigenschaft Dollarzeichenvariablen akzeptiert, wenn die benutzerdefinierte Aufgabe auf der Arbeitsfläche der Pipeline modelliert wird. Fügt den Indikator $ neben dem Titel ein. Wird nur für bestimmte Typen von Eingabeeigenschaften unterstützt. Nein
    labelMessage Zeichenfolge, die als QuickInfo für Benutzer fungiert. Fügt das QuickInfo-Symbol i neben dem Eingabetitel ein. Nein
    enum Nimmt ein Array von Werten auf, in dem die Optionen zum Auswählen von Eingabeeigenschaften angezeigt werden. Wird nur für bestimmte Typen von Eingabeeigenschaften unterstützt.

    Wenn ein Benutzer eine Option auswählt und für die benutzerdefinierte Aufgabe speichert, entspricht der Wert für inputProperty diesem Wert und wird in der benutzerdefinierten Aufgabe angezeigt.

    Beispielsweise der Wert 2015.

    • 2015
    • 2016
    • 2017
    • 2018
    • 2019
    • 2020
    Nein
    options Nimmt ein Array von Objekten mithilfe von optionKey und optionValue auf.
    • optionKey. Der Wert wird an den Codeabschnitt der Aufgabe weitergegeben.
    • optionValue. Zeichenfolge, die die Option auf der Benutzeroberfläche anzeigt.

    Wird nur für bestimmte Typen von Eingabeeigenschaften unterstützt.

    Optionen:

    optionKey: key1. Wenn dieser Wert für die benutzerdefinierte Aufgabe ausgewählt und gespeichert wurde, entspricht der Wert dieser inputProperty dem Wert key1 im Codeabschnitt.

    optionValue: 'Bezeichnung für 1'. Anzeigewert für key1 auf der Benutzeroberfläche, der an keiner anderen Stelle für die benutzerdefinierte Aufgabe angezeigt wird.

    optionKey: key2

    optionValue: 'Bezeichnung für 2'

    optionKey: key3

    optionValue: 'Bezeichnung für 3'

    Nein
    minimum Nimmt eine Zahl auf, die als Mindestwert fungiert und für diese Eingabeeigenschaft gültig ist. Wird nur für Eingabeeigenschaften vom Typ „Zahl“ unterstützt. Nein
    maximum Nimmt eine Zahl auf, die als Höchstwert fungiert und für diese Eingabeeigenschaft gültig ist. Wird nur für Eingabeeigenschaften vom Typ „Zahl“ unterstützt. Nein
    Tabelle 3. Unterstützte Datentypen und Metadaten für benutzerdefinierte Skripts
    Unterstützte Datentypen Unterstützte Metadaten für die Eingabe
    • Zeichenfolge
    • Text
    • Liste: als Liste eines beliebigen Typs
    • Zuordnung: als map[string]any
    • Sicher: wird als Kennwort-Textfeld dargestellt und verschlüsselt, wenn Sie die benutzerdefinierte Aufgabe speichern
    • Zahl
    • Boolesch: wird in Form von Textfeldern angezeigt
    • URL: identisch mit Zeichenfolge, mit zusätzlicher Validierung
    • Auswahl, Optionsschaltfläche
    • type: einer von „string“ oder „text“...
    • default: Standardwert
    • options: Liste mit oder Zuordnung von Optionen, die mit der Auswahl oder der Optionsschaltfläche verwendet werden sollen
    • min: Minimalwert oder -größe
    • max: Maximalwert oder -größe
    • title: detaillierter Name des Textfeldes
    • placeHolder: UI-Platzhalter
    • description: wird zur QuickInfo
    Beispiel:
    inputProperties:
            - name: message
              type: text
              title: Message
              placeHolder: Message for Slack Channel
              defaultValue: Hello Slack
              bindable: true
              labelInfo: true
              labelMessage: This message is posted to the Slack channel link provided in the code
    
  3. Deklarieren Sie die Ausgabeeigenschaften in Ihrem Skript.
    Das Skript erfasst Ausgabeeigenschaften aus dem Abschnitt code: der Geschäftslogik Ihres Skripts, in dem Sie den Kontext für die Ausgabe deklarieren.
    Wenn die Pipeline ausgeführt wird, können Sie den Antwortcode für die Aufgabenausgabe eingeben. Beispiel: 200.
    Schlüssel, die von Code Stream für jede outputProperty unterstützt werden.
    key Beschreibung
    Typ Enthält zurzeit einen einzelnen Wert vom Typ label.
    name Schlüssel, der vom Codeblock der benutzerdefinierten Integrations-YAML ausgegeben wird.
    title Bezeichnung auf der Benutzeroberfläche, die outputProperty anzeigt.
    Beispiel:
    outputProperties:
      - name: statusCode
        type: label
        title: Status Code
  4. Um mit der Eingabe und Ausgabe Ihres benutzerdefinierten Skripts zu interagieren, rufen Sie eine Eingabeeigenschaft ab oder legen Sie eine Ausgabeeigenschaft unter Verwendung von context fest.
    Für eine Eingabeeigenschaft: (context.getInput("key"))
    Für eine Ausgabeeigenschaft: (context.setOutput("key", "value"))
    Für Node.js:
    var context = require("./context.js")
    var message = context.getInput("message");
    //Your Business logic
    context.setOutput("statusCode", 200);
    Für Python:
    from context import getInput, setOutput
    message = getInput('message')
    //Your Business logic
    setOutput('statusCode', '200')
    
    Für Shell:
    # Input, Output properties are environment variables
    echo ${message} # Prints the input message
    //Your Business logic
    export statusCode=200 # Sets output property statusCode
    
  5. Deklarieren Sie im Abschnitt code: die gesamte Geschäftslogik für Ihre benutzerdefinierte Integration.
    Beispielsweise mit der Node.js-Laufzeitumgebung
    code: |
        var https = require('https');
        var context = require("./context.js")
        
        //Get the entered message from task config page and assign it to message var
        var message = context.getInput("message");
        var slackPayload = JSON.stringify(
            {
                text: message
            });
    
        const options = {
            hostname: 'hooks.slack.com',
            port: 443,
            path: '/YOUR_SLACK_WEBHOOK_PATH',
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
                'Content-Length': Buffer.byteLength(slackPayload)
            }
        };
        
        // Makes a https request and sets the output with statusCode which 
        // will be displayed in task result page after execution
        const req = https.request(options, (res) => {
            context.setOutput("statusCode", res.statusCode);
        });
    
        req.on('error', (e) => {
            console.error(e);
        });
        req.write(slackPayload);
        req.end();
    
  6. Bevor Sie Ihr benutzerdefiniertes Integrationsskript mit einer Versionsangabe versehen und freigeben, laden Sie die Kontextdatei für Python oder Node.js herunter. Testen Sie dann die Geschäftslogik, die Sie in Ihr Skript aufgenommen haben.
    1. Positionieren Sie den Mauszeiger im Skript und klicken Sie danach oben auf der Arbeitsfläche auf die Schaltfläche für die Kontextdatei. Wenn Ihr Skript beispielsweise in Python programmiert ist, klicken Sie auf CONTEXT.PY.
    2. Ändern Sie die Datei und speichern Sie sie.
    3. Führen Sie auf Ihrem Entwicklungssystem Ihr benutzerdefiniertes Skript mithilfe der Kontextdatei aus und testen Sie es.
  7. Wenden Sie eine Version auf Ihr benutzerdefiniertes Integrationsskript an.
    1. Klicken Sie auf Version.
    2. Geben Sie die Versionsinformationen ein.
    3. Klicken Sie auf Version, damit Sie das Skript in Ihrer benutzerdefinierten Aufgabe auswählen können.
    4. Um die Version zu erstellen, klicken Sie auf Erstellen.
      Versionsverwaltung Ihres benutzerdefinierten Integrationsskripts.
  8. Zum Speichern des Skripts klicken Sie auf Speichern.
  9. Konfigurieren Sie den Arbeitsbereich in Ihrer Pipeline.
    1. Klicken Sie auf die Registerkarte Arbeitsumgebung.
    2. Wählen Sie den Docker-Host und die Builder-Image-URL aus.
      Erstellen einer benutzerdefinierten Integration.
  10. Fügen Sie Ihrer Pipeline eine benutzerdefinierte Aufgabe hinzu und konfigurieren Sie sie.
    1. Klicken Sie auf die Registerkarte Modell.
    2. Fügen Sie eine Aufgabe hinzu, wählen Sie als Typ Benutzerdefiniert aus und geben Sie einen entsprechenden Namen ein.
    3. Wählen Sie Ihr benutzerdefiniertes Integrationsskript und die Version aus.
    4. Um eine benutzerdefinierte Meldung in Slack anzuzeigen, geben Sie den Meldungstext ein.
      Jeder eingegebene Text überschreibt den defaultValue in Ihrem benutzerdefinierten Integrationsskript. Beispiel:
      Hinzufügen und Konfigurieren einer benutzerdefinierten Aufgabe in Ihrer Pipeline.
  11. Speichern und aktivieren Sie Ihre Pipeline.
    1. Klicken Sie auf Speichern.
    2. Klicken Sie auf der Registerkarte „Pipeline“ auf Pipeline aktivieren, damit der Kreis nach rechts verschoben wird.
  12. Führen Sie Ihre Pipeline aus.
    1. Klicken Sie auf Ausführen.
    2. Sehen Sie sich die Pipeline-Ausführung an.
    3. Bestätigen Sie, dass die Ausgabe den erwarteten Statuscode, den Antwortcode, den Status und die deklarierte Ausgabe enthält.
      Sie haben statusCode als Ausgabeeigenschaft definiert. Beispiel: Ein statusCode von 200 deutet möglicherweise auf einen erfolgreichen Slack-Beitrag hin, und ein responseCode von 0 gibt möglicherweise an, dass das Skript ohne Fehler erfolgreich war.
    4. Um die Ausgabe in den Ausführungsprotokollen zu bestätigen, klicken Sie auf Ausführungen, klicken Sie auf den Link zu Ihrer Pipeline, klicken Sie auf die Aufgabe und sehen Sie sich die protokollierten Daten an. Beispiel:
      Anzeigen der Aufgabenausgabe für die benutzerdefinierte Integration.
  13. Wenn ein Fehler auftritt, beheben Sie das Problem und führen Sie die Pipeline erneut aus.
    Wenn beispielsweise eine Datei oder ein Modul im Basis-Image fehlt, müssen Sie ein weiteres Basis-Image erstellen, das die fehlende Datei enthält. Geben Sie dann die Docker-Datei an und übertragen Sie das Image über die Pipeline.

Ergebnisse

Herzlichen Glückwunsch! Sie haben ein benutzerdefiniertes Integrationsskript erstellt, das Code Stream mit Ihrer Slack-Instanz verbindet und eine Nachricht an einen Slack-Kanal sendet.

Nächste Maßnahme

Erstellen Sie weiterhin benutzerdefinierte Integrationen, um die Verwendung benutzerdefinierter Aufgaben in Ihren Pipelines zu unterstützen, sodass Sie die Funktion von Code Stream in der Automatisierung des Lebenszyklus Ihrer Softwareversion erweitern können.