Einführung
Ein Mitwirkender schlägt eine Codeänderung mit Titel und Beschreibung vor. Ein Build-Auftrag erzeugt daraus ein Vorschauartefakt. Continuous Integration (CI) bedeutet, solche Aufträge bei eingehenden Änderungen automatisch auszuführen. Ein Runner ist das ausführende Programm. Hier startest du selbst einen vorbereiteten kleinen lokalen Runner.
Alle Personen und Ereignisse sind synthetisch. Der Runner führt echte Bash in einem temporären Container ohne Netzwerk und Deployment-Zugangsdaten aus. production in release.conf ist ein lokaler Testwert und löst keine Bereitstellung aus. Der Workshop bildet Textersetzung und Shell-Ausführung ab, nicht Auslöser oder Berechtigungen einer gehosteten CI-Plattform. CI Workshop ist dein Wartungsterminal; Topology erklärt den Ablauf und zeigt nach dem Aktualisieren die tatsächlichen Kanäle.
Du führst einen normalen Build aus, verfolgst eine Skript-Injection, bearbeitest zwei kurze Dateien und prüfst die exakte Verarbeitung der Metadaten. Grundlegende Terminalkenntnisse reichen; erforderliches JSON und Bash-Syntax werden vor der Verwendung erklärt.
Einen normalen Build ausführen
In diesem Schritt lernst du zunächst das erwartete Ergebnis kennen: Der vollständige Titel wird zum Artefakt, der Veröffentlichungskanal bleibt preview.
Wähle zu Beginn dieses Schritts den Tab CI Workshop in der Lab-Oberfläche aus.
Wechsle zum Tab CI Workshop. pwd zeigt das aktuelle Verzeichnis, ls listet seine Dateien. Der Arbeitsbereich ist /home/labex/project/ci-workshop.
Wechsle zum Tab CI Workshop, bevor du den folgenden Befehl ausführst.
pwd
ls
cat zeigt eine Textdatei an. Ein JSON-Objekt umschließt benannte Felder mit geschweiften Klammern; ein Doppelpunkt verbindet Namen und Wert. Zeichenketten verwenden doppelte Anführungszeichen. Darin steht \n für einen Zeilenumbruch. Lies das normale Ereignis:
cat events/ordinary.json
Sein title ist Improve search results. body enthält eine mehrzeilige Beschreibung. Diese Werte stammen von einem Mitwirkenden und sind Daten; der Build darf sie nicht als vertrauenswürdige Befehle behandeln.
Lies die kurze Auftragsdefinition und ihr Skript:
cat job.json
cat build.sh
| Element | Bedeutung im lokalen Runner |
|---|---|
script |
Auszuführende Bash-Datei, derzeit build.sh |
env |
Zuordnung von Umgebungsnamen zu Zeichenketten, derzeit leer {} |
{{event.title}} |
Diesen genauen Platzhalter vor dem Bash-Start durch den Titel ersetzen |
{{event.body}} |
Gleiche Ersetzung für die Beschreibung |
artifact.txt |
Vom Build erzeugte Metadatendatei |
release.conf |
Pro Durchlauf mit preview initialisierter Kanal |
Bash liest Shell-Anweisungen. TITLE="..." weist einer Variablen einen Wert zu; um = dürfen keine Leerzeichen stehen. "$TITLE" expandiert sie als ein Argument und erhält Leerzeichen sowie Zeilenumbrüche. printf '%s' schreibt eine Zeichenkette ohne zusätzlichen Umbruch; einfache Anführungszeichen halten %s wörtlich. > leitet die Ausgabe in eine Datei um und ersetzt deren Inhalt. Das Semikolon trennt Befehle. set -euo pipefail beendet das Skript bei typischen Befehlsfehlern, undefinierten Variablen und Pipelinefehlern; Injection verhindert es nicht.
ci ist der vorbereitete Runner-Befehl. run erwartet einen Ereignisnamen ohne .json sowie einen neuen Ausgabeverzeichnisnamen. Jeder Durchlauf beginnt mit einer neuen preview-Konfiguration:
ci run ordinary first
Erwartet werden channel=preview und exit=0. Null bedeutet, dass Bash erfolgreich endete. Prüfe erzeugtes Skript, Artefakt und Konfiguration mit show:
ci show first
Das Artefakt erscheint als JSON-Zeichenkette "Improve search results", damit später unsichtbare Umbrüche dargestellt werden können. Das ist echter Dateiinhalt, kein simulierter Erfolgsstatus. Der letzte Abschnitt muss preview zeigen. Wechsle zum Tab Topology und aktualisiere die Seite: Die Zeile first liest dieselbe Konfigurationsdatei.
Ein erneuter Aufruf von run mit first meldet absichtlich ein vorhandenes Verzeichnis, damit alte Belege erhalten bleiben. Wähle etwa first-again. Auch fehlgeschlagene Builds behalten das erzeugte Skript und build.log unter runs/NAME zur Diagnose.
Die gefährliche Ersetzung verfolgen
In diesem Schritt siehst du, wie Daten zu ausführbarem Code werden und in einem isolierten Demolauf den Kanal ändern.
Wähle zu Beginn dieses Schritts den Tab CI Workshop in der Lab-Oberfläche aus.
Der Ablauf lautet Ereignis → Auftrag → erzeugter Shell-Quelltext → Bash → Artefakt. Gefährlich ist die Ersetzung vor der Interpretation der Anführungszeichen durch Bash. Doppelte Anführungszeichen schützen Variablenexpansion in einem bereits analysierten Befehl, aber keinen Rohwert, der zuvor in den Quelltext eingefügt wird.
Lies das bereitgestellte harmlose Demoereignis:
Wechsle zum Tab CI Workshop, bevor du den folgenden Befehl ausführst.
cat events/hostile.json
Der title enthält ein doppeltes Anführungszeichen, Semikolon, printf, weiteres Semikolon und #. In Bash beendet das Anführungszeichen die ursprüngliche Zeichenkette, das Semikolon beginnt einen Befehl und # kommentiert den Rest der Zeile aus. Das printf verändert nur die synthetische release.conf dieses Laufs. JSONs \" codiert ein Anführungszeichen; beim späteren Einfügen in Shell-Code wird es dadurch nicht sicher.
Führe das Ereignis in einem neuen Arbeitsbereich aus:
ci run hostile demo
ci show demo
Erwarte channel=production, obwohl der Runner mit preview begann. Suche das eingefügte printf zwischen den Semikolons in generated.sh: Bash hat es tatsächlich ausgeführt. Das Artefakt enthält möglicherweise nur Update, weil der Rest zu Syntax statt Titeldaten wurde. Diesen Fehler wirst du beheben.
demo ist von first getrennt; beide verändern weder job.json noch build.sh. Wechsle zum Tab Topology und aktualisiere die Seite, um die tatsächlichen Kanäle zu vergleichen. production bedeutet hier eine veränderte Testdatei, niemals eine echte Veröffentlichung. Führe den Ereignistext nicht selbst in deiner Wartungsshell aus.

Das allgemeine Risiko beschreibt GitHubs Erklärung zu Skript-Injections. Unsere Platzhalter und das Auftragsformat sind bewusst kleiner als GitHub Actions; gemeinsam ist der Mechanismus „Ersetzung vor Interpretation“.
Den Wert als Daten übergeben
In diesem Schritt hältst du Beitragstext aus dem Shell-Quelltext heraus und erhältst Leerzeichen, Anführungszeichen und mehrere Zeilen.
Wähle zu Beginn dieses Schritts den Tab CI Workshop in der Lab-Oberfläche aus.
Eine Umgebungsvariable ist eine benannte Zeichenkette für einen neuen Prozess. Die Zuordnung env setzt sie direkt, ohne eine Shell-Zuweisung zu erzeugen. In JSON ist eine Zuordnung ein weiteres Objekt in geschweiften Klammern. Setze BUILD_TITLE aus {{event.title}} und lasse Bash erst zur Laufzeit "$BUILD_TITLE" expandieren. Anführungszeichen, Semikolons, $() und Backticks in diesem Wert werden nicht erneut als Befehle interpretiert. Verwende weder eval noch bash -c mit dem Wert: Das würde ihn erneut parsen.
Wir ersetzen zwei kurze Dateien mit Here-Dokumenten. cat > filename <<'JSON' schreibt folgende Zeilen bis zu einer Zeile, die nur JSON enthält. Der zitierte Begrenzer verhindert, dass deine Wartungsshell $ oder andere Syntax expandiert. Kopiere den ganzen Block einschließlich der letzten Begrenzerzeile. Er ersetzt die ganze Datei und eignet sich auch zur Korrektur von Tippfehlern.
Wechsle zum Tab CI Workshop, bevor du den folgenden Befehl ausführst.
cat > job.json <<'JSON'
{
"script": "build.sh",
"env": {
"BUILD_TITLE": "{{event.title}}"
}
}
JSON
Ersetze nun das Skript. BASH erfüllt denselben Zweck der wörtlichen Eingabe. Das Skript verwendet direkt die Umgebungsvariable und enthält keinen Beitragsplatzhalter mehr.
cat > build.sh <<'BASH'
set -euo pipefail
printf '%s' "$BUILD_TITLE" > artifact.txt
printf 'channel='; cat release.conf
BASH
Lies beide Dateien mit dem bekannten cat zurück. Ein fehlendes Komma oder eine Klammer führt zu JSON-Fehlern, ein falscher Umgebungsname zu einer undefinierten Variable. Schreibe den betroffenen Block vollständig neu und versuche es erneut. Alte Läufe gehören zum alten Skript; verwende einen neuen Namen:
ci run ordinary repaired
ci show repaired
Der erzeugte Quelltext enthält nun "$BUILD_TITLE" statt der Titelzeichen. Das Artefakt bleibt Improve search results, der Kanal preview.
Lies vor dem Test die Satzzeichen- und Mehrzeilenfälle:
cat events/quotes.json
cat events/multiline.json
\n in JSON steht für einen echten Zeilenumbruch; auch der letzte \n muss erhalten bleiben. Der Apostroph in O'Brien und Anführungszeichen im Titel sind legitime Daten. Dieselbe Zuordnung übergibt einen mehrzeiligen body: Die Referenz wird {{event.body}}, die Regel zur zitierten Variablen bleibt gleich. Das verwendest du in der Challenge für Versionshinweise.
ci test normal führt deinen unveränderten Auftrag und dein Skript mit normalen, Satzzeichen- und Mehrzeilenereignissen in temporären Verzeichnissen aus. Es vergleicht exakte Bytes und prüft preview. Nur die temporären Verzeichnisse werden entfernt, nicht deine Dateien oder gespeicherten Läufe.
ci test normal
Pro Fall muss exact metadata; channel=preview erscheinen. Satzzeichen entfernen, Zeilen zusammenziehen, einen Titel fest eintragen, alle Ereignisse ablehnen oder den Build überspringen besteht diesen Funktionstest nicht. Fehler nennen den Testfall: Lies ihn und korrigiere beide Dateien vor dem nächsten Versuch.
Die Build-Grenze erneut testen
In diesem Schritt bestätigst du, dass derselbe reparierte Auftrag normale Metadaten erhält und den gezeigten Nebeneffekt verhindert.
Wähle zu Beginn dieses Schritts den Tab CI Workshop in der Lab-Oberfläche aus.
Führe den feindlichen Fall erneut mit einem neuen Ausgabenamen aus:
Wechsle zum Tab CI Workshop, bevor du den folgenden Befehl ausführst.
ci run hostile repaired-hostile
ci show repaired-hostile
Das Artefakt muss nun den gesamten feindlichen Titel als Text enthalten. Semikolons und Anführungszeichen sind in der JSON-Darstellung sichtbar, release.conf bleibt preview. Der alte demo bleibt unverändert, da er zu einem anderen Arbeitsbereich gehört.
Ein weiterer Fall enthält $() und Backticks. Im Shell-Quelltext sind das Formen der Befehlsersetzung. Innerhalb eines in doppelten Anführungszeichen expandierten Umgebungswerts bleiben die Zeichen Daten. Lies den Fall:
cat events/substitution.json
Teste alle fünf Fälle mit denselben eingereichten Dateien:
ci test all
ordinary, quotes, multiline, hostile und substitution müssen exakte Metadaten und preview erhalten; anschließend erscheint die Bereinigungsmeldung. Geprüft werden echte Bash-Ausführung und Ausgabedateien, keine Protokollphrase oder erfundene Angabe secure=true. Die Abschlussprüfung wiederholt diese temporären Tests, ohne Auftrag, Skript oder gespeicherte Läufe zu verändern.
Scheitert nur der feindliche Fall, suche nach verbleibenden Ereignisplatzhaltern in der Shell-Datei oder erneutem Parsen der Variablen. Scheitern Satzzeichen oder mehrere Zeilen, prüfe printf '%s' mit einer doppelt zitierten Variablen. Lösche keine schwierigen Eingaben: Legitime Metadaten zu erhalten gehört zum Ziel. Wechsle zum Tab Topology und aktualisiere die Seite, um den Lauf repaired-hostile neben dem historischen demo zu sehen.

Zusammenfassung
Du hast Metadaten über einen lokalen Runner bis in echte Bash verfolgt, eine isolierte Konfigurationsänderung reproduziert und die Datengrenze mit Umgebungszuordnung und zitierter Expansion repariert. Exakte Tests erhielten Satzzeichen, mehrere Zeilen und den Vorschaukanal. Übertrage die Methode nun auf Versionshinweise.



