{"id":1215,"date":"2022-01-19T08:40:03","date_gmt":"2022-01-19T07:40:03","guid":{"rendered":"https:\/\/informatik.htwk-leipzig.de\/seminar\/?p=1215"},"modified":"2022-01-23T16:54:58","modified_gmt":"2022-01-23T15:54:58","slug":"gitlab-ci-cd-und-pages","status":"publish","type":"post","link":"https:\/\/informatik.htwk-leipzig.de\/seminar\/lehrveranstaltungen\/betriebliche-informationssysteme\/2022\/gitlab-ci-cd-und-pages\/","title":{"rendered":"GitLab CI\/CD und Pages"},"content":{"rendered":"<h1>GitLabs <b>Continuous Methodologies<\/b><\/h1>\n<h2>Inhaltsverzeichnis<\/h2>\n<ul>\n<li>Allgemeines<\/li>\n<li>Workflow<\/li>\n<li>GitLab CI\/CD\n<ul>\n<li>GitLab Pipelines<\/li>\n<li>GitLab Stages<\/li>\n<li>GitLab Jobs<\/li>\n<\/ul>\n<\/li>\n<li>GitLab Pages<\/li>\n<li>Quellen<\/li>\n<\/ul>\n<h2>Allgemeines<\/h2>\n<p>Die Akronyme CI und CD stehen f\u00fcr:<\/p>\n<ul>\n<li><strong><b>Continuous <\/b>Integration<\/strong><\/li>\n<li><strong><b>Continuous <\/b>Delivery<\/strong><\/li>\n<li><strong><b>Continuous <\/b>Deployment<\/strong><\/li>\n<\/ul>\n<p><strong><b>Continuous <\/b>Integration<\/strong> ist eine Technik innerhalb der agilen Softwareentwicklung, um koh\u00e4rente Software schneller zu entwickeln. Dahinter verbirgt sich die Idee, dass Teammitglieder ihre entwickelten Features regelm\u00e4\u00dfig integrieren und diese Integration durch ein automatisches Bauen und Testen der Software verifiziert wird. Das Ziel dabei ist es, Integrationsfehler schneller und fr\u00fchzeitiger zu identifizieren und somit die Integration von koh\u00e4renter Software zu einem <em>non-event<\/em> zu machen.<\/p>\n<p><strong><b>Continuous <\/b>Delivery <\/strong>ist eine Technik innerhalb der agilen Softwareentwicklung, die darauf abzielt, Software nach bestimmten Prinzipien zu entwickeln, sodass diese zu jedem Zeitpunkt released werden kann. Das Ziel dabei ist es, auf Kundenanfragen jederzeit den aktuellen Entwicklungsstand releasen zu k\u00f6nnen, ohne dass weitere Entwicklungsschritte vorgenommen werden m\u00fcssen. Wichtig dabei ist, dass die Produktionsbuilds nicht automatisiert ver\u00f6ffentlicht werden, sondern lediglich vorhanden sind.<\/p>\n<p><strong>Continuous Deployment <\/strong>ist eine Technik innerhalb der agilen Softwareentwicklung, die auf Continuous Integration und Continuous Delivery basiert und zus\u00e4tzlich jede \u00c4nderung an der Software nach erfolgreichem Durchlaufen der Produktions-Pipeline als neustes Produktionsbuild ver\u00f6ffentlicht.<\/p>\n<p>Daraus l\u00e4sst sich folgende Hierarchie der Begriffe ableiten:<\/p>\n<p>Continuous Integration &lt; Continuous Delivery &lt; Continuous Deployment<\/p>\n<h2><strong>Workflow<\/strong><a href=\"https:\/\/www.atlassian.com\/de\/continuous-delivery\/principles\/continuous-integration-vs-delivery-vs-deployment\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-1245 size-full\" src=\"https:\/\/informatik.htwk-leipzig.de\/seminar\/wp-content\/uploads\/2022\/01\/ci-cd-asset-updates-.007.png\" alt=\"Workflow CI\/CD\" width=\"1920\" height=\"1080\" \/><\/a><\/h2>\n<h2>GitLab CI\/CD<\/h2>\n<p>GitLab pr\u00e4sentiert einige Tools, um die oben beschriebenen kontinuierlichem Methoden abzubilden. GitLab erm\u00f6glicht dabei mit den sogenannten GitLab Runnern Jobs innerhalb einer Pipeline laufen zu lassen und somit automatisiert die eigene Software zu bauen, zu testen, zu deployen und zu \u00fcberwachen. Die Runner k\u00f6nnen entweder, wie GitLab, selbst gehostet und zur Verf\u00fcgung gestellt werden oder es werden auf sogenannte Shared Runners zur\u00fcckgegriffen, die allen Nutzern von GitLab zur Verf\u00fcgung stehen.<\/p>\n<p>Kernelemente dieser Tools sind innerhalb von GitLab Pipelines, Stages, Jobs und die GitLab Pages.<\/p>\n<p>Um die Kernelemente und Tools zu verwalten und zu konfigurieren, verwendet GitLab eine YAML-File, die den Namen <em>.gitlab-ci.yaml<\/em> erhalten muss. Innerhalb dieser Konfigurationsdatei kann festgelegt werden, welche Struktur und Jobs eine Pipeline aufweist. Dabei k\u00f6nnen vordefinierte Variablen verwendet und Entscheidungen, die der GitLab Runner bei bestimmten Bedingungen treffen soll, spezifiziert werden.<\/p>\n<h3>GitLab Pipelines<\/h3>\n<p>Pipelines bilden die Top-Level Komponente und bestehen aus Stages und Jobs. Pipelines k\u00f6nnen dabei verschiedenen Status haben. Sie sind entweder pending (ausstehend), running (laufend), done (fertig, erfolgreich) oder failed (fehlgeschlagen). Dabei weist eine Pipeline granular betrachtet folgende Verhaltensweisen auf: Wenn alle Jobs innerhalb einer Stage erfolgreich sind, geht der Runner innerhalb der Pipeline zur n\u00e4chsten Stage \u00fcber, solange bis alle Stages abgeschlossen sind. Wenn irgendein Job fehlschl\u00e4gt, so wird die Pipeline angehalten und die gesamte Pipeline als fehlgeschlagen betrachtet. Der Zustand pending ist der initiale Startzustand der solange gilt, bis ein GitLab Runner mit der Bearbeitung der Pipeline angefangen hat.<\/p>\n<h3>GitLab Stages<\/h3>\n<p>Stages dienen zur Gruppierung von Jobs und beschreiben innerhalb einer Pipeline eine sequentielle Aus\u00fcbung dieser Jobs. Sie definieren ebenso innerhalb einer Pipeline gewisse Phasen.<br \/>\nJobs laufen dabei, falls gen\u00fcgend GitLab Runner zur Verf\u00fcgung stehen, parallel ab. Mit der Hilfe von Stages k\u00f6nnen in der Konfigurationsdatei Abh\u00e4ngigkeiten innerhalb der Pipeline spezifiziert und somit einen gerichteten, azyklischen Graphen (DAG) aufgebaut werden. Stages k\u00f6nnen mithilfe des <code>stages<\/code><em>&#8211;<\/em>Keyword definiert werden.<\/p>\n<h3>GitLab Jobs<\/h3>\n<p>Jobs bilden die atomaren Bestandteile einer Pipeline und definieren die Aktionen, die vom GitLab Runner ausgef\u00fchrt werden sollen (keyword <code>scripts<\/code>). Die Aktionen sind dabei Kommandozeilenbefehle. Wie bereits erw\u00e4hnt, k\u00f6nnen diese zu Stages gruppiert werden (keyword <code>stage<\/code>). Ebenfalls k\u00f6nnen f\u00fcr jeden Job Bedingungen spezifiziert werden, wann dieser Job ausgef\u00fchrt werden soll (keywords <code>except\/only<\/code>). Oft wird dies auf den Namen des Branches reduziert, das bedeutet, ein Job l\u00e4uft nur dann, wenn ein Commit auf den jeweils spezifizierten Namen ausgef\u00fchrt wird. Entstehende Dateien innerhalb eines Jobs und einer Stage k\u00f6nnen gespeichert und so dem Entwickler per Download und automatisiert der n\u00e4chsten Stage zur Verf\u00fcgung gestellt werden (keyword <code>artifacts<\/code>).\u00a0 Daf\u00fcr muss angegeben werden, welche Dateipfade zu den Artefakten gez\u00e4hlt werden (keyword <code>paths<\/code>). Ebenso kann spezififziert werden, wann und wie lange Artefakte hochgeladen werden sollen (keywords <code>expire_in<\/code> und <code>when<\/code>).<\/p>\n<h2><img loading=\"lazy\" decoding=\"async\" class=\" wp-image-1261 aligncenter\" src=\"https:\/\/informatik.htwk-leipzig.de\/seminar\/wp-content\/uploads\/2022\/01\/workflow_gitlab_ci.drawio-1.png\" alt=\"\" width=\"1294\" height=\"429\" \/><\/h2>\n<h2>GitLab Pages<\/h2>\n<p>GitLab Pages ist ein weiteres Tool von GitLab, welches Nutzern erm\u00f6glicht, statische Webseiten mithilfe der GitLab CI\/CD Pipeline zu publizieren. Somit wird ein kostenloses Publizieren direkt vom eigenen Repository aus m\u00f6glich. Ein Nachteil stellt jedoch die Einschr\u00e4nkung dar, dass lediglich per Static Site Generator erzeugte oder in plain HTML\/JavaScript geschriebene Webseiten ver\u00f6ffentlicht werden k\u00f6nnen. Daraus resultiert, dass keine komplexen Web-Applikationen, die auf ein Back-End und Datenbanken zur\u00fcckgreifen, per GitLab Pages publiziert werden k\u00f6nnen.<\/p>\n<p>Abgesehen von diesem Nachteil ist es m\u00f6glich, die eigene Webseite unter der Dom\u00e4ne <em>*.gitlab.io <\/em>oder einer eigenen Dom\u00e4ne, falls vorhanden, zu deployen. Wird die Dom\u00e4ne von GitLab verwendet, so wird automatisch aus dem Benutzernamen die Dom\u00e4ne generiert (<code>&lt;benutzername&gt;.gitlab.io<\/code>). Zur Ver\u00f6ffentlichung greift GitLab Pages auf die Konfigurationsdatei <em>.gitlab-ci.yml<\/em> zur\u00fcck, in der ein Job namens <code>pages<\/code> spezifiziert werden muss. Somit erkennt GitLab, dass die Dateien im Repository ver\u00f6ffentlicht werden sollen und kopiert alle Dateien <em>innerhalb des public<\/em>-Ordners auf den GitLab Pages Server. Die Webseite wird bei der GitLab Dom\u00e4ne dabei automatisch verschl\u00fcsselt und per HTTPS ausgeliefert.<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p><a href=\"https:\/\/docs.gitlab.com\/ee\/user\/project\/pages\/\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-1290 aligncenter\" src=\"https:\/\/informatik.htwk-leipzig.de\/seminar\/wp-content\/uploads\/2022\/01\/new_project_for_pages_v12_5.png\" alt=\"GitLab Pages Workflow\" width=\"794\" height=\"617\" \/><\/a><\/p>\n<p><!--more--><\/p>\n<p>&nbsp;<\/p>\n<h2>GitLab CI\/CD Konfigurationsdatei<\/h2>\n<details>\n<summary style=\"cursor: pointer\">\u2023 Click to expand<\/summary>\n<p><code><\/code><\/p>\n<pre class=\"code highlight\"><span id=\"LC1\" class=\"line\" lang=\"yaml\"><span class=\"na\">image<\/span><span class=\"pi\">:<\/span> <span class=\"s\">node:17 # defines the docker image<\/span><\/span>\r\n<span id=\"LC2\" class=\"line\" lang=\"yaml\"><\/span>\r\n<span id=\"LC3\" class=\"line\" lang=\"yaml\"><span class=\"na\">stages<\/span><span class=\"pi\">:<\/span> <span class=\"c1\"># stages of pipeline<\/span><\/span>\r\n<span id=\"LC4\" class=\"line\" lang=\"yaml\">  <span class=\"pi\">-<\/span> <span class=\"s\">build<\/span><\/span>\r\n<span id=\"LC5\" class=\"line\" lang=\"yaml\">  <span class=\"pi\">-<\/span> <span class=\"s\">test<\/span><\/span>\r\n<span id=\"LC6\" class=\"line\" lang=\"yaml\">  <span class=\"pi\">-<\/span> <span class=\"s\">deploy<\/span><\/span>\r\n<span id=\"LC7\" class=\"line\" lang=\"yaml\">  <span class=\"pi\">-<\/span> <span class=\"s\">cleanup<\/span><\/span>\r\n<span id=\"LC8\" class=\"line\" lang=\"yaml\"><\/span>\r\n<span id=\"LC9\" class=\"line\" lang=\"yaml\"><span class=\"na\">build-component-library<\/span><span class=\"pi\">:<\/span> <span class=\"c1\"># first job<\/span><\/span>\r\n<span id=\"LC10\" class=\"line\" lang=\"yaml\">  <span class=\"na\">stage<\/span><span class=\"pi\">:<\/span> <span class=\"s\">build<\/span> <span class=\"c1\"># in stage build<\/span><\/span>\r\n<span id=\"LC11\" class=\"line\" lang=\"yaml\">  <span class=\"na\">tags<\/span><span class=\"pi\">:<\/span> <span class=\"c1\"># set specific gitlab runner<\/span><\/span>\r\n<span id=\"LC12\" class=\"line\" lang=\"yaml\">    <span class=\"pi\">-<\/span> <span class=\"s\">docker<\/span><\/span>\r\n<span id=\"LC13\" class=\"line\" lang=\"yaml\">  <span class=\"na\">artifacts<\/span><span class=\"pi\">:<\/span> <span class=\"c1\"># files that should be saved<\/span><\/span>\r\n<span id=\"LC14\" class=\"line\" lang=\"yaml\">    <span class=\"na\">paths<\/span><span class=\"pi\">:<\/span> <span class=\"c1\"># path of files<\/span><\/span>\r\n<span id=\"LC15\" class=\"line\" lang=\"yaml\">      <span class=\"pi\">-<\/span> <span class=\"s\">dist<\/span><\/span>\r\n<span id=\"LC16\" class=\"line\" lang=\"yaml\">      <span class=\"pi\">-<\/span> <span class=\"s\">node_modules<\/span><\/span>\r\n<span id=\"LC17\" class=\"line\" lang=\"yaml\">  <span class=\"na\">script<\/span><span class=\"pi\">:<\/span> <span class=\"c1\"># scripts to execute<\/span><\/span>\r\n<span id=\"LC18\" class=\"line\" lang=\"yaml\">    <span class=\"pi\">-<\/span> <span class=\"s\">.\/bin\/check-package-lock.sh<\/span><\/span>\r\n<span id=\"LC19\" class=\"line\" lang=\"yaml\">    <span class=\"pi\">-<\/span> <span class=\"s\">npm run init<\/span><\/span>\r\n<span id=\"LC20\" class=\"line\" lang=\"yaml\">    <span class=\"pi\">-<\/span> <span class=\"s\">npm run build<\/span><\/span>\r\n<span id=\"LC21\" class=\"line\" lang=\"yaml\">  <span class=\"na\">except<\/span><span class=\"pi\">:<\/span> <span class=\"c1\"># control when jobs are added to pipeline -&gt; except when it should not run<\/span><\/span>\r\n<span id=\"LC22\" class=\"line\" lang=\"yaml\">    <span class=\"pi\">-<\/span> <span class=\"s\">triggers<\/span> <span class=\"c1\"># when pipeline is triggered by an api endpoint<\/span><\/span>\r\n<span id=\"LC23\" class=\"line\" lang=\"yaml\"><\/span>\r\n<span id=\"LC24\" class=\"line\" lang=\"yaml\"><span class=\"na\">lint<\/span><span class=\"pi\">:<\/span><\/span>\r\n<span id=\"LC25\" class=\"line\" lang=\"yaml\">  <span class=\"na\">stage<\/span><span class=\"pi\">:<\/span> <span class=\"s\">test<\/span><\/span>\r\n<span id=\"LC26\" class=\"line\" lang=\"yaml\">  <span class=\"na\">tags<\/span><span class=\"pi\">:<\/span><\/span>\r\n<span id=\"LC27\" class=\"line\" lang=\"yaml\">    <span class=\"pi\">-<\/span> <span class=\"s\">docker<\/span><\/span>\r\n<span id=\"LC28\" class=\"line\" lang=\"yaml\">  <span class=\"na\">script<\/span><span class=\"pi\">:<\/span><\/span>\r\n<span id=\"LC29\" class=\"line\" lang=\"yaml\">    <span class=\"pi\">-<\/span> <span class=\"s\">npm run prettier:check<\/span><\/span>\r\n<span id=\"LC30\" class=\"line\" lang=\"yaml\">    <span class=\"pi\">-<\/span> <span class=\"s\">npm run lint<\/span><\/span>\r\n<span id=\"LC31\" class=\"line\" lang=\"yaml\">  <span class=\"na\">except<\/span><span class=\"pi\">:<\/span><\/span>\r\n<span id=\"LC32\" class=\"line\" lang=\"yaml\">    <span class=\"pi\">-<\/span> <span class=\"s\">triggers<\/span><\/span>\r\n<span id=\"LC33\" class=\"line\" lang=\"yaml\"><\/span>\r\n<span id=\"LC34\" class=\"line\" lang=\"yaml\"><span class=\"na\">unit-test<\/span><span class=\"pi\">:<\/span><\/span>\r\n<span id=\"LC35\" class=\"line\" lang=\"yaml\">  <span class=\"na\">stage<\/span><span class=\"pi\">:<\/span> <span class=\"s\">test<\/span><\/span>\r\n<span id=\"LC36\" class=\"line\" lang=\"yaml\">  <span class=\"na\">tags<\/span><span class=\"pi\">:<\/span><\/span>\r\n<span id=\"LC37\" class=\"line\" lang=\"yaml\">    <span class=\"pi\">-<\/span> <span class=\"s\">docker<\/span><\/span>\r\n<span id=\"LC38\" class=\"line\" lang=\"yaml\">  <span class=\"na\">script<\/span><span class=\"pi\">:<\/span><\/span>\r\n<span id=\"LC39\" class=\"line\" lang=\"yaml\">    <span class=\"pi\">-<\/span> <span class=\"s\">npm run test<\/span><\/span>\r\n<span id=\"LC40\" class=\"line\" lang=\"yaml\">  <span class=\"na\">except<\/span><span class=\"pi\">:<\/span><\/span>\r\n<span id=\"LC41\" class=\"line\" lang=\"yaml\">    <span class=\"pi\">-<\/span> <span class=\"s\">triggers<\/span><\/span>\r\n<span id=\"LC42\" class=\"line\" lang=\"yaml\"><\/span>\r\n<span id=\"LC43\" class=\"line\" lang=\"yaml\"><span class=\"na\">integration-test<\/span><span class=\"pi\">:<\/span><\/span>\r\n<span id=\"LC44\" class=\"line\" lang=\"yaml\">  <span class=\"na\">stage<\/span><span class=\"pi\">:<\/span> <span class=\"s\">test<\/span><\/span>\r\n<span id=\"LC45\" class=\"line\" lang=\"yaml\">  <span class=\"na\">tags<\/span><span class=\"pi\">:<\/span><\/span>\r\n<span id=\"LC46\" class=\"line\" lang=\"yaml\">    <span class=\"pi\">-<\/span> <span class=\"s\">docker<\/span><\/span>\r\n<span id=\"LC47\" class=\"line\" lang=\"yaml\">  <span class=\"na\">script<\/span><span class=\"pi\">:<\/span><\/span>\r\n<span id=\"LC48\" class=\"line\" lang=\"yaml\">    <span class=\"pi\">-<\/span> <span class=\"s\">npm run integration-test<\/span><\/span>\r\n<span id=\"LC49\" class=\"line\" lang=\"yaml\">  <span class=\"na\">artifacts<\/span><span class=\"pi\">:<\/span> <span class=\"c1\"># files that should be saved<\/span><\/span>\r\n<span id=\"LC50\" class=\"line\" lang=\"yaml\">    <span class=\"na\">paths<\/span><span class=\"pi\">:<\/span> <span class=\"c1\"># path of files<\/span><\/span>\r\n<span id=\"LC51\" class=\"line\" lang=\"yaml\">      <span class=\"pi\">-<\/span> <span class=\"s\">e2e\/report<\/span><\/span>\r\n<span id=\"LC52\" class=\"line\" lang=\"yaml\">    <span class=\"na\">expire_in<\/span><span class=\"pi\">:<\/span> <span class=\"s\">1 week<\/span> <span class=\"c1\"># expire after 1 week<\/span><\/span>\r\n<span id=\"LC53\" class=\"line\" lang=\"yaml\">    <span class=\"na\">when<\/span><span class=\"pi\">:<\/span> <span class=\"s\">always<\/span> <span class=\"c1\"># upload nomatter if the job fails or not (on_success, on_failure)<\/span><\/span>\r\n<span id=\"LC54\" class=\"line\" lang=\"yaml\">  <span class=\"na\">except<\/span><span class=\"pi\">:<\/span><\/span>\r\n<span id=\"LC55\" class=\"line\" lang=\"yaml\">    <span class=\"pi\">-<\/span> <span class=\"s\">triggers<\/span><\/span>\r\n<span id=\"LC56\" class=\"line\" lang=\"yaml\"><\/span>\r\n<span id=\"LC57\" class=\"line\" lang=\"yaml\"><span class=\"na\">pages<\/span><span class=\"pi\">:<\/span><\/span>\r\n<span id=\"LC58\" class=\"line\" lang=\"yaml\">  <span class=\"na\">stage<\/span><span class=\"pi\">:<\/span> <span class=\"s\">deploy<\/span><\/span>\r\n<span id=\"LC59\" class=\"line\" lang=\"yaml\">  <span class=\"na\">tags<\/span><span class=\"pi\">:<\/span><\/span>\r\n<span id=\"LC60\" class=\"line\" lang=\"yaml\">    <span class=\"pi\">-<\/span> <span class=\"s\">docker<\/span><\/span>\r\n<span id=\"LC61\" class=\"line\" lang=\"yaml\">  <span class=\"na\">artifacts<\/span><span class=\"pi\">:<\/span><\/span>\r\n<span id=\"LC62\" class=\"line\" lang=\"yaml\">    <span class=\"na\">paths<\/span><span class=\"pi\">:<\/span><\/span>\r\n<span id=\"LC63\" class=\"line\" lang=\"yaml\">      <span class=\"pi\">-<\/span> <span class=\"s\">public<\/span><\/span>\r\n<span id=\"LC64\" class=\"line\" lang=\"yaml\">  <span class=\"na\">script<\/span><span class=\"pi\">:<\/span><\/span>\r\n<span id=\"LC65\" class=\"line\" lang=\"yaml\">    <span class=\"pi\">-<\/span> <span class=\"s\">npm run convert-readme-to-html<\/span><\/span>\r\n<span id=\"LC66\" class=\"line\" lang=\"yaml\">    <span class=\"pi\">-<\/span> <span class=\"s\">npm run build<\/span><\/span>\r\n<span id=\"LC67\" class=\"line\" lang=\"yaml\">    <span class=\"pi\">-<\/span> <span class=\"s\">mkdir -p public<\/span><\/span>\r\n<span id=\"LC68\" class=\"line\" lang=\"yaml\">    <span class=\"pi\">-<\/span> <span class=\"s\">mv dist\/* public\/<\/span><\/span>\r\n<span id=\"LC69\" class=\"line\" lang=\"yaml\">  <span class=\"na\">except<\/span><span class=\"pi\">:<\/span><\/span>\r\n<span id=\"LC70\" class=\"line\" lang=\"yaml\">    <span class=\"pi\">-<\/span> <span class=\"s\">triggers<\/span><\/span>\r\n<span id=\"LC71\" class=\"line\" lang=\"yaml\">  <span class=\"na\">only<\/span><span class=\"pi\">:<\/span> <span class=\"c1\"># control when jobs are added to pipeline -&gt; only when it should run<\/span><\/span>\r\n<span id=\"LC72\" class=\"line\" lang=\"yaml\">    <span class=\"pi\">-<\/span> <span class=\"s\">main<\/span> <span class=\"c1\"># runs when the branch name equals master<\/span><\/span>\r\n<span id=\"LC73\" class=\"line\" lang=\"yaml\"><\/span>\r\n<span id=\"LC74\" class=\"line\" lang=\"yaml\"><span class=\"na\">clean<\/span><span class=\"pi\">:<\/span><\/span>\r\n<span id=\"LC75\" class=\"line\" lang=\"yaml\">  <span class=\"na\">stage<\/span><span class=\"pi\">:<\/span> <span class=\"s\">cleanup<\/span><\/span>\r\n<span id=\"LC76\" class=\"line\" lang=\"yaml\">  <span class=\"na\">tags<\/span><span class=\"pi\">:<\/span><\/span>\r\n<span id=\"LC77\" class=\"line\" lang=\"yaml\">    <span class=\"pi\">-<\/span> <span class=\"s\">docker<\/span><\/span>\r\n<span id=\"LC78\" class=\"line\" lang=\"yaml\">  <span class=\"na\">script<\/span><span class=\"pi\">:<\/span><\/span>\r\n<span id=\"LC79\" class=\"line\" lang=\"yaml\">    <span class=\"pi\">-<\/span> <span class=\"s\">.\/bin\/cleanup.sh<\/span><\/span>\r\n<span id=\"LC80\" class=\"line\" lang=\"yaml\">  <span class=\"na\">needs<\/span><span class=\"pi\">:<\/span><\/span>\r\n<span id=\"LC81\" class=\"line\" lang=\"yaml\">    <span class=\"pi\">-<\/span> <span class=\"pi\">[<\/span><span class=\"s2\">\"<\/span><span class=\"s\">pages\"<\/span><span class=\"pi\">]<\/span><\/span>\r\n<span id=\"LC82\" class=\"line\" lang=\"yaml\">  <span class=\"na\">except<\/span><span class=\"pi\">:<\/span><\/span>\r\n<span id=\"LC83\" class=\"line\" lang=\"yaml\">    <span class=\"pi\">-<\/span> <span class=\"s\">triggers<\/span><\/span>\r\n<span id=\"LC84\" class=\"line\" lang=\"yaml\">  <span class=\"na\">only<\/span><span class=\"pi\">:<\/span><\/span>\r\n<span id=\"LC85\" class=\"line\" lang=\"yaml\">    <span class=\"pi\">-<\/span> <span class=\"s\">main<\/span><\/span>\r\n<\/pre>\n<p>&nbsp;<\/p>\n<\/details>\n<h2>Quellen<\/h2>\n<ul>\n<li><a href=\"https:\/\/www.martinfowler.com\/articles\/continuousIntegration.html\">https:\/\/www.martinfowler.com\/articles\/continuousIntegration.html<\/a><\/li>\n<li><a href=\"https:\/\/martinfowler.com\/bliki\/ContinuousDelivery.html\">https:\/\/martinfowler.com\/bliki\/ContinuousDelivery.html<\/a><\/li>\n<li><a href=\"https:\/\/www.atlassian.com\/de\/continuous-delivery\/principles\/continuous-integration-vs-delivery-vs-deployment\">https:\/\/www.atlassian.com\/de\/continuous-delivery\/principles\/continuous-integration-vs-delivery-vs-deployment<\/a><\/li>\n<li><a href=\"https:\/\/docs.gitlab.com\/ee\/ci\/\">https:\/\/docs.gitlab.com\/ee\/ci\/<\/a><\/li>\n<li><a href=\"https:\/\/docs.gitlab.com\/ee\/user\/project\/pages\/\">https:\/\/docs.gitlab.com\/ee\/user\/project\/pages\/<\/a><\/li>\n<\/ul>\n<h2>Weiterf\u00fchrende Literatur<\/h2>\n<ul>\n<li><a href=\"https:\/\/gitlab.imn.htwk-leipzig.de\/fbahr\/bis_gitlab_ci\">https:\/\/gitlab.imn.htwk-leipzig.de\/fbahr\/bis_gitlab_ci<\/a><\/li>\n<li><a href=\"https:\/\/docs.gitlab.com\/ee\/ci\/\">https:\/\/docs.gitlab.com\/ee\/ci\/<\/a><\/li>\n<li><a href=\"https:\/\/docs.gitlab.com\/ee\/user\/project\/pages\/\">https:\/\/docs.gitlab.com\/ee\/user\/project\/pages\/<\/a><\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>GitLabs Continuous Methodologies Inhaltsverzeichnis Allgemeines Workflow GitLab CI\/CD GitLab Pipelines GitLab Stages GitLab Jobs GitLab Pages Quellen Allgemeines Die Akronyme<\/p>\n","protected":false},"author":42,"featured_media":1244,"comment_status":"open","ping_status":"open","sticky":false,"template":"templates\/template-fullwidth.php","format":"standard","meta":{"footnotes":""},"categories":[2],"tags":[85,83,84,82,80],"class_list":["post-1215","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-betriebliche-informationssysteme","tag-agile","tag-continuous-delivery","tag-continuous-deployment","tag-continuous-integration","tag-gitlab"],"_links":{"self":[{"href":"https:\/\/informatik.htwk-leipzig.de\/seminar\/wp-json\/wp\/v2\/posts\/1215","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/informatik.htwk-leipzig.de\/seminar\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/informatik.htwk-leipzig.de\/seminar\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/informatik.htwk-leipzig.de\/seminar\/wp-json\/wp\/v2\/users\/42"}],"replies":[{"embeddable":true,"href":"https:\/\/informatik.htwk-leipzig.de\/seminar\/wp-json\/wp\/v2\/comments?post=1215"}],"version-history":[{"count":26,"href":"https:\/\/informatik.htwk-leipzig.de\/seminar\/wp-json\/wp\/v2\/posts\/1215\/revisions"}],"predecessor-version":[{"id":1341,"href":"https:\/\/informatik.htwk-leipzig.de\/seminar\/wp-json\/wp\/v2\/posts\/1215\/revisions\/1341"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/informatik.htwk-leipzig.de\/seminar\/wp-json\/wp\/v2\/media\/1244"}],"wp:attachment":[{"href":"https:\/\/informatik.htwk-leipzig.de\/seminar\/wp-json\/wp\/v2\/media?parent=1215"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/informatik.htwk-leipzig.de\/seminar\/wp-json\/wp\/v2\/categories?post=1215"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/informatik.htwk-leipzig.de\/seminar\/wp-json\/wp\/v2\/tags?post=1215"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}