Cvičení: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14.
Na posledním cvičení shrneme znalosti ze všech dosud probraných témat. Začneme nástroji systému sestavení, které nám umožňují zachytit - a kodifikovat - proces sestavení, a pak se podíváme, jak lze nastavit GitLab, aby pravidelně kontroloval náš kód a udržoval tak náš projekt zdravý.
Průběžný příklad
Naposledy se vrátíme k našemu příkladu generování webových stránek a použijeme jej jako průběžný příklad pro toto cvičení.
Opět použijeme jednodušší verzi, která vypadala takto:
#!/bin/bash
set -ueo pipefail
pandoc --template template.html index.md >index.html
pandoc --template template.html rules.md >rules.html
./table.py <score.csv | pandoc --template template.html --metadata title="Score" - >score.html
Všimněte si, že pro index
a rules
máme Markdown soubory, ze kterých
vytvoříme HTML.
Stránka score
je generována z CSV souboru.
Příprava
Prosím, vytvořte fork repozitáře s webem, abyste si mohli příklady sami vyzkoušet.
Motivace pro používání systémů sestavení
V našem příkladu je celý web sestaven v několika krocích, kdy jsou stránky HTML generovány z různých zdrojů. To je vlastně velmi podobné tomu, jak se software sestavuje ze zdrojových kódů (uvažujme zdrojové kódy v jazyce C, které se kompilují a linkují dohromady).
Zatímco výše uvedené kroky nevytvoří spustitelný soubor (což je typický případ pro vývoj softwaru), reprezentují obvyklý scénář.
Sestavení softwaru se obvykle skládá z mnoha kroků, které zahrnují tak odlišné činnosti jako třeba:
- kompilace zdrojáků do nějakého meziformátu
- linkování výsledné binárky
- vytvoření bitmapové grafiky v různém rozlišení z jediného vektorového obrázku
- generování dokumentace ze zdrojového kódu
- příprava souborů pro lokalizaci (překlad)
- vytvoření samorozbalujícího archívu
- nahrání softwaru na webový server
- zveřejnění artefaktu v repozitáři balíčků
- …
Skoro všechny jsou vlastně hrozně jednoduché. Složité je poskládat je dohromady. To jest, jak je spustit ve správném pořadí a jak spustit jednotlivé programy se správnými parametry (volbami).
Například, než může být vytvořen instalátor, musí být nachystané všechny ostatní soubory. Soubory pro překlad obvykle závisí na předzpracování nějakých zdrojových souborů, ale musí být nachystány než je vytvořena výsledná binárka. Atd.
I pro malé projekty může být množství kroků poměrně velké. Ale jsou – svým způsobem – nezajímavé: nechcete si je pamatovat. Chcete ten software sestavit!
Všimněte si, že vám s tím vším často pomůže vaše IDE — jediným kliknutím. Ne každý však používá stejné IDE a možná dokonce grafické rozhraní vůbec nemáte.
Kromě toho chcete obvykle spustit sestavení jako součást každé revize — typickým příkladem jsou pipeline GitLabu, které používáme pro testy: spouštějí se bez grafického rozhraní, přesto chceme software sestavit (a také otestovat). Kodifikace tohoto postupu ve skriptu sestavení to zjednodušuje prakticky pro každého.
Náš výše zmíněný skript build.sh
je vlastně docela pěkný. Je snadno
pochopitelný, neobsahuje žádnou složitou logiku a nový člen týmu nemusí
zkoumat všechny drobné detaily a může prostě spustit jediný skript
build.sh
.
Skript je v pohodě, ale zbytečně přepisuje soubory i když nedošlo ke změně. V našem malém příkladu to nevadí (konec konců, počítač máme dost rychlý).
Ale ve větším projektu, kde bychom pracovali s tisícovkami souborů
(klidně se podívejte na zdrojáky Linuxového jádra, Firefoxu nebo
LibreOffice)
je to velký rozdíl.
Pokud se vstupní soubor nezměnil (třeba jsme změnili jen rules.md
)
nemusíme přetvářet ostatní soubory (nemusíme znovu vytvářet index.html
).
Trochu teď skript rozšíříme.
...
should_generate() {
local barename="$1"
if ! [ -e "${barename}.html" ]; then
return 0
fi
if [ "${barename}.md" -nt "${barename}.html" ]; then
return 0
else
return 1
fi
}
...
should_generate index && pandoc --template template.html index.md >index.html
should_generate rules && pandoc --template template.html rules.md >rules.html
...
Tohle můžeme udělat pro každý příkaz a zrychlíme tím vytváření webu.
Ale.
To je dost práce. A pravděpodobně by ušetřený čas by promrhán přepisováním našeho skriptu. Nemluvě o tom, že výsledek je děsivý. A dost náročný na údržbu.
Často také potřebujeme sestavit jen část projektu: např. jen vygenerovat dokumentaci (bez dalšího zveřejnění, třeba). Ačkoliv rozšíření skriptu tímto způsobem je možné, pro velké projekty to nebude fungovat dobře.
if [ -z "$1" ]; then
... # build here
elif [ "${1:-}" = "clean" ]; then
rm -f index.html rules.html score.html
elif [ "${1:-}" = "publish" ]; then
cp index.html rules.html score.html /var/www/web-page/
else
...
Naštěstí je tu lepší cesta.
Existují speciální nástroje zvané build systémy (česky možná také nástroje pro řízení překladu/sestavení) které mají jediný účel: koordinovat proces sestavení. Uživateli dávají vysokoúrovňový jazyk, ve kterém může zachytit výše zmíněné kroky pro sestavení softwaru.
V tomto cvičení se zaměříme na make
.
make
je poměrně starý systém, ale pořád je hojně používán.
Je to také jeden z nejjednodušších nástrojů z této kategorie: hodně toho
musíte připravit ručně, ale pro vysvětlení principů je to perfektní.
Budeme mít plnou moc nad celým procesem a uvidíte, co se všechno děje.
make
Nejprve se přesuňte do kořenového adresáře (lokálního klonu vašeho forku) repozitáře příkladu s webem.
Soubory v tomto adresáři jsou prakticky stejné jako v našem shellovém
skriptu výše, ale je zde jeden soubor navíc: Makefile
. Všimněte si, že
Makefile
je napsán s velkým M, aby byl snadno rozlišitelný (ls
v
nelokalizovaném nastavení řadí velká písmena jako první).
Tento soubor je řídicím souborem pro sestavovací systém make
, který dělá
přesně to, co jsme se snažili napodobit v předchozím příkladu. Obsahuje
posloupnost pravidel pro sestavování souborů.
K přesné syntaxi pravidel se dostaneme brzy, ale nejprve si s nimi pojďme pohrát. Spusťte následující příkaz:
make
Zobrazí se následující výstup (pokud jste už některé příkazy provedli ručně, může se výstup lišit):
pandoc --template template.html index.md >index.html
pandoc --template template.html rules.md >rules.html
make
vypíše příkazy, které provede, a spustí je. Vytvořil pro nás webové
stránky: všimněte si, že byly vygenerovány soubory HTML.
Soubor version.inc.html
prozatím vůbec negenerujeme.
Spusťte znovu make
.
make: Nothing to be done for 'all'.
Jak vidíte, make
byl dost chytrý na to, aby rozpoznal, že vzhledem k tomu,
že se žádný soubor nezměnil, není třeba nic spouštět.
Aktualizujte soubor index.md
(funguje i touch index.md
) a znovu spusťte
make
. Všimněte si, že soubor index.html
byl znovu sestaven, zatímco
soubor rules.html
zůstal nedotčen.
pandoc --template template.html index.md >index.html
Tomuto postupu se říká inkrementální sestavení (sestavujeme pouze to, co bylo potřeba, místo abychom sestavovali vše od začátku).
Jak jsme uvedli výše: v našem malém příkladu to není příliš zajímavé. Jakmile však budou vstupních souborů tisíce, rozdíl bude obrovský.
Je také možné spustit make index.html
a požádat o přestavbu pouze
index.html
. Sestavení je opět inkrementální.
Pokud si přejete vynutit sestavení, spusťte make
s -B
. Často se tomu
říká nepodmíněné sestavení.
Jinými slovy, make
nám umožňuje zachytit jednotlivé jednoduché příkazy
potřebné pro sestavení projektu (bez ohledu na to, zda kompilujeme a
linkujeme programy v jazyce C nebo generujeme webovou stránku) do uceleného
skriptu.
Přestavuje pouze věci, které je třeba přestavět, a co je zajímavější, bere v
potaz závislosti. Například pokud se scores.html
generuje z scores.md
,
který se sestavuje z scores.csv
, stačí zadat, jak se má sestavit
scores.md
z scores.csv
a jak se má vytvořit scores.html
z scores.md
,
a make
zajistí správné pořadí.
vysvětlení formátu Makefile
Makefile
je řídicí soubor pro systém sestavování s názvem make
. V
podstatě se jedná o jazyk specifický pro danou doménu (domain-specific
language), který zjednodušuje nastavení skriptu bez nutnosti
funkceshould_generate
, kterou jsme zmínili výše.
make
rozlišuje tabulátory a
mezery. Veškeré odsazení v souboru Makefile musí být provedeno pomocí
tabulátorů. Musíte se ujistit, že váš editor nenahrazuje tabulátory na
mezery. To je také častý problém při kopírování kusů kódu z webového
prohlížeče.
(Obvykle váš editor rozpozná, že Makefile
je speciální název souboru, a
sám se přepne na politiku pouze tabulátory.) Pokud místo toho použijete
mezery, obvykle se zobrazí chyba typu Makefile:LINE_NUMBER: *** missing separator. Stop.
.
Soubor Makefile obsahuje posloupnost pravidel. Pravidlo vypadá takto:
rules.html: rules.md template.html
pandoc --template template.html rules.md >rules.html
Název před dvojtečkou je cíl pravidla. Obvykle je to název souboru, který
chceme vytvořit. Zde je to rules.html
.
Zbytek prvního řádku je seznam závislostí – souborů, ze kterých je cíl
sestaven. V našem příkladu jsou závislostmi soubory rules.md
a
template.html
. Jinými slovy: když se tyto soubory (rules.md
a
template.html
) změní, musíme znovu sestavit rules.html
.
Třetí částí jsou následující řádky, které musí být odsazeny
tabulátorem. Obsahují příkazy, které je třeba provést, aby byl cíl
sestaven. Zde je to volání příkazu pandoc
.
make
spustí příkazy, pokud je cíl zastaralý. To znamená, že buď chybí
cílový soubor, nebo je jedna či více závislostí novější než cíl.
Zbytek souboru Makefile
je podobný. Jsou zde pravidla pro další soubory a
také několik speciálních pravidel.
Speciální pravidla
Speciální pravidla jsou all
, clean
a .PHONY
. Neurčují soubory, které
mají být sestaveny, ale spíše speciální akce.
all
je tradiční název pro první pravidlo v souboru. Říká se mu výchozí
pravidlo a je použito, pokud spustíte make
bez argumentů. Obvykle nemá
žádné příkazy a závisí na všech souborech, které by měly být sestaveny jako
výchozí.
clean
je speciální pravidlo, které obsahuje pouze příkazy, ale žádné
závislosti. Jeho účelem je odstranit všechny vygenerované soubory, pokud
chcete vyčistit svůj pracovní prostor. Obvykle clean
odstraní všechny
soubory, které nejsou verzovány (tj. nejsou pod kontrolou systému Git).
To lze považovat za nesprávné použití programu make
, které má však dlouhou
tradici. Z pohledu make
jsou cíle all
a clean
stále považovány za
názvy souborů. Pokud vytvoříte soubor s názvem clean
, speciální pravidlo
přestane fungovat, protože cíl bude považován za aktuální (existuje a žádná
závislost není novější).
Chcete-li se této pasti vyhnout, měli byste výslovně říci make
, že cílem
není soubor. To se provede tak, že jej uvedete jako závislost speciálního
cíle .PHONY
(všimněte si úvodní tečky).
Obecně je vidět, že make
má spoustu zvláštností. Často je to tak u
programů, které začaly jako jednoduchý nástroj a prošly si 40 lety
postupného vývoje, kdy pomalu přibývaly funkce. Přesto je to jeden z
nejpoužívanějších build systémů. Často také slouží jako back-end pro
pokročilejší nástroje — ty vygenerují Makefile
z přívětivější
specifikace a delegují práci na make
.
Cvičení
Zlepšení udržovatelnosti souboru Makefile
Soubor Makefile
začíná obsahovat příliš mnoho opakujícího se kódu.
Ale i s tím vám může make
pomoci.
Odstraňme všechna pravidla pro generování out/*.html
z *.md
a nahraďme
jej tímto pravidlem:
out/%.html: %.md template.html
pandoc --template template.html -o $@ $<
To je vzorové pravidlo (pattern rule), které zachycuje myšlenku, že HTML je generováno z Markdown. Znak procenta ve specifikaci závislostí a cíle představuje tzv. stem — proměnlivou (tj. měnící se) část vzoru.
V příkazové části používáme proměnné make
. Proměnné make
začínají na
dolar jako v shellu, ale nejsou stejné.
$@
je skutečný cíl a $<
je první závislost.
Spusťte make clean && make
a ověřte, zda se web generuje i při použití
vzorových pravidel.
Kromě vzorových pravidel rozumí make
také (uživatelským) proměnným. Ty
mohou zlepšit čitelnost, protože můžete oddělit konfiguraci od
příkazů. Například:
PAGES = \
out/index.html \
out/rules.html \
out/score.html
all: $(PAGES) ...
...
Všimněte si, že na rozdíl od shellu jsou proměnné expandovány pomocí $(VAR)
konstrukcí. (S výjimkou speciálních proměnných, jako je $<
.)
Nepřenositelná rozšíření
make
je velmi starý nástroj, který existuje v mnoha různých
implementacích. Dosud zmíněné funkce by měly fungovat s jakoukoli verzí
make
. (Přinejmenším s přiměřeně nedávnou verzí. Staré verze make
neměly
.PHONY
ani vzorová pravidla.)
Poslední doplněk bude fungovat pouze v GNU make (ale ten je v Linuxu výchozí, takže by s ním neměl být žádný problém).
Soubor Makefile
změníme takto:
PAGES = \
index \
rules \
score
PAGES_TMP=$(addsuffix .html, $(PAGES))
PAGES_HTML=$(addprefix out/, $(PAGES_TMP))
Uchováváme pouze základní název každé stránky a počítáme výstupní
cestu. $(addsuffix ...)
a $(addprefix ...)
jsou volání vestavěných
funkcí. Formálně jsou všechny argumenty funkcí řetězce, ale v tomto případě
jsou jména oddělená čárkami považována za seznam.
Všimněte si, že jsme přidali PAGES_TMP
pouze pro zlepšení čitelnosti při
prvním použití této vlastnosti. Za normálních okolností byste do
PAGES_HTML
přiřazovali přímo toto.
PAGES_HTML=$(addprefix out/, $(addsuffix .html, $(PAGES)))
To bude ještě užitečnější, až budeme chtít pro každou stránku vygenerovat
také soubor PDF. Můžeme přidat vzorové pravidlo a vytvořit seznam PDF pomocí
$(addsuffix .pdf, $(PAGES))
.
GitLab CI
Pokud jste ještě nikdy neslyšeli pojem kontinuální integrace (Continuous Integration — CI), pak je to v kostce následující.
O kontinuální integraci
Abyste zajistili, že software, který vytváříte, je ve zdravém stavu, měli byste na něm často provádět testy a co nejdříve opravovat nefunkční věci (protože náklady na opravu chyb dramaticky rostou s každým dnem, kdy nejsou odhaleny).
To znamená, že vývojář musí při každé revizi spustit testy. Protože je obtížné to vynutit, je lepší to dělat automaticky. CI ve své nejjednodušší podobě označuje stav, kdy se automatické testy (např. na bázi BATS nebo Pythonu) provádějí automaticky po každém odeslání (push), např. po odeslání změn v libovolné větvi do GitLabu.
CI však dokáže mnohem víc: pokud testy projdou, posloupnost příkazů (pipeline) může software zabalit a publikovat jako artefakt (např. jako instalační program). Nebo může spustit úlohu pro nasazení do produkčního prostředí a zpřístupnit jej zákazníkům. A tak dále.
Nastavení CI na GitLabu
V tomto cvičení uvidíte, jak si nastavit GitLab CI podle vašich potřeb.
Důležité je vědět, že GitLab CI může běžet nad Podmanovými kontejnery. Takže pro nastavení GitLabové pipeline si vyberete obraz pro Podman a příkazy, které je potřeba v takovém kontejneru spustit. GitLab pak vytvoří daný kontejner a spustí v něm vaše příkazy.
Podle výsledku celého skriptu (tj. jeho exit kódu) pak označí buď pipeline jako procházející nebo selhanou.
Vzpomeňte si na úkol 12/test-in-alpine.txt
: ten byl vlastně přípravou na
CI.
V tomto kurzu se zaměříme na nejjednodušší konfiguraci, kdy chceme provádět testy po každé revizi. GitLab lze nakonfigurovat i pro složitější úlohy, kdy lze software dokonce nasadit na virtuální cloudový stroj, ale to je bohužel mimo náš rozsah.
Pokud vás toto téma zajímá, GitLab má rozsáhlou dokumentaci. Dokumentace je často hustě zaplněna množstvím informací, ale je skvělým zdrojem znalostí nejen o GitLabu, ale o mnoha principech softwarového inženýrství obecně.
.gitlab-ci.yml
Konfigurace GitLab CI je uložena v souboru .gitlab-ci.yml
, který musí být
uložen v kořenovém adresáři projektu.
Očekáváme, že máte vlastní fork webového úložiště a že jste rozšířili
původní soubor Makefile
.
Nyní nastavíme úlohu CI, která sestaví pouze web. Bude to ta nejzákladnější CI, jakou si lze představit. Ale alespoň zajistí, že web bude vždy v sestavitelném stavu.
Pro urychlení však z našeho Makefile
odstraníme generování PDF, protože
instalace OpenOffice vyžaduje stažení 400 MB, což je pro každou revizi
poměrně hodně.
image: fedora:37
build:
script:
- dnf install -y make pandoc
- make
Určuje úlohu pipeline build (tento název se zobrazí ve webovém
uživatelském rozhraní), která se spustí pomocí obrazu
fedora a provede dva příkazy. První
nainstaluje závislost a druhý spustí make
.
Přidejte soubor .gitlab-ci.yml
do svého úložiště Git (tj. do svého forku),
odevzdejte jej (commit) a odešlete (push).
Pokud otevřete stránku projektu na webu GitLabu, měla by se vedle ní zobrazit ikona pipeline, která by měla nakonec zezelenat.
Log by pravděpodobně vypadal takto.
Running with gitlab-runner 15.11.0 (436955cb)
on gitlab.mff docker Mtt-jvRo, system ID: s_7f0691b32461
Preparing the "docker" executor 00:03
Using Docker executor with image fedora:37 ...
Pulling docker image fedora:37 ...
Using docker image sha256:34354ac2c458e89615b558a15cefe1441dd6cb0fc92401e3a39a7b7012519123 for fedora:37 with digest fedora@sha256:e3012fe03ccee2d37a7940c4c105fb240cbb566bf228c609d9b510c9582061e0 ...
Preparing environment 00:00
Running on runner-mtt-jvro-project-11023-concurrent-0 via gitlab-runner...
Getting source from Git repository 00:01
Fetching changes with git depth set to 20...
Reinitialized existing Git repository in /builds/horkv6am/nswi-177-web/.git/
Checking out 58653aa3 as detached HEAD (ref is master)...
Removing out/index.html
Removing out/main.css
Removing out/rules.html
Removing out/score.html
Removing tmp/
Skipping Git submodules setup
Executing "step_script" stage of the job script 00:33
Using docker image sha256:34354ac2c458e89615b558a15cefe1441dd6cb0fc92401e3a39a7b7012519123 for fedora:37 with digest fedora@sha256:e3012fe03ccee2d37a7940c4c105fb240cbb566bf228c609d9b510c9582061e0 ...
$ dnf install -y make pandoc
Fedora 37 - x86_64 43 MB/s | 82 MB 00:01
Fedora 37 openh264 (From Cisco) - x86_64 4.3 kB/s | 2.5 kB 00:00
Fedora Modular 37 - x86_64 17 MB/s | 3.8 MB 00:00
Fedora 37 - x86_64 - Updates 24 MB/s | 29 MB 00:01
Fedora Modular 37 - x86_64 - Updates 4.8 MB/s | 2.9 MB 00:00
Dependencies resolved.
================================================================================
Package Architecture Version Repository Size
================================================================================
Installing:
make x86_64 1:4.3-11.fc37 fedora 542 k
pandoc x86_64 2.14.0.3-18.fc37 fedora 21 M
Installing dependencies:
gc x86_64 8.0.6-4.fc37 fedora 103 k
guile22 x86_64 2.2.7-6.fc37 fedora 6.5 M
libtool-ltdl x86_64 2.4.7-2.fc37 fedora 37 k
pandoc-common noarch 2.14.0.3-18.fc37 fedora 472 k
Transaction Summary
================================================================================
Install 6 Packages
Total download size: 29 M
Installed size: 204 M
Downloading Packages:
(1/6): libtool-ltdl-2.4.7-2.fc37.x86_64.rpm 846 kB/s | 37 kB 00:00
(2/6): make-4.3-11.fc37.x86_64.rpm 9.4 MB/s | 542 kB 00:00
(3/6): gc-8.0.6-4.fc37.x86_64.rpm 595 kB/s | 103 kB 00:00
(4/6): pandoc-common-2.14.0.3-18.fc37.noarch.rp 8.4 MB/s | 472 kB 00:00
(5/6): guile22-2.2.7-6.fc37.x86_64.rpm 18 MB/s | 6.5 MB 00:00
(6/6): pandoc-2.14.0.3-18.fc37.x86_64.rpm 56 MB/s | 21 MB 00:00
--------------------------------------------------------------------------------
Total 51 MB/s | 29 MB 00:00
Running transaction check
Transaction check succeeded.
Running transaction test
Transaction test succeeded.
Running transaction
Preparing : 1/1
Installing : pandoc-common-2.14.0.3-18.fc37.noarch 1/6
Installing : libtool-ltdl-2.4.7-2.fc37.x86_64 2/6
Installing : gc-8.0.6-4.fc37.x86_64 3/6
Installing : guile22-2.2.7-6.fc37.x86_64 4/6
Installing : make-1:4.3-11.fc37.x86_64 5/6
Installing : pandoc-2.14.0.3-18.fc37.x86_64 6/6
Running scriptlet: pandoc-2.14.0.3-18.fc37.x86_64 6/6
Verifying : gc-8.0.6-4.fc37.x86_64 1/6
Verifying : guile22-2.2.7-6.fc37.x86_64 2/6
Verifying : libtool-ltdl-2.4.7-2.fc37.x86_64 3/6
Verifying : make-1:4.3-11.fc37.x86_64 4/6
Verifying : pandoc-2.14.0.3-18.fc37.x86_64 5/6
Verifying : pandoc-common-2.14.0.3-18.fc37.noarch 6/6
Installed:
gc-8.0.6-4.fc37.x86_64 guile22-2.2.7-6.fc37.x86_64
libtool-ltdl-2.4.7-2.fc37.x86_64 make-1:4.3-11.fc37.x86_64
pandoc-2.14.0.3-18.fc37.x86_64 pandoc-common-2.14.0.3-18.fc37.noarch
Complete!
$ make
pandoc --template template.html -o out/index.html index.md
pandoc --template template.html -o out/rules.html rules.md
./table.py <score.csv | pandoc --template template.html --metadata title="Score" - >out/score.html
cp main.css out/
Cleaning up project directory and file based variables 00:01
Job succeeded
Všimněte si, že GitLab nejprve připojí úložiště Git do kontejneru a poté
provede příkazy uvnitř klonu. Příkazy se provádějí pomocí set -e
: první
neúspěšný příkaz ukončí celou pipeline.
Pokuste se emulovat výše uvedený běh lokálně. Hint. Solution.
Cvičení
Další drobnosti
Všimněte si, jak je použití pipeline GitLab snadné. Najdete správný obraz (image), zadáte skript a GitLab se postará o zbytek.
Pokud si nejste jisti, který obraz zvolit, oficiální obrazy jsou dobrým začátkem. Skript může mít několik kroků, ve kterých před spuštěním programu nainstalujete chybějící závislosti.
Připomeňme, že nemusíte vytvářet virtuální prostředí: celý počítač je váš (a
bude stejně odstraněn), takže můžete instalovat věci globálně. Vzpomeňte si
na výše uvedený příklad, kdy jsme provedli pip install
bez spuštění
virtuálního prostředí.
Může být definováno více úloh, které jsou spouštěny paralelně (ve skutečnosti mezi nimi mohou existovat poměrně složité závislosti, ale v následujícím příkladu jsou všechny úlohy spuštěny najednou).
Následující příklad ukazuje fragment souboru .gitlab-ci.yml
, který testuje
projekt na více verzích jazyka Python.
# Default image if no other is specified
image: python:3.10
stages:
- test
# Commands executed before each "script" section (for any job)
before_script:
# To have a quick check that the version is correct
- python3 --version
# Install the project
- python3 -m pip install ...
# Run unit tests under different versions
unittests3.7:
stage: test
image: "python:3.7"
script:
- pytest --log-level debug tests/
unittests3.8:
stage: test
image: "python:3.8"
script:
- pytest --log-level debug tests/
unittests3.9:
stage: test
image: "python:3.9"
script:
- pytest --log-level debug tests/
unittests3.10:
stage: test
image: "python:3.10"
script:
- pytest --log-level debug tests/
Úlohy před cvičením (deadline: začátek vašeho cvičení, týden 15. května – 19. května)
Následující úlohy musí být vyřešeny a odevzdány před příchodem na vaše cvičení. Pokud máte cvičení ve středu v 10.40, soubory musí být nahrány do vašeho projektu (repozitáře) na GitLabu nejpozději ve středu v 10.39.
Pro virtuální cvičení je deadline úterý 9:00 (každý týden, vždy ráno, bez ohledu na možné státní svátky apod.).
Všechny úlohy (pokud není explicitně uvedeno jinak) musí být odevzdány přes váš repozitář na úkoly. Pro většinu úloh existují automatické testy, které vám mohou pomoci zkontrolovat úplnost vašeho řešení (zde je popsáno jak číst jejich výsledky).
14/web/Makefile
(100 bodů, skupina devel
)
AKTUALIZACE
Prosím, přesuňte vaše řešení do 14/web
aby nedocházelo ke konfliktům s
úlohami po cvičení. Pokud jste již vaše řešení commitnuli, následující
příkazy by ho měly přesunout (nezapomeňte změny commitnout).
git mv 14 14-web
mkdir -p 14/
git mv 14-web 14/web
K některým částem jsme přidali dovysvětlení, tyto části jsou zvýrazněné.
Kvůli výše uvedenému posouváme deadline cca o dva na 9.00 ráno. Pokud chodíte na cvičení v pondělí 15.40, podíváme se na stav vašeho repozitáře ve středu v 9.00. Věříme, že to je dostatek času navíc soubory přesunout.
Tato úloha rozšíří průběžný příklad, který jsme použili na tomto cvičení.
Následující jste již provedli (ale je to také součástí hodnocení tohoto úkolu):
- Generujte soubory
index.html
arules.html
z příslušných souborů*.md
. - Vygenerované soubory uložte do podadresáře
out/
. - cíl
clean
odstraní všechny soubory v adresářiout/
(kromě souboru.gitignore
).
Jako novou funkci očekáváme, že příklad rozšíříte o následující:
-
Přesuňte zdrojové soubory do podadresáře
src/
. Toto je povinná část, bez tohoto přesunu nebude žádný z testů fungovat. Očekáváme, že soubory přesunute ručně, tj. ne během buildu. Cílem je trochu pročistit adresářovou strukturu. Takže byste měli mít commitnutý soubor14/web/src/index.md
ve vašem repozitáři. -
Generujte stránky ze souborů
*.csv
. Zescore.csv
se již generuje souborscore.html
. Předpokládáme, že přidáte souborygroup-a.csv
agroup-b.csv
, ze kterých se generujígroup-a.html
agroup-b.html
(pomocí skriptutable.py
jako proscore.csv
). Souborygroup-a.html
agroup-b.html
by měly být vytvořeny automaticky. -
Generujte stránky ze souborů
*.bin
. Očekáváme, že soubor bude mít stejné základní jméno jako výsledný soubor.html
a postará se o kompletní generování obsahu. Test si vytváří vlastnífrom-news.bin
, vaše řešení musí používat vzorová pravidla (pattern rules) se správými stemy. -
Přidejte speciální cíl
spelling
, který zobrazí seznam překlepů v souborech Markdown. Předpokládáme, že pro tento úkol použijeteaspell
a jako hlavní jazyk použijete angličtinu.
Nápověda #1: seznam generovaných souborů si uložte do proměnné PAGES
, protože Vám to zjednoduší údržbu vašeho Makefile
.
Nápověda č. 2: následující příklad je jednoduchý příklad dynamicky generované
webové stránky, která může být uložena v souboru src/news.bin
. Skript je trochu
záludný, protože data webové stránky jsou součástí skriptu a používá $0
pro čtení
sám sebe (podobný trik se často používá při vytváření samorozbalovacích
archivů pro Linux).
#!/bin/bash
set -ueo pipefail
sed '1,/^---NEWS-START-HERE---/d' "$0" | while read -r date comment; do
echo "<dt>$date</dt>"
echo "<dd>$comment</dd>"
done | pandoc --template template.html --metadata title="News" -
exit 0
# Actual news are stored below.
# Add each news item on a separate line
#
# !!! Do not modify the line NEWS-START-HERE !!!
#
---NEWS-START-HERE---
2023-05-01 Website running
2023-05-02 Registration open
Úlohy po cvičení (deadline: 4. června)
Očekáváme, že následující úlohy vyřešíte po cvičení, tj. poté, co budete mít zpětnou vazbu k vašim řešením úloh před cvičením.
Všechny úlohy (pokud není explicitně uvedeno jinak) musí být odevzdány přes váš repozitář na úkoly. Pro většinu úloh existují automatické testy, které vám mohou pomoci zkontrolovat úplnost vašeho řešení (zde je popsáno jak číst jejich výsledky).
14/cc/Makefile
(40 bodů, skupina devel
)
Převeďte shellový skript pro sestavení spustitelného souboru (ze zdrojových kódů C) na skript založený na make.
Zdrojáky jsou v repozitáři s
příklady
(v 14/cc
).
Soubor Makefile
, který vytvoříte, musí nabízet následující funkce:
- Výchozí cíl
all
vytvoří spustitelný souborexample
. - Speciální cíl
clean
odstraní všechny mezisoubory (*.o
) i výsledný spustitelný soubor (example
). - Objektové soubory (
.o
) se vytvářejí pro každý soubor zvlášť, doporučujeme použít vzorová pravidla (pattern rules). - Objektové soubory musí být závislé na zdrojovém souboru (odpovídajícím
souboru
.c
) i na hlavičkovém souboru.
Prosím, commitněte do repozitáře i zdrojové soubory.
14/group-sum-ci.yml
(60 bodů, skupina git
)
Připravte si soubor CI pro svůj fork repozitáře
group-sum
,
který bude automaticky spouštět testy při každém commitu.
Očekáváme, že stále máte svůj fork; pokud ne, forkněte jej znovu a
nezapomeňte jej sloučit s větví tests
repozitáře
gitolite3@linux.ms.mff.cuni.cz:lab07-group-sum-ng.git
tak, abyste měli
soubor tests.bats
.
Doporučujeme, abyste změnili viditelnost vašeho forku na privátní.
tests.bats
.
V tomto repozitáři (tj. ve vašem forku projektu group-sum
) vytvořte soubor
.gitlab-ci.yml
se správnou konfigurací, který bude schopen spustit BATSové
testy.
Zkontrolujte, zda se po každém commitu (resp. pushnutí) spustí pipeline a zda testy prochází.
Poté zkopírujte soubor .gitlab-ci.yml
do repozitáře s úlohami jako
14/group-sum-ci.yml
. Neměňte konfigurace repozitáře s úlohami, zajímá nás
pouze konfigurační soubor (ale ujistěte se, že vám ve vašem forku funguje).
Učební výstupy
Učební výstupy podávají zhuštěný souhrn základních konceptů a dovedností, které byste měli umět vysvětlit a/nebo použít po každém cvičení. Také obsahují absolutní minimum, které je potřebné pro pochopení navazujících cvičení (a dalších předmětů).
Znalosti konceptů
Znalost konceptů znamená, že rozumíte významu a kontextu daného tématu a jste schopni témata zasadit do většího rámce. Takže, jste schopni …
-
vysvětlit principy continous integration
-
vysvětlit výhody používání continous integration
-
vyjmenovat několik kroků, které jsou často nutné k vytvoření distribuovatelného softwaru (např. balíček nebo instalační program) ze zdrojového kódu a dalších základních artefaktů
-
vysvětlit, proč by sestavování softwaru mělo být reprodukovatelným procesem
-
vysvětlit, jak je možné zachytit proces sestavení softwaru
-
vysvětlit pojmy jazyků, které se používají pro zachycení potřebných kroků pro sestavení (distribuci) softwaru
-
vysvětlit v širším smyslu, jak funguje GitLab CI
Praktické dovednosti
Praktické dovednosti se obvykle týkají použití daných programů pro vyřešení různých úloh. Takže, dokážete …
-
sestavit projekty používající
make
-
vytvořit Makefile, který řídí sestavení jednoduchého projektu
-
používat pravidla se zástupnými znaky v
Makefile
-
nastavit GitLab CI pro jednoduché projekty
-
volitelné: používat proměnné v
Makefile
-
volitelné: používat základní rozšíření GNU Make pro zjednodušení složitějších
Makefile
Seznam změn na této stránce
-
2023-05-23: Poznámka o commitnutí zdrojáků v úloze po cvičení.
-
2023-05-14: Přidány automatické testy a doplněno zadání pro úlohy před cvičením.
-
2023-05-15: Přidány úlohy po cvičení.